From 741fb4b9e135cfb161a749db88713229038577bb Mon Sep 17 00:00:00 2001 From: Tim Redfern Date: Thu, 5 Sep 2013 17:55:35 +0100 Subject: making act segmenter --- ffmpeg1/libavformat/4xm.c | 372 --- ffmpeg1/libavformat/Makefile | 453 --- ffmpeg1/libavformat/a64.c | 62 - ffmpeg1/libavformat/aacdec.c | 94 - ffmpeg1/libavformat/ac3dec.c | 123 - ffmpeg1/libavformat/act.c | 207 -- ffmpeg1/libavformat/adtsenc.c | 176 -- ffmpeg1/libavformat/adxdec.c | 113 - ffmpeg1/libavformat/aea.c | 105 - ffmpeg1/libavformat/afc.c | 81 - ffmpeg1/libavformat/aiff.h | 57 - ffmpeg1/libavformat/aiffdec.c | 358 --- ffmpeg1/libavformat/aiffenc.c | 332 --- ffmpeg1/libavformat/allformats.c | 341 --- ffmpeg1/libavformat/amr.c | 182 -- ffmpeg1/libavformat/anm.c | 229 -- ffmpeg1/libavformat/apc.c | 96 - ffmpeg1/libavformat/ape.c | 443 --- ffmpeg1/libavformat/apetag.c | 169 -- ffmpeg1/libavformat/apetag.h | 44 - ffmpeg1/libavformat/apetagenc.c | 65 - ffmpeg1/libavformat/aqtitledec.c | 148 - ffmpeg1/libavformat/asf.c | 162 -- ffmpeg1/libavformat/asf.h | 188 -- ffmpeg1/libavformat/asfcrypt.c | 185 -- ffmpeg1/libavformat/asfcrypt.h | 29 - ffmpeg1/libavformat/asfdec.c | 1553 ---------- ffmpeg1/libavformat/asfenc.c | 914 ------ ffmpeg1/libavformat/assdec.c | 169 -- ffmpeg1/libavformat/assenc.c | 89 - ffmpeg1/libavformat/ast.c | 29 - ffmpeg1/libavformat/ast.h | 30 - ffmpeg1/libavformat/astdec.c | 119 - ffmpeg1/libavformat/astenc.c | 214 -- ffmpeg1/libavformat/au.c | 211 -- ffmpeg1/libavformat/audiointerleave.c | 148 - ffmpeg1/libavformat/audiointerleave.h | 55 - ffmpeg1/libavformat/avc.c | 193 -- ffmpeg1/libavformat/avc.h | 34 - ffmpeg1/libavformat/avformat.h | 2126 -------------- ffmpeg1/libavformat/avi.h | 38 - ffmpeg1/libavformat/avidec.c | 1614 ----------- ffmpeg1/libavformat/avienc.c | 663 ----- ffmpeg1/libavformat/avio.c | 434 --- ffmpeg1/libavformat/avio.h | 475 --- ffmpeg1/libavformat/avio_internal.h | 107 - ffmpeg1/libavformat/aviobuf.c | 1005 ------- ffmpeg1/libavformat/avisynth.c | 641 ----- ffmpeg1/libavformat/avlanguage.c | 765 ----- ffmpeg1/libavformat/avlanguage.h | 39 - ffmpeg1/libavformat/avr.c | 100 - ffmpeg1/libavformat/avs.c | 232 -- ffmpeg1/libavformat/bethsoftvid.c | 296 -- ffmpeg1/libavformat/bfi.c | 173 -- ffmpeg1/libavformat/bink.c | 287 -- ffmpeg1/libavformat/bintext.c | 409 --- ffmpeg1/libavformat/bit.c | 157 - ffmpeg1/libavformat/bluray.c | 235 -- ffmpeg1/libavformat/bmv.c | 139 - ffmpeg1/libavformat/brstm.c | 297 -- ffmpeg1/libavformat/c93.c | 202 -- ffmpeg1/libavformat/cache.c | 140 - ffmpeg1/libavformat/caf.c | 66 - ffmpeg1/libavformat/caf.h | 34 - ffmpeg1/libavformat/cafdec.c | 434 --- ffmpeg1/libavformat/cafenc.c | 279 -- ffmpeg1/libavformat/cavsvideodec.c | 68 - ffmpeg1/libavformat/cdg.c | 79 - ffmpeg1/libavformat/cdxl.c | 231 -- ffmpeg1/libavformat/concat.c | 193 -- ffmpeg1/libavformat/concatdec.c | 405 --- ffmpeg1/libavformat/crcenc.c | 67 - ffmpeg1/libavformat/crypto.c | 170 -- ffmpeg1/libavformat/cutils.c | 57 - ffmpeg1/libavformat/data_uri.c | 118 - ffmpeg1/libavformat/daud.c | 96 - ffmpeg1/libavformat/dfa.c | 118 - ffmpeg1/libavformat/diracdec.c | 34 - ffmpeg1/libavformat/dnxhddec.c | 45 - ffmpeg1/libavformat/dsicin.c | 232 -- ffmpeg1/libavformat/dtsdec.c | 77 - ffmpeg1/libavformat/dtshddec.c | 139 - ffmpeg1/libavformat/dv.c | 614 ---- ffmpeg1/libavformat/dv.h | 41 - ffmpeg1/libavformat/dvenc.c | 420 --- ffmpeg1/libavformat/dxa.c | 225 -- ffmpeg1/libavformat/eacdata.c | 105 - ffmpeg1/libavformat/electronicarts.c | 636 ---- ffmpeg1/libavformat/epafdec.c | 104 - ffmpeg1/libavformat/ffm.h | 60 - ffmpeg1/libavformat/ffmdec.c | 639 ---- ffmpeg1/libavformat/ffmenc.c | 280 -- ffmpeg1/libavformat/ffmeta.h | 29 - ffmpeg1/libavformat/ffmetadec.c | 175 -- ffmpeg1/libavformat/ffmetaenc.c | 99 - ffmpeg1/libavformat/file.c | 218 -- ffmpeg1/libavformat/filmstripdec.c | 110 - ffmpeg1/libavformat/filmstripenc.c | 84 - ffmpeg1/libavformat/flacdec.c | 295 -- ffmpeg1/libavformat/flacenc.c | 140 - ffmpeg1/libavformat/flacenc.h | 32 - ffmpeg1/libavformat/flacenc_header.c | 47 - ffmpeg1/libavformat/flic.c | 269 -- ffmpeg1/libavformat/flv.h | 138 - ffmpeg1/libavformat/flvdec.c | 923 ------ ffmpeg1/libavformat/flvenc.c | 591 ---- ffmpeg1/libavformat/framecrcenc.c | 61 - ffmpeg1/libavformat/framehash.c | 33 - ffmpeg1/libavformat/frmdec.c | 110 - ffmpeg1/libavformat/g722.c | 57 - ffmpeg1/libavformat/g723_1.c | 85 - ffmpeg1/libavformat/g729dec.c | 103 - ffmpeg1/libavformat/gif.c | 381 --- ffmpeg1/libavformat/gifdec.c | 302 -- ffmpeg1/libavformat/gopher.c | 125 - ffmpeg1/libavformat/gsmdec.c | 100 - ffmpeg1/libavformat/gxf.c | 596 ---- ffmpeg1/libavformat/gxf.h | 52 - ffmpeg1/libavformat/gxfenc.c | 999 ------- ffmpeg1/libavformat/h261dec.c | 65 - ffmpeg1/libavformat/h263dec.c | 65 - ffmpeg1/libavformat/h264dec.c | 70 - ffmpeg1/libavformat/hls.c | 828 ------ ffmpeg1/libavformat/hlsenc.c | 348 --- ffmpeg1/libavformat/hlsproto.c | 323 --- ffmpeg1/libavformat/http.c | 945 ------ ffmpeg1/libavformat/http.h | 48 - ffmpeg1/libavformat/httpauth.c | 287 -- ffmpeg1/libavformat/httpauth.h | 79 - ffmpeg1/libavformat/icodec.c | 182 -- ffmpeg1/libavformat/icoenc.c | 204 -- ffmpeg1/libavformat/id3v1.c | 246 -- ffmpeg1/libavformat/id3v1.h | 41 - ffmpeg1/libavformat/id3v2.c | 858 ------ ffmpeg1/libavformat/id3v2.h | 163 -- ffmpeg1/libavformat/id3v2enc.c | 284 -- ffmpeg1/libavformat/idcin.c | 380 --- ffmpeg1/libavformat/idroqdec.c | 237 -- ffmpeg1/libavformat/idroqenc.c | 46 - ffmpeg1/libavformat/iff.c | 485 ---- ffmpeg1/libavformat/ilbc.c | 141 - ffmpeg1/libavformat/img2.c | 102 - ffmpeg1/libavformat/img2dec.c | 498 ---- ffmpeg1/libavformat/img2enc.c | 168 -- ffmpeg1/libavformat/ingenientdec.c | 66 - ffmpeg1/libavformat/internal.h | 395 --- ffmpeg1/libavformat/ipmovie.c | 656 ----- ffmpeg1/libavformat/ircam.c | 47 - ffmpeg1/libavformat/ircam.h | 30 - ffmpeg1/libavformat/ircamdec.c | 115 - ffmpeg1/libavformat/ircamenc.c | 62 - ffmpeg1/libavformat/isom.c | 571 ---- ffmpeg1/libavformat/isom.h | 209 -- ffmpeg1/libavformat/iss.c | 144 - ffmpeg1/libavformat/iv8.c | 118 - ffmpeg1/libavformat/ivfdec.c | 91 - ffmpeg1/libavformat/ivfenc.c | 69 - ffmpeg1/libavformat/jacosubdec.c | 270 -- ffmpeg1/libavformat/jacosubenc.c | 42 - ffmpeg1/libavformat/jvdec.c | 239 -- ffmpeg1/libavformat/latmenc.c | 230 -- ffmpeg1/libavformat/libavformat.pc | 14 - ffmpeg1/libavformat/libavformat.v | 37 - ffmpeg1/libavformat/libmodplug.c | 368 --- ffmpeg1/libavformat/libnut.c | 322 --- ffmpeg1/libavformat/librtmp.c | 283 -- ffmpeg1/libavformat/lmlm4.c | 127 - ffmpeg1/libavformat/loasdec.c | 87 - ffmpeg1/libavformat/log2_tab.c | 1 - ffmpeg1/libavformat/lvfdec.c | 148 - ffmpeg1/libavformat/lxfdec.c | 348 --- ffmpeg1/libavformat/m4vdec.c | 52 - ffmpeg1/libavformat/matroska.c | 136 - ffmpeg1/libavformat/matroska.h | 280 -- ffmpeg1/libavformat/matroskadec.c | 2557 ---------------- ffmpeg1/libavformat/matroskaenc.c | 1461 ---------- ffmpeg1/libavformat/md5enc.c | 130 - ffmpeg1/libavformat/md5proto.c | 95 - ffmpeg1/libavformat/metadata.c | 70 - ffmpeg1/libavformat/metadata.h | 44 - ffmpeg1/libavformat/mgsts.c | 106 - ffmpeg1/libavformat/microdvddec.c | 167 -- ffmpeg1/libavformat/microdvdenc.c | 68 - ffmpeg1/libavformat/mkvtimestamp_v2.c | 51 - ffmpeg1/libavformat/mm.c | 197 -- ffmpeg1/libavformat/mmf.c | 319 -- ffmpeg1/libavformat/mms.c | 149 - ffmpeg1/libavformat/mms.h | 64 - ffmpeg1/libavformat/mmsh.c | 410 --- ffmpeg1/libavformat/mmst.c | 629 ---- ffmpeg1/libavformat/mov.c | 3408 ---------------------- ffmpeg1/libavformat/mov_chan.c | 592 ---- ffmpeg1/libavformat/mov_chan.h | 68 - ffmpeg1/libavformat/movenc.c | 4084 -------------------------- ffmpeg1/libavformat/movenc.h | 190 -- ffmpeg1/libavformat/movenchint.c | 462 --- ffmpeg1/libavformat/mp3dec.c | 329 --- ffmpeg1/libavformat/mp3enc.c | 522 ---- ffmpeg1/libavformat/mpc.c | 237 -- ffmpeg1/libavformat/mpc8.c | 317 -- ffmpeg1/libavformat/mpeg.c | 912 ------ ffmpeg1/libavformat/mpeg.h | 73 - ffmpeg1/libavformat/mpegenc.c | 1242 -------- ffmpeg1/libavformat/mpegts.c | 2313 --------------- ffmpeg1/libavformat/mpegts.h | 107 - ffmpeg1/libavformat/mpegtsenc.c | 1268 -------- ffmpeg1/libavformat/mpegvideodec.c | 72 - ffmpeg1/libavformat/mpjpeg.c | 69 - ffmpeg1/libavformat/mpl2dec.c | 146 - ffmpeg1/libavformat/mpsubdec.c | 140 - ffmpeg1/libavformat/msnwc_tcp.c | 140 - ffmpeg1/libavformat/mtv.c | 203 -- ffmpeg1/libavformat/mux.c | 814 ------ ffmpeg1/libavformat/mvdec.c | 441 --- ffmpeg1/libavformat/mvi.c | 143 - ffmpeg1/libavformat/mxf.c | 137 - ffmpeg1/libavformat/mxf.h | 85 - ffmpeg1/libavformat/mxfdec.c | 2392 --------------- ffmpeg1/libavformat/mxfenc.c | 2173 -------------- ffmpeg1/libavformat/mxg.c | 260 -- ffmpeg1/libavformat/ncdec.c | 101 - ffmpeg1/libavformat/network.c | 214 -- ffmpeg1/libavformat/network.h | 225 -- ffmpeg1/libavformat/nistspheredec.c | 128 - ffmpeg1/libavformat/noproxy-test.c | 43 - ffmpeg1/libavformat/nsvdec.c | 802 ------ ffmpeg1/libavformat/nullenc.c | 36 - ffmpeg1/libavformat/nut.c | 264 -- ffmpeg1/libavformat/nut.h | 133 - ffmpeg1/libavformat/nutdec.c | 1050 ------- ffmpeg1/libavformat/nutenc.c | 1023 ------- ffmpeg1/libavformat/nuv.c | 392 --- ffmpeg1/libavformat/oggdec.c | 853 ------ ffmpeg1/libavformat/oggdec.h | 160 - ffmpeg1/libavformat/oggenc.c | 636 ---- ffmpeg1/libavformat/oggparsecelt.c | 97 - ffmpeg1/libavformat/oggparsedirac.c | 117 - ffmpeg1/libavformat/oggparseflac.c | 100 - ffmpeg1/libavformat/oggparseogm.c | 202 -- ffmpeg1/libavformat/oggparseopus.c | 135 - ffmpeg1/libavformat/oggparseskeleton.c | 95 - ffmpeg1/libavformat/oggparsespeex.c | 139 - ffmpeg1/libavformat/oggparsetheora.c | 206 -- ffmpeg1/libavformat/oggparsevorbis.c | 392 --- ffmpeg1/libavformat/oma.c | 34 - ffmpeg1/libavformat/oma.h | 44 - ffmpeg1/libavformat/omadec.c | 453 --- ffmpeg1/libavformat/omaenc.c | 106 - ffmpeg1/libavformat/options.c | 123 - ffmpeg1/libavformat/options_table.h | 86 - ffmpeg1/libavformat/os_support.c | 377 --- ffmpeg1/libavformat/os_support.h | 138 - ffmpeg1/libavformat/paf.c | 261 -- ffmpeg1/libavformat/pcm.c | 76 - ffmpeg1/libavformat/pcm.h | 31 - ffmpeg1/libavformat/pcmdec.c | 146 - ffmpeg1/libavformat/pcmenc.c | 94 - ffmpeg1/libavformat/pjsdec.c | 137 - ffmpeg1/libavformat/pmpdec.c | 197 -- ffmpeg1/libavformat/psxstr.c | 317 -- ffmpeg1/libavformat/pva.c | 225 -- ffmpeg1/libavformat/pvfdec.c | 75 - ffmpeg1/libavformat/qcp.c | 196 -- ffmpeg1/libavformat/qtpalette.h | 313 -- ffmpeg1/libavformat/r3d.c | 410 --- ffmpeg1/libavformat/rawdec.c | 162 -- ffmpeg1/libavformat/rawdec.h | 67 - ffmpeg1/libavformat/rawenc.c | 282 -- ffmpeg1/libavformat/rawenc.h | 29 - ffmpeg1/libavformat/rawvideodec.c | 129 - ffmpeg1/libavformat/rdt.c | 572 ---- ffmpeg1/libavformat/rdt.h | 112 - ffmpeg1/libavformat/realtextdec.c | 153 - ffmpeg1/libavformat/riff.c | 867 ------ ffmpeg1/libavformat/riff.h | 97 - ffmpeg1/libavformat/rl2.c | 298 -- ffmpeg1/libavformat/rm.c | 47 - ffmpeg1/libavformat/rm.h | 95 - ffmpeg1/libavformat/rmdec.c | 1037 ------- ffmpeg1/libavformat/rmenc.c | 480 --- ffmpeg1/libavformat/rmsipr.c | 61 - ffmpeg1/libavformat/rmsipr.h | 35 - ffmpeg1/libavformat/rpl.c | 359 --- ffmpeg1/libavformat/rso.c | 30 - ffmpeg1/libavformat/rso.h | 32 - ffmpeg1/libavformat/rsodec.c | 83 - ffmpeg1/libavformat/rsoenc.c | 111 - ffmpeg1/libavformat/rtmp.h | 71 - ffmpeg1/libavformat/rtmpcrypt.c | 336 --- ffmpeg1/libavformat/rtmpcrypt.h | 69 - ffmpeg1/libavformat/rtmpdh.c | 339 --- ffmpeg1/libavformat/rtmpdh.h | 102 - ffmpeg1/libavformat/rtmphttp.c | 276 -- ffmpeg1/libavformat/rtmppkt.c | 526 ---- ffmpeg1/libavformat/rtmppkt.h | 288 -- ffmpeg1/libavformat/rtmpproto.c | 2681 ----------------- ffmpeg1/libavformat/rtp.c | 151 - ffmpeg1/libavformat/rtp.h | 112 - ffmpeg1/libavformat/rtpdec.c | 878 ------ ffmpeg1/libavformat/rtpdec.h | 219 -- ffmpeg1/libavformat/rtpdec_amr.c | 209 -- ffmpeg1/libavformat/rtpdec_asf.c | 310 -- ffmpeg1/libavformat/rtpdec_formats.h | 69 - ffmpeg1/libavformat/rtpdec_g726.c | 46 - ffmpeg1/libavformat/rtpdec_h263.c | 113 - ffmpeg1/libavformat/rtpdec_h263_rfc2190.c | 214 -- ffmpeg1/libavformat/rtpdec_h264.c | 399 --- ffmpeg1/libavformat/rtpdec_ilbc.c | 73 - ffmpeg1/libavformat/rtpdec_jpeg.c | 392 --- ffmpeg1/libavformat/rtpdec_latm.c | 189 -- ffmpeg1/libavformat/rtpdec_mpeg12.c | 72 - ffmpeg1/libavformat/rtpdec_mpeg4.c | 279 -- ffmpeg1/libavformat/rtpdec_mpegts.c | 106 - ffmpeg1/libavformat/rtpdec_qcelp.c | 230 -- ffmpeg1/libavformat/rtpdec_qdm2.c | 319 -- ffmpeg1/libavformat/rtpdec_qt.c | 258 -- ffmpeg1/libavformat/rtpdec_svq3.c | 134 - ffmpeg1/libavformat/rtpdec_vp8.c | 298 -- ffmpeg1/libavformat/rtpdec_xiph.c | 409 --- ffmpeg1/libavformat/rtpenc.c | 611 ---- ffmpeg1/libavformat/rtpenc.h | 98 - ffmpeg1/libavformat/rtpenc_aac.c | 85 - ffmpeg1/libavformat/rtpenc_amr.c | 65 - ffmpeg1/libavformat/rtpenc_chain.c | 107 - ffmpeg1/libavformat/rtpenc_chain.h | 32 - ffmpeg1/libavformat/rtpenc_h263.c | 81 - ffmpeg1/libavformat/rtpenc_h263_rfc2190.c | 195 -- ffmpeg1/libavformat/rtpenc_h264.c | 109 - ffmpeg1/libavformat/rtpenc_jpeg.c | 138 - ffmpeg1/libavformat/rtpenc_latm.c | 61 - ffmpeg1/libavformat/rtpenc_mpv.c | 117 - ffmpeg1/libavformat/rtpenc_vp8.c | 55 - ffmpeg1/libavformat/rtpenc_xiph.c | 127 - ffmpeg1/libavformat/rtpproto.c | 339 --- ffmpeg1/libavformat/rtsp.c | 2243 -------------- ffmpeg1/libavformat/rtsp.h | 607 ---- ffmpeg1/libavformat/rtspcodes.h | 54 - ffmpeg1/libavformat/rtspdec.c | 937 ------ ffmpeg1/libavformat/rtspenc.c | 247 -- ffmpeg1/libavformat/samidec.c | 137 - ffmpeg1/libavformat/sapdec.c | 237 -- ffmpeg1/libavformat/sapenc.c | 271 -- ffmpeg1/libavformat/sauce.c | 104 - ffmpeg1/libavformat/sauce.h | 40 - ffmpeg1/libavformat/sbgdec.c | 1513 ---------- ffmpeg1/libavformat/sctp.c | 332 --- ffmpeg1/libavformat/sdp.c | 713 ----- ffmpeg1/libavformat/seek-test.c | 151 - ffmpeg1/libavformat/seek.c | 509 ---- ffmpeg1/libavformat/seek.h | 123 - ffmpeg1/libavformat/segafilm.c | 336 --- ffmpeg1/libavformat/segment.c | 833 ------ ffmpeg1/libavformat/sierravmd.c | 301 -- ffmpeg1/libavformat/siff.c | 252 -- ffmpeg1/libavformat/smacker.c | 379 --- ffmpeg1/libavformat/smjpeg.c | 40 - ffmpeg1/libavformat/smjpeg.h | 45 - ffmpeg1/libavformat/smjpegdec.c | 183 -- ffmpeg1/libavformat/smjpegenc.c | 147 - ffmpeg1/libavformat/smoothstreamingenc.c | 637 ---- ffmpeg1/libavformat/smush.c | 240 -- ffmpeg1/libavformat/sol.c | 151 - ffmpeg1/libavformat/sox.h | 29 - ffmpeg1/libavformat/soxdec.c | 134 - ffmpeg1/libavformat/soxenc.c | 121 - ffmpeg1/libavformat/spdif.c | 42 - ffmpeg1/libavformat/spdif.h | 65 - ffmpeg1/libavformat/spdifdec.c | 240 -- ffmpeg1/libavformat/spdifenc.c | 557 ---- ffmpeg1/libavformat/srtdec.c | 163 -- ffmpeg1/libavformat/srtenc.c | 116 - ffmpeg1/libavformat/srtp.c | 471 --- ffmpeg1/libavformat/srtp.h | 52 - ffmpeg1/libavformat/srtpproto.c | 144 - ffmpeg1/libavformat/subtitles.c | 231 -- ffmpeg1/libavformat/subtitles.h | 99 - ffmpeg1/libavformat/subviewer1dec.c | 124 - ffmpeg1/libavformat/subviewerdec.c | 194 -- ffmpeg1/libavformat/swf.c | 29 - ffmpeg1/libavformat/swf.h | 149 - ffmpeg1/libavformat/swfdec.c | 489 ---- ffmpeg1/libavformat/swfenc.c | 547 ---- ffmpeg1/libavformat/takdec.c | 185 -- ffmpeg1/libavformat/tcp.c | 282 -- ffmpeg1/libavformat/tedcaptionsdec.c | 365 --- ffmpeg1/libavformat/tee.c | 278 -- ffmpeg1/libavformat/thp.c | 206 -- ffmpeg1/libavformat/tiertexseq.c | 317 -- ffmpeg1/libavformat/tls.c | 309 -- ffmpeg1/libavformat/tmv.c | 199 -- ffmpeg1/libavformat/tta.c | 171 -- ffmpeg1/libavformat/tty.c | 169 -- ffmpeg1/libavformat/txd.c | 100 - ffmpeg1/libavformat/udp.c | 847 ------ ffmpeg1/libavformat/url-test.c | 55 - ffmpeg1/libavformat/url.h | 251 -- ffmpeg1/libavformat/urldecode.c | 86 - ffmpeg1/libavformat/urldecode.h | 35 - ffmpeg1/libavformat/utils.c | 4487 ----------------------------- ffmpeg1/libavformat/vc1test.c | 119 - ffmpeg1/libavformat/vc1testenc.c | 95 - ffmpeg1/libavformat/version.h | 79 - ffmpeg1/libavformat/vivo.c | 313 -- ffmpeg1/libavformat/voc.c | 37 - ffmpeg1/libavformat/voc.h | 51 - ffmpeg1/libavformat/vocdec.c | 175 -- ffmpeg1/libavformat/vocenc.c | 110 - ffmpeg1/libavformat/vorbiscomment.c | 75 - ffmpeg1/libavformat/vorbiscomment.h | 57 - ffmpeg1/libavformat/vplayerdec.c | 128 - ffmpeg1/libavformat/vqf.c | 284 -- ffmpeg1/libavformat/w64.c | 39 - ffmpeg1/libavformat/w64.h | 31 - ffmpeg1/libavformat/wavdec.c | 687 ----- ffmpeg1/libavformat/wavenc.c | 383 --- ffmpeg1/libavformat/wc3movie.c | 304 -- ffmpeg1/libavformat/webvttdec.c | 176 -- ffmpeg1/libavformat/westwood_aud.c | 181 -- ffmpeg1/libavformat/westwood_vqa.c | 277 -- ffmpeg1/libavformat/wtv.c | 82 - ffmpeg1/libavformat/wtv.h | 58 - ffmpeg1/libavformat/wtvdec.c | 1084 ------- ffmpeg1/libavformat/wtvenc.c | 810 ------ ffmpeg1/libavformat/wv.c | 397 --- ffmpeg1/libavformat/wvenc.c | 144 - ffmpeg1/libavformat/xa.c | 128 - ffmpeg1/libavformat/xmv.c | 566 ---- ffmpeg1/libavformat/xwma.c | 277 -- ffmpeg1/libavformat/yop.c | 229 -- ffmpeg1/libavformat/yuv4mpeg.c | 611 ---- 430 files changed, 134866 deletions(-) delete mode 100644 ffmpeg1/libavformat/4xm.c delete mode 100644 ffmpeg1/libavformat/Makefile delete mode 100644 ffmpeg1/libavformat/a64.c delete mode 100644 ffmpeg1/libavformat/aacdec.c delete mode 100644 ffmpeg1/libavformat/ac3dec.c delete mode 100644 ffmpeg1/libavformat/act.c delete mode 100644 ffmpeg1/libavformat/adtsenc.c delete mode 100644 ffmpeg1/libavformat/adxdec.c delete mode 100644 ffmpeg1/libavformat/aea.c delete mode 100644 ffmpeg1/libavformat/afc.c delete mode 100644 ffmpeg1/libavformat/aiff.h delete mode 100644 ffmpeg1/libavformat/aiffdec.c delete mode 100644 ffmpeg1/libavformat/aiffenc.c delete mode 100644 ffmpeg1/libavformat/allformats.c delete mode 100644 ffmpeg1/libavformat/amr.c delete mode 100644 ffmpeg1/libavformat/anm.c delete mode 100644 ffmpeg1/libavformat/apc.c delete mode 100644 ffmpeg1/libavformat/ape.c delete mode 100644 ffmpeg1/libavformat/apetag.c delete mode 100644 ffmpeg1/libavformat/apetag.h delete mode 100644 ffmpeg1/libavformat/apetagenc.c delete mode 100644 ffmpeg1/libavformat/aqtitledec.c delete mode 100644 ffmpeg1/libavformat/asf.c delete mode 100644 ffmpeg1/libavformat/asf.h delete mode 100644 ffmpeg1/libavformat/asfcrypt.c delete mode 100644 ffmpeg1/libavformat/asfcrypt.h delete mode 100644 ffmpeg1/libavformat/asfdec.c delete mode 100644 ffmpeg1/libavformat/asfenc.c delete mode 100644 ffmpeg1/libavformat/assdec.c delete mode 100644 ffmpeg1/libavformat/assenc.c delete mode 100644 ffmpeg1/libavformat/ast.c delete mode 100644 ffmpeg1/libavformat/ast.h delete mode 100644 ffmpeg1/libavformat/astdec.c delete mode 100644 ffmpeg1/libavformat/astenc.c delete mode 100644 ffmpeg1/libavformat/au.c delete mode 100644 ffmpeg1/libavformat/audiointerleave.c delete mode 100644 ffmpeg1/libavformat/audiointerleave.h delete mode 100644 ffmpeg1/libavformat/avc.c delete mode 100644 ffmpeg1/libavformat/avc.h delete mode 100644 ffmpeg1/libavformat/avformat.h delete mode 100644 ffmpeg1/libavformat/avi.h delete mode 100644 ffmpeg1/libavformat/avidec.c delete mode 100644 ffmpeg1/libavformat/avienc.c delete mode 100644 ffmpeg1/libavformat/avio.c delete mode 100644 ffmpeg1/libavformat/avio.h delete mode 100644 ffmpeg1/libavformat/avio_internal.h delete mode 100644 ffmpeg1/libavformat/aviobuf.c delete mode 100644 ffmpeg1/libavformat/avisynth.c delete mode 100644 ffmpeg1/libavformat/avlanguage.c delete mode 100644 ffmpeg1/libavformat/avlanguage.h delete mode 100644 ffmpeg1/libavformat/avr.c delete mode 100644 ffmpeg1/libavformat/avs.c delete mode 100644 ffmpeg1/libavformat/bethsoftvid.c delete mode 100644 ffmpeg1/libavformat/bfi.c delete mode 100644 ffmpeg1/libavformat/bink.c delete mode 100644 ffmpeg1/libavformat/bintext.c delete mode 100644 ffmpeg1/libavformat/bit.c delete mode 100644 ffmpeg1/libavformat/bluray.c delete mode 100644 ffmpeg1/libavformat/bmv.c delete mode 100644 ffmpeg1/libavformat/brstm.c delete mode 100644 ffmpeg1/libavformat/c93.c delete mode 100644 ffmpeg1/libavformat/cache.c delete mode 100644 ffmpeg1/libavformat/caf.c delete mode 100644 ffmpeg1/libavformat/caf.h delete mode 100644 ffmpeg1/libavformat/cafdec.c delete mode 100644 ffmpeg1/libavformat/cafenc.c delete mode 100644 ffmpeg1/libavformat/cavsvideodec.c delete mode 100644 ffmpeg1/libavformat/cdg.c delete mode 100644 ffmpeg1/libavformat/cdxl.c delete mode 100644 ffmpeg1/libavformat/concat.c delete mode 100644 ffmpeg1/libavformat/concatdec.c delete mode 100644 ffmpeg1/libavformat/crcenc.c delete mode 100644 ffmpeg1/libavformat/crypto.c delete mode 100644 ffmpeg1/libavformat/cutils.c delete mode 100644 ffmpeg1/libavformat/data_uri.c delete mode 100644 ffmpeg1/libavformat/daud.c delete mode 100644 ffmpeg1/libavformat/dfa.c delete mode 100644 ffmpeg1/libavformat/diracdec.c delete mode 100644 ffmpeg1/libavformat/dnxhddec.c delete mode 100644 ffmpeg1/libavformat/dsicin.c delete mode 100644 ffmpeg1/libavformat/dtsdec.c delete mode 100644 ffmpeg1/libavformat/dtshddec.c delete mode 100644 ffmpeg1/libavformat/dv.c delete mode 100644 ffmpeg1/libavformat/dv.h delete mode 100644 ffmpeg1/libavformat/dvenc.c delete mode 100644 ffmpeg1/libavformat/dxa.c delete mode 100644 ffmpeg1/libavformat/eacdata.c delete mode 100644 ffmpeg1/libavformat/electronicarts.c delete mode 100644 ffmpeg1/libavformat/epafdec.c delete mode 100644 ffmpeg1/libavformat/ffm.h delete mode 100644 ffmpeg1/libavformat/ffmdec.c delete mode 100644 ffmpeg1/libavformat/ffmenc.c delete mode 100644 ffmpeg1/libavformat/ffmeta.h delete mode 100644 ffmpeg1/libavformat/ffmetadec.c delete mode 100644 ffmpeg1/libavformat/ffmetaenc.c delete mode 100644 ffmpeg1/libavformat/file.c delete mode 100644 ffmpeg1/libavformat/filmstripdec.c delete mode 100644 ffmpeg1/libavformat/filmstripenc.c delete mode 100644 ffmpeg1/libavformat/flacdec.c delete mode 100644 ffmpeg1/libavformat/flacenc.c delete mode 100644 ffmpeg1/libavformat/flacenc.h delete mode 100644 ffmpeg1/libavformat/flacenc_header.c delete mode 100644 ffmpeg1/libavformat/flic.c delete mode 100644 ffmpeg1/libavformat/flv.h delete mode 100644 ffmpeg1/libavformat/flvdec.c delete mode 100644 ffmpeg1/libavformat/flvenc.c delete mode 100644 ffmpeg1/libavformat/framecrcenc.c delete mode 100644 ffmpeg1/libavformat/framehash.c delete mode 100644 ffmpeg1/libavformat/frmdec.c delete mode 100644 ffmpeg1/libavformat/g722.c delete mode 100644 ffmpeg1/libavformat/g723_1.c delete mode 100644 ffmpeg1/libavformat/g729dec.c delete mode 100644 ffmpeg1/libavformat/gif.c delete mode 100644 ffmpeg1/libavformat/gifdec.c delete mode 100644 ffmpeg1/libavformat/gopher.c delete mode 100644 ffmpeg1/libavformat/gsmdec.c delete mode 100644 ffmpeg1/libavformat/gxf.c delete mode 100644 ffmpeg1/libavformat/gxf.h delete mode 100644 ffmpeg1/libavformat/gxfenc.c delete mode 100644 ffmpeg1/libavformat/h261dec.c delete mode 100644 ffmpeg1/libavformat/h263dec.c delete mode 100644 ffmpeg1/libavformat/h264dec.c delete mode 100644 ffmpeg1/libavformat/hls.c delete mode 100644 ffmpeg1/libavformat/hlsenc.c delete mode 100644 ffmpeg1/libavformat/hlsproto.c delete mode 100644 ffmpeg1/libavformat/http.c delete mode 100644 ffmpeg1/libavformat/http.h delete mode 100644 ffmpeg1/libavformat/httpauth.c delete mode 100644 ffmpeg1/libavformat/httpauth.h delete mode 100644 ffmpeg1/libavformat/icodec.c delete mode 100644 ffmpeg1/libavformat/icoenc.c delete mode 100644 ffmpeg1/libavformat/id3v1.c delete mode 100644 ffmpeg1/libavformat/id3v1.h delete mode 100644 ffmpeg1/libavformat/id3v2.c delete mode 100644 ffmpeg1/libavformat/id3v2.h delete mode 100644 ffmpeg1/libavformat/id3v2enc.c delete mode 100644 ffmpeg1/libavformat/idcin.c delete mode 100644 ffmpeg1/libavformat/idroqdec.c delete mode 100644 ffmpeg1/libavformat/idroqenc.c delete mode 100644 ffmpeg1/libavformat/iff.c delete mode 100644 ffmpeg1/libavformat/ilbc.c delete mode 100644 ffmpeg1/libavformat/img2.c delete mode 100644 ffmpeg1/libavformat/img2dec.c delete mode 100644 ffmpeg1/libavformat/img2enc.c delete mode 100644 ffmpeg1/libavformat/ingenientdec.c delete mode 100644 ffmpeg1/libavformat/internal.h delete mode 100644 ffmpeg1/libavformat/ipmovie.c delete mode 100644 ffmpeg1/libavformat/ircam.c delete mode 100644 ffmpeg1/libavformat/ircam.h delete mode 100644 ffmpeg1/libavformat/ircamdec.c delete mode 100644 ffmpeg1/libavformat/ircamenc.c delete mode 100644 ffmpeg1/libavformat/isom.c delete mode 100644 ffmpeg1/libavformat/isom.h delete mode 100644 ffmpeg1/libavformat/iss.c delete mode 100644 ffmpeg1/libavformat/iv8.c delete mode 100644 ffmpeg1/libavformat/ivfdec.c delete mode 100644 ffmpeg1/libavformat/ivfenc.c delete mode 100644 ffmpeg1/libavformat/jacosubdec.c delete mode 100644 ffmpeg1/libavformat/jacosubenc.c delete mode 100644 ffmpeg1/libavformat/jvdec.c delete mode 100644 ffmpeg1/libavformat/latmenc.c delete mode 100644 ffmpeg1/libavformat/libavformat.pc delete mode 100644 ffmpeg1/libavformat/libavformat.v delete mode 100644 ffmpeg1/libavformat/libmodplug.c delete mode 100644 ffmpeg1/libavformat/libnut.c delete mode 100644 ffmpeg1/libavformat/librtmp.c delete mode 100644 ffmpeg1/libavformat/lmlm4.c delete mode 100644 ffmpeg1/libavformat/loasdec.c delete mode 100644 ffmpeg1/libavformat/log2_tab.c delete mode 100644 ffmpeg1/libavformat/lvfdec.c delete mode 100644 ffmpeg1/libavformat/lxfdec.c delete mode 100644 ffmpeg1/libavformat/m4vdec.c delete mode 100644 ffmpeg1/libavformat/matroska.c delete mode 100644 ffmpeg1/libavformat/matroska.h delete mode 100644 ffmpeg1/libavformat/matroskadec.c delete mode 100644 ffmpeg1/libavformat/matroskaenc.c delete mode 100644 ffmpeg1/libavformat/md5enc.c delete mode 100644 ffmpeg1/libavformat/md5proto.c delete mode 100644 ffmpeg1/libavformat/metadata.c delete mode 100644 ffmpeg1/libavformat/metadata.h delete mode 100644 ffmpeg1/libavformat/mgsts.c delete mode 100644 ffmpeg1/libavformat/microdvddec.c delete mode 100644 ffmpeg1/libavformat/microdvdenc.c delete mode 100644 ffmpeg1/libavformat/mkvtimestamp_v2.c delete mode 100644 ffmpeg1/libavformat/mm.c delete mode 100644 ffmpeg1/libavformat/mmf.c delete mode 100644 ffmpeg1/libavformat/mms.c delete mode 100644 ffmpeg1/libavformat/mms.h delete mode 100644 ffmpeg1/libavformat/mmsh.c delete mode 100644 ffmpeg1/libavformat/mmst.c delete mode 100644 ffmpeg1/libavformat/mov.c delete mode 100644 ffmpeg1/libavformat/mov_chan.c delete mode 100644 ffmpeg1/libavformat/mov_chan.h delete mode 100644 ffmpeg1/libavformat/movenc.c delete mode 100644 ffmpeg1/libavformat/movenc.h delete mode 100644 ffmpeg1/libavformat/movenchint.c delete mode 100644 ffmpeg1/libavformat/mp3dec.c delete mode 100644 ffmpeg1/libavformat/mp3enc.c delete mode 100644 ffmpeg1/libavformat/mpc.c delete mode 100644 ffmpeg1/libavformat/mpc8.c delete mode 100644 ffmpeg1/libavformat/mpeg.c delete mode 100644 ffmpeg1/libavformat/mpeg.h delete mode 100644 ffmpeg1/libavformat/mpegenc.c delete mode 100644 ffmpeg1/libavformat/mpegts.c delete mode 100644 ffmpeg1/libavformat/mpegts.h delete mode 100644 ffmpeg1/libavformat/mpegtsenc.c delete mode 100644 ffmpeg1/libavformat/mpegvideodec.c delete mode 100644 ffmpeg1/libavformat/mpjpeg.c delete mode 100644 ffmpeg1/libavformat/mpl2dec.c delete mode 100644 ffmpeg1/libavformat/mpsubdec.c delete mode 100644 ffmpeg1/libavformat/msnwc_tcp.c delete mode 100644 ffmpeg1/libavformat/mtv.c delete mode 100644 ffmpeg1/libavformat/mux.c delete mode 100644 ffmpeg1/libavformat/mvdec.c delete mode 100644 ffmpeg1/libavformat/mvi.c delete mode 100644 ffmpeg1/libavformat/mxf.c delete mode 100644 ffmpeg1/libavformat/mxf.h delete mode 100644 ffmpeg1/libavformat/mxfdec.c delete mode 100644 ffmpeg1/libavformat/mxfenc.c delete mode 100644 ffmpeg1/libavformat/mxg.c delete mode 100644 ffmpeg1/libavformat/ncdec.c delete mode 100644 ffmpeg1/libavformat/network.c delete mode 100644 ffmpeg1/libavformat/network.h delete mode 100644 ffmpeg1/libavformat/nistspheredec.c delete mode 100644 ffmpeg1/libavformat/noproxy-test.c delete mode 100644 ffmpeg1/libavformat/nsvdec.c delete mode 100644 ffmpeg1/libavformat/nullenc.c delete mode 100644 ffmpeg1/libavformat/nut.c delete mode 100644 ffmpeg1/libavformat/nut.h delete mode 100644 ffmpeg1/libavformat/nutdec.c delete mode 100644 ffmpeg1/libavformat/nutenc.c delete mode 100644 ffmpeg1/libavformat/nuv.c delete mode 100644 ffmpeg1/libavformat/oggdec.c delete mode 100644 ffmpeg1/libavformat/oggdec.h delete mode 100644 ffmpeg1/libavformat/oggenc.c delete mode 100644 ffmpeg1/libavformat/oggparsecelt.c delete mode 100644 ffmpeg1/libavformat/oggparsedirac.c delete mode 100644 ffmpeg1/libavformat/oggparseflac.c delete mode 100644 ffmpeg1/libavformat/oggparseogm.c delete mode 100644 ffmpeg1/libavformat/oggparseopus.c delete mode 100644 ffmpeg1/libavformat/oggparseskeleton.c delete mode 100644 ffmpeg1/libavformat/oggparsespeex.c delete mode 100644 ffmpeg1/libavformat/oggparsetheora.c delete mode 100644 ffmpeg1/libavformat/oggparsevorbis.c delete mode 100644 ffmpeg1/libavformat/oma.c delete mode 100644 ffmpeg1/libavformat/oma.h delete mode 100644 ffmpeg1/libavformat/omadec.c delete mode 100644 ffmpeg1/libavformat/omaenc.c delete mode 100644 ffmpeg1/libavformat/options.c delete mode 100644 ffmpeg1/libavformat/options_table.h delete mode 100644 ffmpeg1/libavformat/os_support.c delete mode 100644 ffmpeg1/libavformat/os_support.h delete mode 100644 ffmpeg1/libavformat/paf.c delete mode 100644 ffmpeg1/libavformat/pcm.c delete mode 100644 ffmpeg1/libavformat/pcm.h delete mode 100644 ffmpeg1/libavformat/pcmdec.c delete mode 100644 ffmpeg1/libavformat/pcmenc.c delete mode 100644 ffmpeg1/libavformat/pjsdec.c delete mode 100644 ffmpeg1/libavformat/pmpdec.c delete mode 100644 ffmpeg1/libavformat/psxstr.c delete mode 100644 ffmpeg1/libavformat/pva.c delete mode 100644 ffmpeg1/libavformat/pvfdec.c delete mode 100644 ffmpeg1/libavformat/qcp.c delete mode 100644 ffmpeg1/libavformat/qtpalette.h delete mode 100644 ffmpeg1/libavformat/r3d.c delete mode 100644 ffmpeg1/libavformat/rawdec.c delete mode 100644 ffmpeg1/libavformat/rawdec.h delete mode 100644 ffmpeg1/libavformat/rawenc.c delete mode 100644 ffmpeg1/libavformat/rawenc.h delete mode 100644 ffmpeg1/libavformat/rawvideodec.c delete mode 100644 ffmpeg1/libavformat/rdt.c delete mode 100644 ffmpeg1/libavformat/rdt.h delete mode 100644 ffmpeg1/libavformat/realtextdec.c delete mode 100644 ffmpeg1/libavformat/riff.c delete mode 100644 ffmpeg1/libavformat/riff.h delete mode 100644 ffmpeg1/libavformat/rl2.c delete mode 100644 ffmpeg1/libavformat/rm.c delete mode 100644 ffmpeg1/libavformat/rm.h delete mode 100644 ffmpeg1/libavformat/rmdec.c delete mode 100644 ffmpeg1/libavformat/rmenc.c delete mode 100644 ffmpeg1/libavformat/rmsipr.c delete mode 100644 ffmpeg1/libavformat/rmsipr.h delete mode 100644 ffmpeg1/libavformat/rpl.c delete mode 100644 ffmpeg1/libavformat/rso.c delete mode 100644 ffmpeg1/libavformat/rso.h delete mode 100644 ffmpeg1/libavformat/rsodec.c delete mode 100644 ffmpeg1/libavformat/rsoenc.c delete mode 100644 ffmpeg1/libavformat/rtmp.h delete mode 100644 ffmpeg1/libavformat/rtmpcrypt.c delete mode 100644 ffmpeg1/libavformat/rtmpcrypt.h delete mode 100644 ffmpeg1/libavformat/rtmpdh.c delete mode 100644 ffmpeg1/libavformat/rtmpdh.h delete mode 100644 ffmpeg1/libavformat/rtmphttp.c delete mode 100644 ffmpeg1/libavformat/rtmppkt.c delete mode 100644 ffmpeg1/libavformat/rtmppkt.h delete mode 100644 ffmpeg1/libavformat/rtmpproto.c delete mode 100644 ffmpeg1/libavformat/rtp.c delete mode 100644 ffmpeg1/libavformat/rtp.h delete mode 100644 ffmpeg1/libavformat/rtpdec.c delete mode 100644 ffmpeg1/libavformat/rtpdec.h delete mode 100644 ffmpeg1/libavformat/rtpdec_amr.c delete mode 100644 ffmpeg1/libavformat/rtpdec_asf.c delete mode 100644 ffmpeg1/libavformat/rtpdec_formats.h delete mode 100644 ffmpeg1/libavformat/rtpdec_g726.c delete mode 100644 ffmpeg1/libavformat/rtpdec_h263.c delete mode 100644 ffmpeg1/libavformat/rtpdec_h263_rfc2190.c delete mode 100644 ffmpeg1/libavformat/rtpdec_h264.c delete mode 100644 ffmpeg1/libavformat/rtpdec_ilbc.c delete mode 100644 ffmpeg1/libavformat/rtpdec_jpeg.c delete mode 100644 ffmpeg1/libavformat/rtpdec_latm.c delete mode 100644 ffmpeg1/libavformat/rtpdec_mpeg12.c delete mode 100644 ffmpeg1/libavformat/rtpdec_mpeg4.c delete mode 100644 ffmpeg1/libavformat/rtpdec_mpegts.c delete mode 100644 ffmpeg1/libavformat/rtpdec_qcelp.c delete mode 100644 ffmpeg1/libavformat/rtpdec_qdm2.c delete mode 100644 ffmpeg1/libavformat/rtpdec_qt.c delete mode 100644 ffmpeg1/libavformat/rtpdec_svq3.c delete mode 100644 ffmpeg1/libavformat/rtpdec_vp8.c delete mode 100644 ffmpeg1/libavformat/rtpdec_xiph.c delete mode 100644 ffmpeg1/libavformat/rtpenc.c delete mode 100644 ffmpeg1/libavformat/rtpenc.h delete mode 100644 ffmpeg1/libavformat/rtpenc_aac.c delete mode 100644 ffmpeg1/libavformat/rtpenc_amr.c delete mode 100644 ffmpeg1/libavformat/rtpenc_chain.c delete mode 100644 ffmpeg1/libavformat/rtpenc_chain.h delete mode 100644 ffmpeg1/libavformat/rtpenc_h263.c delete mode 100644 ffmpeg1/libavformat/rtpenc_h263_rfc2190.c delete mode 100644 ffmpeg1/libavformat/rtpenc_h264.c delete mode 100644 ffmpeg1/libavformat/rtpenc_jpeg.c delete mode 100644 ffmpeg1/libavformat/rtpenc_latm.c delete mode 100644 ffmpeg1/libavformat/rtpenc_mpv.c delete mode 100644 ffmpeg1/libavformat/rtpenc_vp8.c delete mode 100644 ffmpeg1/libavformat/rtpenc_xiph.c delete mode 100644 ffmpeg1/libavformat/rtpproto.c delete mode 100644 ffmpeg1/libavformat/rtsp.c delete mode 100644 ffmpeg1/libavformat/rtsp.h delete mode 100644 ffmpeg1/libavformat/rtspcodes.h delete mode 100644 ffmpeg1/libavformat/rtspdec.c delete mode 100644 ffmpeg1/libavformat/rtspenc.c delete mode 100644 ffmpeg1/libavformat/samidec.c delete mode 100644 ffmpeg1/libavformat/sapdec.c delete mode 100644 ffmpeg1/libavformat/sapenc.c delete mode 100644 ffmpeg1/libavformat/sauce.c delete mode 100644 ffmpeg1/libavformat/sauce.h delete mode 100644 ffmpeg1/libavformat/sbgdec.c delete mode 100644 ffmpeg1/libavformat/sctp.c delete mode 100644 ffmpeg1/libavformat/sdp.c delete mode 100644 ffmpeg1/libavformat/seek-test.c delete mode 100644 ffmpeg1/libavformat/seek.c delete mode 100644 ffmpeg1/libavformat/seek.h delete mode 100644 ffmpeg1/libavformat/segafilm.c delete mode 100644 ffmpeg1/libavformat/segment.c delete mode 100644 ffmpeg1/libavformat/sierravmd.c delete mode 100644 ffmpeg1/libavformat/siff.c delete mode 100644 ffmpeg1/libavformat/smacker.c delete mode 100644 ffmpeg1/libavformat/smjpeg.c delete mode 100644 ffmpeg1/libavformat/smjpeg.h delete mode 100644 ffmpeg1/libavformat/smjpegdec.c delete mode 100644 ffmpeg1/libavformat/smjpegenc.c delete mode 100644 ffmpeg1/libavformat/smoothstreamingenc.c delete mode 100644 ffmpeg1/libavformat/smush.c delete mode 100644 ffmpeg1/libavformat/sol.c delete mode 100644 ffmpeg1/libavformat/sox.h delete mode 100644 ffmpeg1/libavformat/soxdec.c delete mode 100644 ffmpeg1/libavformat/soxenc.c delete mode 100644 ffmpeg1/libavformat/spdif.c delete mode 100644 ffmpeg1/libavformat/spdif.h delete mode 100644 ffmpeg1/libavformat/spdifdec.c delete mode 100644 ffmpeg1/libavformat/spdifenc.c delete mode 100644 ffmpeg1/libavformat/srtdec.c delete mode 100644 ffmpeg1/libavformat/srtenc.c delete mode 100644 ffmpeg1/libavformat/srtp.c delete mode 100644 ffmpeg1/libavformat/srtp.h delete mode 100644 ffmpeg1/libavformat/srtpproto.c delete mode 100644 ffmpeg1/libavformat/subtitles.c delete mode 100644 ffmpeg1/libavformat/subtitles.h delete mode 100644 ffmpeg1/libavformat/subviewer1dec.c delete mode 100644 ffmpeg1/libavformat/subviewerdec.c delete mode 100644 ffmpeg1/libavformat/swf.c delete mode 100644 ffmpeg1/libavformat/swf.h delete mode 100644 ffmpeg1/libavformat/swfdec.c delete mode 100644 ffmpeg1/libavformat/swfenc.c delete mode 100644 ffmpeg1/libavformat/takdec.c delete mode 100644 ffmpeg1/libavformat/tcp.c delete mode 100644 ffmpeg1/libavformat/tedcaptionsdec.c delete mode 100644 ffmpeg1/libavformat/tee.c delete mode 100644 ffmpeg1/libavformat/thp.c delete mode 100644 ffmpeg1/libavformat/tiertexseq.c delete mode 100644 ffmpeg1/libavformat/tls.c delete mode 100644 ffmpeg1/libavformat/tmv.c delete mode 100644 ffmpeg1/libavformat/tta.c delete mode 100644 ffmpeg1/libavformat/tty.c delete mode 100644 ffmpeg1/libavformat/txd.c delete mode 100644 ffmpeg1/libavformat/udp.c delete mode 100644 ffmpeg1/libavformat/url-test.c delete mode 100644 ffmpeg1/libavformat/url.h delete mode 100644 ffmpeg1/libavformat/urldecode.c delete mode 100644 ffmpeg1/libavformat/urldecode.h delete mode 100644 ffmpeg1/libavformat/utils.c delete mode 100644 ffmpeg1/libavformat/vc1test.c delete mode 100644 ffmpeg1/libavformat/vc1testenc.c delete mode 100644 ffmpeg1/libavformat/version.h delete mode 100644 ffmpeg1/libavformat/vivo.c delete mode 100644 ffmpeg1/libavformat/voc.c delete mode 100644 ffmpeg1/libavformat/voc.h delete mode 100644 ffmpeg1/libavformat/vocdec.c delete mode 100644 ffmpeg1/libavformat/vocenc.c delete mode 100644 ffmpeg1/libavformat/vorbiscomment.c delete mode 100644 ffmpeg1/libavformat/vorbiscomment.h delete mode 100644 ffmpeg1/libavformat/vplayerdec.c delete mode 100644 ffmpeg1/libavformat/vqf.c delete mode 100644 ffmpeg1/libavformat/w64.c delete mode 100644 ffmpeg1/libavformat/w64.h delete mode 100644 ffmpeg1/libavformat/wavdec.c delete mode 100644 ffmpeg1/libavformat/wavenc.c delete mode 100644 ffmpeg1/libavformat/wc3movie.c delete mode 100644 ffmpeg1/libavformat/webvttdec.c delete mode 100644 ffmpeg1/libavformat/westwood_aud.c delete mode 100644 ffmpeg1/libavformat/westwood_vqa.c delete mode 100644 ffmpeg1/libavformat/wtv.c delete mode 100644 ffmpeg1/libavformat/wtv.h delete mode 100644 ffmpeg1/libavformat/wtvdec.c delete mode 100644 ffmpeg1/libavformat/wtvenc.c delete mode 100644 ffmpeg1/libavformat/wv.c delete mode 100644 ffmpeg1/libavformat/wvenc.c delete mode 100644 ffmpeg1/libavformat/xa.c delete mode 100644 ffmpeg1/libavformat/xmv.c delete mode 100644 ffmpeg1/libavformat/xwma.c delete mode 100644 ffmpeg1/libavformat/yop.c delete mode 100644 ffmpeg1/libavformat/yuv4mpeg.c (limited to 'ffmpeg1/libavformat') diff --git a/ffmpeg1/libavformat/4xm.c b/ffmpeg1/libavformat/4xm.c deleted file mode 100644 index 1e142f5..0000000 --- a/ffmpeg1/libavformat/4xm.c +++ /dev/null @@ -1,372 +0,0 @@ -/* - * 4X Technologies .4xm File Demuxer (no muxer) - * Copyright (c) 2003 The ffmpeg Project - * - * 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 - */ - -/** - * @file - * 4X Technologies file demuxer - * by Mike Melanson (melanson@pcisys.net) - * for more information on the .4xm file format, visit: - * http://www.pcisys.net/~melanson/codecs/ - */ - -#include "libavutil/intreadwrite.h" -#include "libavutil/intfloat.h" -#include "avformat.h" -#include "internal.h" - -#define RIFF_TAG MKTAG('R', 'I', 'F', 'F') -#define FOURXMV_TAG MKTAG('4', 'X', 'M', 'V') -#define LIST_TAG MKTAG('L', 'I', 'S', 'T') -#define HEAD_TAG MKTAG('H', 'E', 'A', 'D') -#define TRK__TAG MKTAG('T', 'R', 'K', '_') -#define MOVI_TAG MKTAG('M', 'O', 'V', 'I') -#define VTRK_TAG MKTAG('V', 'T', 'R', 'K') -#define STRK_TAG MKTAG('S', 'T', 'R', 'K') -#define std__TAG MKTAG('s', 't', 'd', '_') -#define name_TAG MKTAG('n', 'a', 'm', 'e') -#define vtrk_TAG MKTAG('v', 't', 'r', 'k') -#define strk_TAG MKTAG('s', 't', 'r', 'k') -#define ifrm_TAG MKTAG('i', 'f', 'r', 'm') -#define pfrm_TAG MKTAG('p', 'f', 'r', 'm') -#define cfrm_TAG MKTAG('c', 'f', 'r', 'm') -#define ifr2_TAG MKTAG('i', 'f', 'r', '2') -#define pfr2_TAG MKTAG('p', 'f', 'r', '2') -#define cfr2_TAG MKTAG('c', 'f', 'r', '2') -#define snd__TAG MKTAG('s', 'n', 'd', '_') - -#define vtrk_SIZE 0x44 -#define strk_SIZE 0x28 - -#define GET_LIST_HEADER() \ - fourcc_tag = avio_rl32(pb); \ - size = avio_rl32(pb); \ - if (fourcc_tag != LIST_TAG) \ - return AVERROR_INVALIDDATA; \ - fourcc_tag = avio_rl32(pb); - -typedef struct AudioTrack { - int sample_rate; - int bits; - int channels; - int stream_index; - int adpcm; - int64_t audio_pts; -} AudioTrack; - -typedef struct FourxmDemuxContext { - int width; - int height; - int video_stream_index; - int track_count; - AudioTrack *tracks; - - int64_t video_pts; - float fps; -} FourxmDemuxContext; - -static int fourxm_probe(AVProbeData *p) -{ - if ((AV_RL32(&p->buf[0]) != RIFF_TAG) || - (AV_RL32(&p->buf[8]) != FOURXMV_TAG)) - return 0; - - return AVPROBE_SCORE_MAX; -} - -static int fourxm_read_header(AVFormatContext *s) -{ - AVIOContext *pb = s->pb; - unsigned int fourcc_tag; - unsigned int size; - int header_size; - FourxmDemuxContext *fourxm = s->priv_data; - unsigned char *header; - int i, ret; - AVStream *st; - - fourxm->track_count = 0; - fourxm->tracks = NULL; - fourxm->fps = 1.0; - - /* skip the first 3 32-bit numbers */ - avio_skip(pb, 12); - - /* check for LIST-HEAD */ - GET_LIST_HEADER(); - header_size = size - 4; - if (fourcc_tag != HEAD_TAG || header_size < 0) - return AVERROR_INVALIDDATA; - - /* allocate space for the header and load the whole thing */ - header = av_malloc(header_size); - if (!header) - return AVERROR(ENOMEM); - if (avio_read(pb, header, header_size) != header_size){ - av_free(header); - return AVERROR(EIO); - } - - /* take the lazy approach and search for any and all vtrk and strk chunks */ - for (i = 0; i < header_size - 8; i++) { - fourcc_tag = AV_RL32(&header[i]); - size = AV_RL32(&header[i + 4]); - if (size > header_size - i - 8 && (fourcc_tag == vtrk_TAG || fourcc_tag == strk_TAG)) { - av_log(s, AV_LOG_ERROR, "chunk larger than array %d>%d\n", size, header_size - i - 8); - return AVERROR_INVALIDDATA; - } - - if (fourcc_tag == std__TAG) { - if (header_size < i + 16) { - av_log(s, AV_LOG_ERROR, "std TAG truncated\n"); - return AVERROR_INVALIDDATA; - } - fourxm->fps = av_int2float(AV_RL32(&header[i + 12])); - } else if (fourcc_tag == vtrk_TAG) { - /* check that there is enough data */ - if (size != vtrk_SIZE) { - ret= AVERROR_INVALIDDATA; - goto fail; - } - fourxm->width = AV_RL32(&header[i + 36]); - fourxm->height = AV_RL32(&header[i + 40]); - - /* allocate a new AVStream */ - st = avformat_new_stream(s, NULL); - if (!st){ - ret= AVERROR(ENOMEM); - goto fail; - } - avpriv_set_pts_info(st, 60, 1, fourxm->fps); - - fourxm->video_stream_index = st->index; - - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = AV_CODEC_ID_4XM; - st->codec->extradata_size = 4; - st->codec->extradata = av_malloc(4); - AV_WL32(st->codec->extradata, AV_RL32(&header[i + 16])); - st->codec->width = fourxm->width; - st->codec->height = fourxm->height; - - i += 8 + size; - } else if (fourcc_tag == strk_TAG) { - int current_track; - /* check that there is enough data */ - if (size != strk_SIZE) { - ret= AVERROR_INVALIDDATA; - goto fail; - } - current_track = AV_RL32(&header[i + 8]); - if((unsigned)current_track >= UINT_MAX / sizeof(AudioTrack) - 1){ - av_log(s, AV_LOG_ERROR, "current_track too large\n"); - ret = AVERROR_INVALIDDATA; - goto fail; - } - if (current_track + 1 > fourxm->track_count) { - fourxm->tracks = av_realloc_f(fourxm->tracks, - sizeof(AudioTrack), - current_track + 1); - if (!fourxm->tracks) { - ret = AVERROR(ENOMEM); - goto fail; - } - memset(&fourxm->tracks[fourxm->track_count], 0, - sizeof(AudioTrack) * (current_track + 1 - fourxm->track_count)); - fourxm->track_count = current_track + 1; - } - fourxm->tracks[current_track].adpcm = AV_RL32(&header[i + 12]); - fourxm->tracks[current_track].channels = AV_RL32(&header[i + 36]); - fourxm->tracks[current_track].sample_rate = AV_RL32(&header[i + 40]); - fourxm->tracks[current_track].bits = AV_RL32(&header[i + 44]); - fourxm->tracks[current_track].audio_pts = 0; - if( fourxm->tracks[current_track].channels <= 0 - || fourxm->tracks[current_track].sample_rate <= 0 - || fourxm->tracks[current_track].bits < 0){ - av_log(s, AV_LOG_ERROR, "audio header invalid\n"); - ret = AVERROR_INVALIDDATA; - goto fail; - } - if(!fourxm->tracks[current_track].adpcm && fourxm->tracks[current_track].bits<8){ - av_log(s, AV_LOG_ERROR, "bits unspecified for non ADPCM\n"); - ret = AVERROR_INVALIDDATA; - goto fail; - } - i += 8 + size; - - /* allocate a new AVStream */ - st = avformat_new_stream(s, NULL); - if (!st){ - ret= AVERROR(ENOMEM); - goto fail; - } - - st->id = current_track; - avpriv_set_pts_info(st, 60, 1, fourxm->tracks[current_track].sample_rate); - - fourxm->tracks[current_track].stream_index = st->index; - - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_tag = 0; - st->codec->channels = fourxm->tracks[current_track].channels; - st->codec->sample_rate = fourxm->tracks[current_track].sample_rate; - st->codec->bits_per_coded_sample = fourxm->tracks[current_track].bits; - st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * - st->codec->bits_per_coded_sample; - st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample; - if (fourxm->tracks[current_track].adpcm){ - st->codec->codec_id = AV_CODEC_ID_ADPCM_4XM; - }else if (st->codec->bits_per_coded_sample == 8){ - st->codec->codec_id = AV_CODEC_ID_PCM_U8; - }else - st->codec->codec_id = AV_CODEC_ID_PCM_S16LE; - } - } - - /* skip over the LIST-MOVI chunk (which is where the stream should be */ - GET_LIST_HEADER(); - if (fourcc_tag != MOVI_TAG){ - ret= AVERROR_INVALIDDATA; - goto fail; - } - - av_free(header); - /* initialize context members */ - fourxm->video_pts = -1; /* first frame will push to 0 */ - - return 0; -fail: - av_freep(&fourxm->tracks); - av_free(header); - return ret; -} - -static int fourxm_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - FourxmDemuxContext *fourxm = s->priv_data; - AVIOContext *pb = s->pb; - unsigned int fourcc_tag; - unsigned int size; - int ret = 0; - unsigned int track_number; - int packet_read = 0; - unsigned char header[8]; - int audio_frame_count; - - while (!packet_read) { - - if ((ret = avio_read(s->pb, header, 8)) < 0) - return ret; - fourcc_tag = AV_RL32(&header[0]); - size = AV_RL32(&header[4]); - if (url_feof(pb)) - return AVERROR(EIO); - switch (fourcc_tag) { - - case LIST_TAG: - /* this is a good time to bump the video pts */ - fourxm->video_pts ++; - - /* skip the LIST-* tag and move on to the next fourcc */ - avio_rl32(pb); - break; - - case ifrm_TAG: - case pfrm_TAG: - case cfrm_TAG: - case ifr2_TAG: - case pfr2_TAG: - case cfr2_TAG: - /* allocate 8 more bytes than 'size' to account for fourcc - * and size */ - if (size + 8 < size || av_new_packet(pkt, size + 8)) - return AVERROR(EIO); - pkt->stream_index = fourxm->video_stream_index; - pkt->pts = fourxm->video_pts; - pkt->pos = avio_tell(s->pb); - memcpy(pkt->data, header, 8); - ret = avio_read(s->pb, &pkt->data[8], size); - - if (ret < 0){ - av_free_packet(pkt); - }else - packet_read = 1; - break; - - case snd__TAG: - track_number = avio_rl32(pb); - avio_skip(pb, 4); - size-=8; - - if (track_number < fourxm->track_count && fourxm->tracks[track_number].channels>0) { - ret= av_get_packet(s->pb, pkt, size); - if(ret<0) - return AVERROR(EIO); - pkt->stream_index = - fourxm->tracks[track_number].stream_index; - pkt->pts = fourxm->tracks[track_number].audio_pts; - packet_read = 1; - - /* pts accounting */ - audio_frame_count = size; - if (fourxm->tracks[track_number].adpcm) - audio_frame_count -= - 2 * (fourxm->tracks[track_number].channels); - audio_frame_count /= - fourxm->tracks[track_number].channels; - if (fourxm->tracks[track_number].adpcm){ - audio_frame_count *= 2; - }else - audio_frame_count /= - (fourxm->tracks[track_number].bits / 8); - fourxm->tracks[track_number].audio_pts += audio_frame_count; - - } else { - avio_skip(pb, size); - } - break; - - default: - avio_skip(pb, size); - break; - } - } - return ret; -} - -static int fourxm_read_close(AVFormatContext *s) -{ - FourxmDemuxContext *fourxm = s->priv_data; - - av_freep(&fourxm->tracks); - - return 0; -} - -AVInputFormat ff_fourxm_demuxer = { - .name = "4xm", - .long_name = NULL_IF_CONFIG_SMALL("4X Technologies"), - .priv_data_size = sizeof(FourxmDemuxContext), - .read_probe = fourxm_probe, - .read_header = fourxm_read_header, - .read_packet = fourxm_read_packet, - .read_close = fourxm_read_close, -}; diff --git a/ffmpeg1/libavformat/Makefile b/ffmpeg1/libavformat/Makefile deleted file mode 100644 index bc6ea16..0000000 --- a/ffmpeg1/libavformat/Makefile +++ /dev/null @@ -1,453 +0,0 @@ -include $(SUBDIR)../config.mak - -NAME = avformat -FFLIBS = avcodec avutil - -HEADERS = avformat.h \ - avio.h \ - version.h \ - -OBJS = allformats.o \ - avio.o \ - aviobuf.o \ - cutils.o \ - id3v1.o \ - id3v2.o \ - metadata.o \ - mux.o \ - options.o \ - os_support.o \ - riff.o \ - sdp.o \ - seek.o \ - utils.o \ - -OBJS-$(CONFIG_NETWORK) += network.o -OBJS-$(CONFIG_RTPDEC) += rdt.o \ - rtp.o \ - rtpdec.o \ - rtpdec_amr.o \ - rtpdec_asf.o \ - rtpdec_g726.o \ - rtpdec_h263.o \ - rtpdec_h263_rfc2190.o \ - rtpdec_h264.o \ - rtpdec_ilbc.o \ - rtpdec_jpeg.o \ - rtpdec_latm.o \ - rtpdec_mpeg12.o \ - rtpdec_mpeg4.o \ - rtpdec_mpegts.o \ - rtpdec_qcelp.o \ - rtpdec_qdm2.o \ - rtpdec_qt.o \ - rtpdec_svq3.o \ - rtpdec_vp8.o \ - rtpdec_xiph.o \ - srtp.o -OBJS-$(CONFIG_RTPENC_CHAIN) += rtpenc_chain.o rtp.o -OBJS-$(CONFIG_SHARED) += log2_tab.o - -# muxers/demuxers -OBJS-$(CONFIG_A64_MUXER) += a64.o rawenc.o -OBJS-$(CONFIG_AAC_DEMUXER) += aacdec.o rawdec.o -OBJS-$(CONFIG_AC3_DEMUXER) += ac3dec.o rawdec.o -OBJS-$(CONFIG_AC3_MUXER) += rawenc.o -OBJS-$(CONFIG_ACT_DEMUXER) += act.o -OBJS-$(CONFIG_ADF_DEMUXER) += bintext.o sauce.o -OBJS-$(CONFIG_ADX_DEMUXER) += adxdec.o -OBJS-$(CONFIG_ADX_MUXER) += rawenc.o -OBJS-$(CONFIG_ADTS_MUXER) += adtsenc.o -OBJS-$(CONFIG_AEA_DEMUXER) += aea.o pcm.o -OBJS-$(CONFIG_AFC_DEMUXER) += afc.o -OBJS-$(CONFIG_AIFF_DEMUXER) += aiffdec.o pcm.o isom.o \ - mov_chan.o -OBJS-$(CONFIG_AIFF_MUXER) += aiffenc.o isom.o id3v2enc.o -OBJS-$(CONFIG_AMR_DEMUXER) += amr.o -OBJS-$(CONFIG_AMR_MUXER) += amr.o -OBJS-$(CONFIG_ANM_DEMUXER) += anm.o -OBJS-$(CONFIG_APC_DEMUXER) += apc.o -OBJS-$(CONFIG_APE_DEMUXER) += ape.o apetag.o img2.o -OBJS-$(CONFIG_AQTITLE_DEMUXER) += aqtitledec.o subtitles.o -OBJS-$(CONFIG_ASF_DEMUXER) += asfdec.o asf.o asfcrypt.o \ - avlanguage.o -OBJS-$(CONFIG_ASF_MUXER) += asfenc.o asf.o -OBJS-$(CONFIG_ASS_DEMUXER) += assdec.o subtitles.o -OBJS-$(CONFIG_ASS_MUXER) += assenc.o -OBJS-$(CONFIG_AST_DEMUXER) += ast.o astdec.o -OBJS-$(CONFIG_AST_MUXER) += ast.o astenc.o -OBJS-$(CONFIG_AU_DEMUXER) += au.o pcm.o -OBJS-$(CONFIG_AU_MUXER) += au.o rawenc.o -OBJS-$(CONFIG_AVI_DEMUXER) += avidec.o -OBJS-$(CONFIG_AVI_MUXER) += avienc.o -OBJS-$(CONFIG_AVISYNTH) += avisynth.o -OBJS-$(CONFIG_AVM2_MUXER) += swfenc.o swf.o -OBJS-$(CONFIG_AVR_DEMUXER) += avr.o pcm.o -OBJS-$(CONFIG_AVS_DEMUXER) += avs.o vocdec.o voc.o -OBJS-$(CONFIG_BETHSOFTVID_DEMUXER) += bethsoftvid.o -OBJS-$(CONFIG_BFI_DEMUXER) += bfi.o -OBJS-$(CONFIG_BINK_DEMUXER) += bink.o -OBJS-$(CONFIG_BINTEXT_DEMUXER) += bintext.o sauce.o -OBJS-$(CONFIG_BIT_DEMUXER) += bit.o -OBJS-$(CONFIG_BIT_MUXER) += bit.o -OBJS-$(CONFIG_BMV_DEMUXER) += bmv.o -OBJS-$(CONFIG_BRSTM_DEMUXER) += brstm.o -OBJS-$(CONFIG_C93_DEMUXER) += c93.o vocdec.o voc.o -OBJS-$(CONFIG_CAF_DEMUXER) += cafdec.o caf.o mov.o mov_chan.o \ - isom.o -OBJS-$(CONFIG_CAF_MUXER) += cafenc.o caf.o riff.o isom.o -OBJS-$(CONFIG_CAVSVIDEO_DEMUXER) += cavsvideodec.o rawdec.o -OBJS-$(CONFIG_CAVSVIDEO_MUXER) += rawenc.o -OBJS-$(CONFIG_CDG_DEMUXER) += cdg.o -OBJS-$(CONFIG_CDXL_DEMUXER) += cdxl.o -OBJS-$(CONFIG_CONCAT_DEMUXER) += concatdec.o -OBJS-$(CONFIG_CRC_MUXER) += crcenc.o -OBJS-$(CONFIG_DAUD_DEMUXER) += daud.o -OBJS-$(CONFIG_DAUD_MUXER) += daud.o -OBJS-$(CONFIG_DFA_DEMUXER) += dfa.o -OBJS-$(CONFIG_DIRAC_DEMUXER) += diracdec.o rawdec.o -OBJS-$(CONFIG_DIRAC_MUXER) += rawenc.o -OBJS-$(CONFIG_DNXHD_DEMUXER) += dnxhddec.o rawdec.o -OBJS-$(CONFIG_DNXHD_MUXER) += rawenc.o -OBJS-$(CONFIG_DSICIN_DEMUXER) += dsicin.o -OBJS-$(CONFIG_DTSHD_DEMUXER) += dtshddec.o -OBJS-$(CONFIG_DTS_DEMUXER) += dtsdec.o rawdec.o -OBJS-$(CONFIG_DTS_MUXER) += rawenc.o -OBJS-$(CONFIG_DV_DEMUXER) += dv.o -OBJS-$(CONFIG_DV_MUXER) += dvenc.o -OBJS-$(CONFIG_DXA_DEMUXER) += dxa.o -OBJS-$(CONFIG_EA_CDATA_DEMUXER) += eacdata.o -OBJS-$(CONFIG_EA_DEMUXER) += electronicarts.o -OBJS-$(CONFIG_EAC3_DEMUXER) += ac3dec.o rawdec.o -OBJS-$(CONFIG_EAC3_MUXER) += rawenc.o -OBJS-$(CONFIG_EPAF_DEMUXER) += epafdec.o pcm.o -OBJS-$(CONFIG_FFM_DEMUXER) += ffmdec.o -OBJS-$(CONFIG_FFM_MUXER) += ffmenc.o -OBJS-$(CONFIG_FFMETADATA_DEMUXER) += ffmetadec.o -OBJS-$(CONFIG_FFMETADATA_MUXER) += ffmetaenc.o -OBJS-$(CONFIG_FILMSTRIP_DEMUXER) += filmstripdec.o -OBJS-$(CONFIG_FILMSTRIP_MUXER) += filmstripenc.o -OBJS-$(CONFIG_FLAC_DEMUXER) += flacdec.o rawdec.o \ - oggparsevorbis.o \ - vorbiscomment.o -OBJS-$(CONFIG_FLAC_MUXER) += flacenc.o flacenc_header.o \ - vorbiscomment.o -OBJS-$(CONFIG_FLIC_DEMUXER) += flic.o -OBJS-$(CONFIG_FLV_DEMUXER) += flvdec.o -OBJS-$(CONFIG_FLV_MUXER) += flvenc.o avc.o -OBJS-$(CONFIG_FOURXM_DEMUXER) += 4xm.o -OBJS-$(CONFIG_FRAMECRC_MUXER) += framecrcenc.o framehash.o -OBJS-$(CONFIG_FRAMEMD5_MUXER) += md5enc.o framehash.o -OBJS-$(CONFIG_FRM_DEMUXER) += frmdec.o -OBJS-$(CONFIG_GIF_MUXER) += gif.o -OBJS-$(CONFIG_GIF_DEMUXER) += gifdec.o -OBJS-$(CONFIG_GSM_DEMUXER) += gsmdec.o -OBJS-$(CONFIG_GXF_DEMUXER) += gxf.o -OBJS-$(CONFIG_GXF_MUXER) += gxfenc.o audiointerleave.o -OBJS-$(CONFIG_G722_DEMUXER) += g722.o rawdec.o -OBJS-$(CONFIG_G722_MUXER) += rawenc.o -OBJS-$(CONFIG_G723_1_DEMUXER) += g723_1.o -OBJS-$(CONFIG_G723_1_MUXER) += rawenc.o -OBJS-$(CONFIG_G729_DEMUXER) += g729dec.o -OBJS-$(CONFIG_H261_DEMUXER) += h261dec.o rawdec.o -OBJS-$(CONFIG_H261_MUXER) += rawenc.o -OBJS-$(CONFIG_H263_DEMUXER) += h263dec.o rawdec.o -OBJS-$(CONFIG_H263_MUXER) += rawenc.o -OBJS-$(CONFIG_H264_DEMUXER) += h264dec.o rawdec.o -OBJS-$(CONFIG_H264_MUXER) += rawenc.o -OBJS-$(CONFIG_HLS_DEMUXER) += hls.o -OBJS-$(CONFIG_HLS_MUXER) += hlsenc.o mpegtsenc.o -OBJS-$(CONFIG_ICO_DEMUXER) += icodec.o -OBJS-$(CONFIG_ICO_MUXER) += icoenc.o -OBJS-$(CONFIG_IDCIN_DEMUXER) += idcin.o -OBJS-$(CONFIG_IDF_DEMUXER) += bintext.o sauce.o -OBJS-$(CONFIG_IFF_DEMUXER) += iff.o -OBJS-$(CONFIG_ILBC_DEMUXER) += ilbc.o -OBJS-$(CONFIG_ILBC_MUXER) += ilbc.o -OBJS-$(CONFIG_IMAGE2_DEMUXER) += img2dec.o img2.o -OBJS-$(CONFIG_IMAGE2_MUXER) += img2enc.o img2.o -OBJS-$(CONFIG_IMAGE2PIPE_DEMUXER) += img2dec.o img2.o -OBJS-$(CONFIG_IMAGE2PIPE_MUXER) += img2enc.o img2.o -OBJS-$(CONFIG_INGENIENT_DEMUXER) += ingenientdec.o rawdec.o -OBJS-$(CONFIG_IPMOVIE_DEMUXER) += ipmovie.o -OBJS-$(CONFIG_IRCAM_DEMUXER) += ircamdec.o ircam.o pcm.o -OBJS-$(CONFIG_IRCAM_MUXER) += ircamenc.o ircam.o rawenc.o -OBJS-$(CONFIG_ISS_DEMUXER) += iss.o -OBJS-$(CONFIG_IV8_DEMUXER) += iv8.o -OBJS-$(CONFIG_IVF_DEMUXER) += ivfdec.o -OBJS-$(CONFIG_IVF_MUXER) += ivfenc.o -OBJS-$(CONFIG_JACOSUB_DEMUXER) += jacosubdec.o subtitles.o -OBJS-$(CONFIG_JACOSUB_MUXER) += jacosubenc.o rawenc.o -OBJS-$(CONFIG_JV_DEMUXER) += jvdec.o -OBJS-$(CONFIG_LATM_DEMUXER) += rawdec.o -OBJS-$(CONFIG_LATM_MUXER) += latmenc.o rawenc.o -OBJS-$(CONFIG_LMLM4_DEMUXER) += lmlm4.o -OBJS-$(CONFIG_LOAS_DEMUXER) += loasdec.o rawdec.o -OBJS-$(CONFIG_LVF_DEMUXER) += lvfdec.o -OBJS-$(CONFIG_LXF_DEMUXER) += lxfdec.o -OBJS-$(CONFIG_M4V_DEMUXER) += m4vdec.o rawdec.o -OBJS-$(CONFIG_M4V_MUXER) += rawenc.o -OBJS-$(CONFIG_MATROSKA_DEMUXER) += matroskadec.o matroska.o \ - isom.o rmsipr.o -OBJS-$(CONFIG_MATROSKA_MUXER) += matroskaenc.o matroska.o \ - isom.o avc.o \ - flacenc_header.o avlanguage.o -OBJS-$(CONFIG_MD5_MUXER) += md5enc.o -OBJS-$(CONFIG_MGSTS_DEMUXER) += mgsts.o -OBJS-$(CONFIG_MICRODVD_DEMUXER) += microdvddec.o subtitles.o -OBJS-$(CONFIG_MICRODVD_MUXER) += microdvdenc.o -OBJS-$(CONFIG_MJPEG_DEMUXER) += rawdec.o -OBJS-$(CONFIG_MJPEG_MUXER) += rawenc.o -OBJS-$(CONFIG_MLP_DEMUXER) += rawdec.o -OBJS-$(CONFIG_MLP_MUXER) += rawenc.o -OBJS-$(CONFIG_MM_DEMUXER) += mm.o -OBJS-$(CONFIG_MMF_DEMUXER) += mmf.o -OBJS-$(CONFIG_MMF_MUXER) += mmf.o rawenc.o -OBJS-$(CONFIG_MOV_DEMUXER) += mov.o isom.o mov_chan.o -OBJS-$(CONFIG_MOV_MUXER) += movenc.o isom.o avc.o \ - movenchint.o mov_chan.o rtp.o -OBJS-$(CONFIG_MP2_MUXER) += mp3enc.o rawenc.o id3v2enc.o -OBJS-$(CONFIG_MP3_DEMUXER) += mp3dec.o -OBJS-$(CONFIG_MP3_MUXER) += mp3enc.o rawenc.o id3v2enc.o -OBJS-$(CONFIG_MPC_DEMUXER) += mpc.o apetag.o img2.o -OBJS-$(CONFIG_MPC8_DEMUXER) += mpc8.o apetag.o img2.o -OBJS-$(CONFIG_MPEG1SYSTEM_MUXER) += mpegenc.o -OBJS-$(CONFIG_MPEG1VCD_MUXER) += mpegenc.o -OBJS-$(CONFIG_MPEG2DVD_MUXER) += mpegenc.o -OBJS-$(CONFIG_MPEG2VOB_MUXER) += mpegenc.o -OBJS-$(CONFIG_MPEG2SVCD_MUXER) += mpegenc.o -OBJS-$(CONFIG_MPEG1VIDEO_MUXER) += rawenc.o -OBJS-$(CONFIG_MPEG2VIDEO_MUXER) += rawenc.o -OBJS-$(CONFIG_MPEGPS_DEMUXER) += mpeg.o -OBJS-$(CONFIG_MPEGTS_DEMUXER) += mpegts.o isom.o -OBJS-$(CONFIG_MPEGTS_MUXER) += mpegtsenc.o -OBJS-$(CONFIG_MPEGVIDEO_DEMUXER) += mpegvideodec.o rawdec.o -OBJS-$(CONFIG_MPJPEG_MUXER) += mpjpeg.o -OBJS-$(CONFIG_MPL2_DEMUXER) += mpl2dec.o subtitles.o -OBJS-$(CONFIG_MPSUB_DEMUXER) += mpsubdec.o subtitles.o -OBJS-$(CONFIG_MSNWC_TCP_DEMUXER) += msnwc_tcp.o -OBJS-$(CONFIG_MTV_DEMUXER) += mtv.o -OBJS-$(CONFIG_MVI_DEMUXER) += mvi.o -OBJS-$(CONFIG_MV_DEMUXER) += mvdec.o -OBJS-$(CONFIG_MXF_DEMUXER) += mxfdec.o mxf.o -OBJS-$(CONFIG_MXF_MUXER) += mxfenc.o mxf.o audiointerleave.o -OBJS-$(CONFIG_MXG_DEMUXER) += mxg.o -OBJS-$(CONFIG_NC_DEMUXER) += ncdec.o -OBJS-$(CONFIG_NISTSPHERE_DEMUXER) += nistspheredec.o pcm.o -OBJS-$(CONFIG_NSV_DEMUXER) += nsvdec.o -OBJS-$(CONFIG_NULL_MUXER) += nullenc.o -OBJS-$(CONFIG_NUT_DEMUXER) += nutdec.o nut.o -OBJS-$(CONFIG_NUT_MUXER) += nutenc.o nut.o -OBJS-$(CONFIG_NUV_DEMUXER) += nuv.o -OBJS-$(CONFIG_OGG_DEMUXER) += oggdec.o \ - oggparsecelt.o \ - oggparsedirac.o \ - oggparseflac.o \ - oggparseogm.o \ - oggparseopus.o \ - oggparseskeleton.o \ - oggparsespeex.o \ - oggparsetheora.o \ - oggparsevorbis.o \ - vorbiscomment.o -OBJS-$(CONFIG_OGG_MUXER) += oggenc.o \ - vorbiscomment.o -OBJS-$(CONFIG_OMA_DEMUXER) += omadec.o pcm.o oma.o -OBJS-$(CONFIG_OMA_MUXER) += omaenc.o rawenc.o oma.o id3v2enc.o -OBJS-$(CONFIG_PAF_DEMUXER) += paf.o -OBJS-$(CONFIG_PCM_ALAW_DEMUXER) += pcmdec.o pcm.o -OBJS-$(CONFIG_PCM_ALAW_MUXER) += pcmenc.o rawenc.o -OBJS-$(CONFIG_PCM_F32BE_DEMUXER) += pcmdec.o pcm.o -OBJS-$(CONFIG_PCM_F32BE_MUXER) += pcmenc.o rawenc.o -OBJS-$(CONFIG_PCM_F32LE_DEMUXER) += pcmdec.o pcm.o -OBJS-$(CONFIG_PCM_F32LE_MUXER) += pcmenc.o rawenc.o -OBJS-$(CONFIG_PCM_F64BE_DEMUXER) += pcmdec.o pcm.o -OBJS-$(CONFIG_PCM_F64BE_MUXER) += pcmenc.o rawenc.o -OBJS-$(CONFIG_PCM_F64LE_DEMUXER) += pcmdec.o pcm.o -OBJS-$(CONFIG_PCM_F64LE_MUXER) += pcmenc.o rawenc.o -OBJS-$(CONFIG_PCM_MULAW_DEMUXER) += pcmdec.o pcm.o -OBJS-$(CONFIG_PCM_MULAW_MUXER) += pcmenc.o rawenc.o -OBJS-$(CONFIG_PCM_S16BE_DEMUXER) += pcmdec.o pcm.o -OBJS-$(CONFIG_PCM_S16BE_MUXER) += pcmenc.o rawenc.o -OBJS-$(CONFIG_PCM_S16LE_DEMUXER) += pcmdec.o pcm.o -OBJS-$(CONFIG_PCM_S16LE_MUXER) += pcmenc.o rawenc.o -OBJS-$(CONFIG_PCM_S24BE_DEMUXER) += pcmdec.o pcm.o -OBJS-$(CONFIG_PCM_S24BE_MUXER) += pcmenc.o rawenc.o -OBJS-$(CONFIG_PCM_S24LE_DEMUXER) += pcmdec.o pcm.o -OBJS-$(CONFIG_PCM_S24LE_MUXER) += pcmenc.o rawenc.o -OBJS-$(CONFIG_PCM_S32BE_DEMUXER) += pcmdec.o pcm.o -OBJS-$(CONFIG_PCM_S32BE_MUXER) += pcmenc.o rawenc.o -OBJS-$(CONFIG_PCM_S32LE_DEMUXER) += pcmdec.o pcm.o -OBJS-$(CONFIG_PCM_S32LE_MUXER) += pcmenc.o rawenc.o -OBJS-$(CONFIG_PCM_S8_DEMUXER) += pcmdec.o pcm.o -OBJS-$(CONFIG_PCM_S8_MUXER) += pcmenc.o rawenc.o -OBJS-$(CONFIG_PCM_U16BE_DEMUXER) += pcmdec.o pcm.o -OBJS-$(CONFIG_PCM_U16BE_MUXER) += pcmenc.o rawenc.o -OBJS-$(CONFIG_PCM_U16LE_DEMUXER) += pcmdec.o pcm.o -OBJS-$(CONFIG_PCM_U16LE_MUXER) += pcmenc.o rawenc.o -OBJS-$(CONFIG_PCM_U24BE_DEMUXER) += pcmdec.o pcm.o -OBJS-$(CONFIG_PCM_U24BE_MUXER) += pcmenc.o rawenc.o -OBJS-$(CONFIG_PCM_U24LE_DEMUXER) += pcmdec.o pcm.o -OBJS-$(CONFIG_PCM_U24LE_MUXER) += pcmenc.o rawenc.o -OBJS-$(CONFIG_PCM_U32BE_DEMUXER) += pcmdec.o pcm.o -OBJS-$(CONFIG_PCM_U32BE_MUXER) += pcmenc.o rawenc.o -OBJS-$(CONFIG_PCM_U32LE_DEMUXER) += pcmdec.o pcm.o -OBJS-$(CONFIG_PCM_U32LE_MUXER) += pcmenc.o rawenc.o -OBJS-$(CONFIG_PCM_U8_DEMUXER) += pcmdec.o pcm.o -OBJS-$(CONFIG_PCM_U8_MUXER) += pcmenc.o rawenc.o -OBJS-$(CONFIG_PJS_DEMUXER) += pjsdec.o subtitles.o -OBJS-$(CONFIG_PMP_DEMUXER) += pmpdec.o -OBJS-$(CONFIG_PVA_DEMUXER) += pva.o -OBJS-$(CONFIG_PVF_DEMUXER) += pvfdec.o pcm.o -OBJS-$(CONFIG_QCP_DEMUXER) += qcp.o -OBJS-$(CONFIG_R3D_DEMUXER) += r3d.o -OBJS-$(CONFIG_RAWVIDEO_DEMUXER) += rawvideodec.o -OBJS-$(CONFIG_RAWVIDEO_MUXER) += rawenc.o -OBJS-$(CONFIG_REALTEXT_DEMUXER) += realtextdec.o subtitles.o -OBJS-$(CONFIG_RL2_DEMUXER) += rl2.o -OBJS-$(CONFIG_RM_DEMUXER) += rmdec.o rm.o rmsipr.o -OBJS-$(CONFIG_RM_MUXER) += rmenc.o rm.o -OBJS-$(CONFIG_ROQ_DEMUXER) += idroqdec.o -OBJS-$(CONFIG_ROQ_MUXER) += idroqenc.o rawenc.o -OBJS-$(CONFIG_RSO_DEMUXER) += rsodec.o rso.o pcm.o -OBJS-$(CONFIG_RSO_MUXER) += rsoenc.o rso.o -OBJS-$(CONFIG_RPL_DEMUXER) += rpl.o -OBJS-$(CONFIG_RTP_MUXER) += rtp.o \ - rtpenc_aac.o \ - rtpenc_latm.o \ - rtpenc_amr.o \ - rtpenc_h263.o \ - rtpenc_h263_rfc2190.o \ - rtpenc_jpeg.o \ - rtpenc_mpv.o \ - rtpenc.o \ - rtpenc_h264.o \ - rtpenc_vp8.o \ - rtpenc_xiph.o \ - avc.o -OBJS-$(CONFIG_RTSP_DEMUXER) += rtsp.o rtspdec.o httpauth.o \ - urldecode.o -OBJS-$(CONFIG_RTSP_MUXER) += rtsp.o rtspenc.o httpauth.o \ - urldecode.o -OBJS-$(CONFIG_SAMI_DEMUXER) += samidec.o subtitles.o -OBJS-$(CONFIG_SAP_DEMUXER) += sapdec.o -OBJS-$(CONFIG_SAP_MUXER) += sapenc.o -OBJS-$(CONFIG_SBG_DEMUXER) += sbgdec.o -OBJS-$(CONFIG_SDP_DEMUXER) += rtsp.o -OBJS-$(CONFIG_SEGAFILM_DEMUXER) += segafilm.o -OBJS-$(CONFIG_SEGMENT_MUXER) += segment.o -OBJS-$(CONFIG_SHORTEN_DEMUXER) += rawdec.o -OBJS-$(CONFIG_SIFF_DEMUXER) += siff.o -OBJS-$(CONFIG_SMACKER_DEMUXER) += smacker.o -OBJS-$(CONFIG_SMJPEG_DEMUXER) += smjpegdec.o smjpeg.o -OBJS-$(CONFIG_SMJPEG_MUXER) += smjpegenc.o smjpeg.o -OBJS-$(CONFIG_SMOOTHSTREAMING_MUXER) += smoothstreamingenc.o isom.o -OBJS-$(CONFIG_SMUSH_DEMUXER) += smush.o -OBJS-$(CONFIG_SOL_DEMUXER) += sol.o pcm.o -OBJS-$(CONFIG_SOX_DEMUXER) += soxdec.o pcm.o -OBJS-$(CONFIG_SOX_MUXER) += soxenc.o rawenc.o -OBJS-$(CONFIG_SPDIF_DEMUXER) += spdif.o spdifdec.o -OBJS-$(CONFIG_SPDIF_MUXER) += spdif.o spdifenc.o -OBJS-$(CONFIG_SRT_DEMUXER) += srtdec.o subtitles.o -OBJS-$(CONFIG_SRT_MUXER) += srtenc.o -OBJS-$(CONFIG_STR_DEMUXER) += psxstr.o -OBJS-$(CONFIG_SUBVIEWER1_DEMUXER) += subviewer1dec.o subtitles.o -OBJS-$(CONFIG_SUBVIEWER_DEMUXER) += subviewerdec.o subtitles.o -OBJS-$(CONFIG_SWF_DEMUXER) += swfdec.o swf.o -OBJS-$(CONFIG_SWF_MUXER) += swfenc.o swf.o -OBJS-$(CONFIG_TAK_DEMUXER) += takdec.o apetag.o img2.o rawdec.o -OBJS-$(CONFIG_TEDCAPTIONS_DEMUXER) += tedcaptionsdec.o subtitles.o -OBJS-$(CONFIG_TEE_MUXER) += tee.o -OBJS-$(CONFIG_THP_DEMUXER) += thp.o -OBJS-$(CONFIG_TIERTEXSEQ_DEMUXER) += tiertexseq.o -OBJS-$(CONFIG_MKVTIMESTAMP_V2_MUXER) += mkvtimestamp_v2.o -OBJS-$(CONFIG_TMV_DEMUXER) += tmv.o -OBJS-$(CONFIG_TRUEHD_DEMUXER) += rawdec.o -OBJS-$(CONFIG_TRUEHD_MUXER) += rawenc.o -OBJS-$(CONFIG_TTA_DEMUXER) += tta.o -OBJS-$(CONFIG_TTY_DEMUXER) += tty.o sauce.o -OBJS-$(CONFIG_TXD_DEMUXER) += txd.o -OBJS-$(CONFIG_VC1_DEMUXER) += rawdec.o -OBJS-$(CONFIG_VC1T_DEMUXER) += vc1test.o -OBJS-$(CONFIG_VC1T_MUXER) += vc1testenc.o -OBJS-$(CONFIG_VIVO_DEMUXER) += vivo.o -OBJS-$(CONFIG_VMD_DEMUXER) += sierravmd.o -OBJS-$(CONFIG_VOBSUB_DEMUXER) += subtitles.o # mpeg demuxer is in the dependencies -OBJS-$(CONFIG_VOC_DEMUXER) += vocdec.o voc.o -OBJS-$(CONFIG_VOC_MUXER) += vocenc.o voc.o -OBJS-$(CONFIG_VPLAYER_DEMUXER) += vplayerdec.o subtitles.o -OBJS-$(CONFIG_VQF_DEMUXER) += vqf.o -OBJS-$(CONFIG_W64_DEMUXER) += wavdec.o w64.o pcm.o -OBJS-$(CONFIG_W64_MUXER) += wavenc.o w64.o -OBJS-$(CONFIG_WAV_DEMUXER) += wavdec.o pcm.o -OBJS-$(CONFIG_WAV_MUXER) += wavenc.o -OBJS-$(CONFIG_WC3_DEMUXER) += wc3movie.o -OBJS-$(CONFIG_WEBM_MUXER) += matroskaenc.o matroska.o \ - isom.o avc.o \ - flacenc_header.o avlanguage.o -OBJS-$(CONFIG_WEBVTT_DEMUXER) += webvttdec.o subtitles.o -OBJS-$(CONFIG_WSAUD_DEMUXER) += westwood_aud.o -OBJS-$(CONFIG_WSVQA_DEMUXER) += westwood_vqa.o -OBJS-$(CONFIG_WTV_DEMUXER) += wtvdec.o wtv.o asfdec.o asf.o asfcrypt.o \ - avlanguage.o mpegts.o isom.o -OBJS-$(CONFIG_WTV_MUXER) += wtvenc.o wtv.o asf.o asfenc.o -OBJS-$(CONFIG_WV_DEMUXER) += wv.o apetag.o img2.o -OBJS-$(CONFIG_WV_MUXER) += wvenc.o apetagenc.o -OBJS-$(CONFIG_XA_DEMUXER) += xa.o -OBJS-$(CONFIG_XBIN_DEMUXER) += bintext.o sauce.o -OBJS-$(CONFIG_XMV_DEMUXER) += xmv.o -OBJS-$(CONFIG_XWMA_DEMUXER) += xwma.o -OBJS-$(CONFIG_YOP_DEMUXER) += yop.o -OBJS-$(CONFIG_YUV4MPEGPIPE_MUXER) += yuv4mpeg.o -OBJS-$(CONFIG_YUV4MPEGPIPE_DEMUXER) += yuv4mpeg.o - -# external libraries -OBJS-$(CONFIG_LIBMODPLUG_DEMUXER) += libmodplug.o -OBJS-$(CONFIG_LIBNUT_DEMUXER) += libnut.o -OBJS-$(CONFIG_LIBNUT_MUXER) += libnut.o -OBJS-$(CONFIG_LIBRTMP) += librtmp.o - -# protocols I/O -OBJS-$(CONFIG_APPLEHTTP_PROTOCOL) += hlsproto.o -OBJS-$(CONFIG_BLURAY_PROTOCOL) += bluray.o -OBJS-$(CONFIG_CACHE_PROTOCOL) += cache.o -OBJS-$(CONFIG_CONCAT_PROTOCOL) += concat.o -OBJS-$(CONFIG_CRYPTO_PROTOCOL) += crypto.o -OBJS-$(CONFIG_DATA_PROTOCOL) += data_uri.o -OBJS-$(CONFIG_FFRTMPCRYPT_PROTOCOL) += rtmpcrypt.o rtmpdh.o -OBJS-$(CONFIG_FFRTMPHTTP_PROTOCOL) += rtmphttp.o -OBJS-$(CONFIG_FILE_PROTOCOL) += file.o -OBJS-$(CONFIG_GOPHER_PROTOCOL) += gopher.o -OBJS-$(CONFIG_HLS_PROTOCOL) += hlsproto.o -OBJS-$(CONFIG_HTTP_PROTOCOL) += http.o httpauth.o urldecode.o -OBJS-$(CONFIG_HTTPPROXY_PROTOCOL) += http.o httpauth.o urldecode.o -OBJS-$(CONFIG_HTTPS_PROTOCOL) += http.o httpauth.o urldecode.o -OBJS-$(CONFIG_MMSH_PROTOCOL) += mmsh.o mms.o asf.o -OBJS-$(CONFIG_MMST_PROTOCOL) += mmst.o mms.o asf.o -OBJS-$(CONFIG_MD5_PROTOCOL) += md5proto.o -OBJS-$(CONFIG_PIPE_PROTOCOL) += file.o -OBJS-$(CONFIG_RTMP_PROTOCOL) += rtmpproto.o rtmppkt.o -OBJS-$(CONFIG_RTMPE_PROTOCOL) += rtmpproto.o rtmppkt.o -OBJS-$(CONFIG_RTMPS_PROTOCOL) += rtmpproto.o rtmppkt.o -OBJS-$(CONFIG_RTMPT_PROTOCOL) += rtmpproto.o rtmppkt.o -OBJS-$(CONFIG_RTMPTE_PROTOCOL) += rtmpproto.o rtmppkt.o -OBJS-$(CONFIG_RTMPTS_PROTOCOL) += rtmpproto.o rtmppkt.o -OBJS-$(CONFIG_RTP_PROTOCOL) += rtpproto.o -OBJS-$(CONFIG_SCTP_PROTOCOL) += sctp.o -OBJS-$(CONFIG_SRTP_PROTOCOL) += srtpproto.o srtp.o -OBJS-$(CONFIG_TCP_PROTOCOL) += tcp.o -OBJS-$(CONFIG_TLS_PROTOCOL) += tls.o -OBJS-$(CONFIG_UDP_PROTOCOL) += udp.o - -SKIPHEADERS-$(CONFIG_FFRTMPCRYPT_PROTOCOL) += rtmpdh.h -SKIPHEADERS-$(CONFIG_NETWORK) += network.h rtsp.h -TESTPROGS = noproxy \ - seek \ - srtp \ - url \ - -TOOLS = aviocat \ - ismindex \ - pktdumper \ - probetest \ - seek_print \ diff --git a/ffmpeg1/libavformat/a64.c b/ffmpeg1/libavformat/a64.c deleted file mode 100644 index 786c75c..0000000 --- a/ffmpeg1/libavformat/a64.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * a64 muxer - * Copyright (c) 2009 Tobias Bindhammer - * - * 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 "libavcodec/avcodec.h" -#include "libavcodec/bytestream.h" -#include "avformat.h" -#include "rawenc.h" - -static int a64_write_header(struct AVFormatContext *s) -{ - AVCodecContext *avctx = s->streams[0]->codec; - uint8_t header[5] = { - 0x00, //load - 0x40, //address - 0x00, //mode - 0x00, //charset_lifetime (multi only) - 0x00 //fps in 50/fps; - }; - switch (avctx->codec->id) { - case AV_CODEC_ID_A64_MULTI: - header[2] = 0x00; - header[3] = AV_RB32(avctx->extradata+0); - header[4] = 2; - break; - case AV_CODEC_ID_A64_MULTI5: - header[2] = 0x01; - header[3] = AV_RB32(avctx->extradata+0); - header[4] = 3; - break; - default: - return AVERROR(EINVAL); - } - avio_write(s->pb, header, 2); - return 0; -} - -AVOutputFormat ff_a64_muxer = { - .name = "a64", - .long_name = NULL_IF_CONFIG_SMALL("a64 - video for Commodore 64"), - .extensions = "a64, A64", - .video_codec = AV_CODEC_ID_A64_MULTI, - .write_header = a64_write_header, - .write_packet = ff_raw_write_packet, -}; diff --git a/ffmpeg1/libavformat/aacdec.c b/ffmpeg1/libavformat/aacdec.c deleted file mode 100644 index 7c17dd0..0000000 --- a/ffmpeg1/libavformat/aacdec.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * raw ADTS AAC demuxer - * Copyright (c) 2008 Michael Niedermayer - * Copyright (c) 2009 Robert Swain ( rob opendot cl ) - * - * 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 "libavutil/intreadwrite.h" -#include "avformat.h" -#include "internal.h" -#include "rawdec.h" -#include "id3v1.h" - - -static int adts_aac_probe(AVProbeData *p) -{ - int max_frames = 0, first_frames = 0; - int fsize, frames; - const uint8_t *buf0 = p->buf; - const uint8_t *buf2; - const uint8_t *buf; - const uint8_t *end = buf0 + p->buf_size - 7; - - buf = buf0; - - for(; buf < end; buf= buf2+1) { - buf2 = buf; - - for(frames = 0; buf2 < end; frames++) { - uint32_t header = AV_RB16(buf2); - if((header&0xFFF6) != 0xFFF0) - break; - fsize = (AV_RB32(buf2 + 3) >> 13) & 0x1FFF; - if(fsize < 7) - break; - fsize = FFMIN(fsize, end - buf2); - buf2 += fsize; - } - max_frames = FFMAX(max_frames, frames); - if(buf == buf0) - first_frames= frames; - } - if (first_frames>=3) return AVPROBE_SCORE_MAX/2+1; - else if(max_frames>500)return AVPROBE_SCORE_MAX/2; - else if(max_frames>=3) return AVPROBE_SCORE_MAX/4; - else if(max_frames>=1) return 1; - else return 0; -} - -static int adts_aac_read_header(AVFormatContext *s) -{ - AVStream *st; - - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = s->iformat->raw_codec_id; - st->need_parsing = AVSTREAM_PARSE_FULL_RAW; - - ff_id3v1_read(s); - - //LCM of all possible ADTS sample rates - avpriv_set_pts_info(st, 64, 1, 28224000); - - return 0; -} - -AVInputFormat ff_aac_demuxer = { - .name = "aac", - .long_name = NULL_IF_CONFIG_SMALL("raw ADTS AAC (Advanced Audio Coding)"), - .read_probe = adts_aac_probe, - .read_header = adts_aac_read_header, - .read_packet = ff_raw_read_partial_packet, - .flags = AVFMT_GENERIC_INDEX, - .extensions = "aac", - .raw_codec_id = AV_CODEC_ID_AAC, -}; diff --git a/ffmpeg1/libavformat/ac3dec.c b/ffmpeg1/libavformat/ac3dec.c deleted file mode 100644 index c531f8a..0000000 --- a/ffmpeg1/libavformat/ac3dec.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * RAW AC-3 and E-AC-3 demuxer - * Copyright (c) 2007 Justin Ruggles - * - * 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 "libavutil/crc.h" -#include "libavcodec/ac3_parser.h" -#include "avformat.h" -#include "rawdec.h" - -static int ac3_eac3_probe(AVProbeData *p, enum AVCodecID expected_codec_id) -{ - int max_frames, first_frames = 0, frames; - const uint8_t *buf, *buf2, *end; - AC3HeaderInfo hdr; - GetBitContext gbc; - enum AVCodecID codec_id = AV_CODEC_ID_AC3; - - max_frames = 0; - buf = p->buf; - end = buf + p->buf_size; - - for(; buf < end; buf++) { - if(buf > p->buf && !(buf[0] == 0x0B && buf[1] == 0x77) - && !(buf[0] == 0x77 && buf[1] == 0x0B) ) - continue; - buf2 = buf; - - for(frames = 0; buf2 < end; frames++) { - uint8_t buf3[4096]; - int i; - if(!memcmp(buf2, "\x1\x10\0\0\0\0\0\0", 8)) - buf2+=16; - if (buf[0] == 0x77 && buf[1] == 0x0B) { - for(i=0; i<8; i+=2) { - buf3[i ] = buf[i+1]; - buf3[i+1] = buf[i ]; - } - init_get_bits(&gbc, buf3, 54); - }else - init_get_bits(&gbc, buf2, 54); - if(avpriv_ac3_parse_header(&gbc, &hdr) < 0) - break; - if(buf2 + hdr.frame_size > end) - break; - if (buf[0] == 0x77 && buf[1] == 0x0B) { - av_assert0(hdr.frame_size <= sizeof(buf3)); - for(i=8; i 10) - codec_id = AV_CODEC_ID_EAC3; - buf2 += hdr.frame_size; - } - max_frames = FFMAX(max_frames, frames); - if(buf == p->buf) - first_frames = frames; - } - if(codec_id != expected_codec_id) return 0; - // keep this in sync with mp3 probe, both need to avoid - // issues with MPEG-files! - if (first_frames>=4) return AVPROBE_SCORE_MAX/2+1; - else if(max_frames>200)return AVPROBE_SCORE_MAX/2; - else if(max_frames>=4) return AVPROBE_SCORE_MAX/4; - else if(max_frames>=1) return 1; - else return 0; -} - -#if CONFIG_AC3_DEMUXER -static int ac3_probe(AVProbeData *p) -{ - return ac3_eac3_probe(p, AV_CODEC_ID_AC3); -} - -AVInputFormat ff_ac3_demuxer = { - .name = "ac3", - .long_name = NULL_IF_CONFIG_SMALL("raw AC-3"), - .read_probe = ac3_probe, - .read_header = ff_raw_audio_read_header, - .read_packet = ff_raw_read_partial_packet, - .flags= AVFMT_GENERIC_INDEX, - .extensions = "ac3", - .raw_codec_id = AV_CODEC_ID_AC3, -}; -#endif - -#if CONFIG_EAC3_DEMUXER -static int eac3_probe(AVProbeData *p) -{ - return ac3_eac3_probe(p, AV_CODEC_ID_EAC3); -} - -AVInputFormat ff_eac3_demuxer = { - .name = "eac3", - .long_name = NULL_IF_CONFIG_SMALL("raw E-AC-3"), - .read_probe = eac3_probe, - .read_header = ff_raw_audio_read_header, - .read_packet = ff_raw_read_partial_packet, - .flags = AVFMT_GENERIC_INDEX, - .extensions = "eac3", - .raw_codec_id = AV_CODEC_ID_EAC3, -}; -#endif diff --git a/ffmpeg1/libavformat/act.c b/ffmpeg1/libavformat/act.c deleted file mode 100644 index 78f1d3b..0000000 --- a/ffmpeg1/libavformat/act.c +++ /dev/null @@ -1,207 +0,0 @@ -/* - * ACT file format demuxer - * Copyright (c) 2007-2008 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" -#include "internal.h" -#include "libavcodec/get_bits.h" - -#define CHUNK_SIZE 512 -#define RIFF_TAG MKTAG('R','I','F','F') -#define WAVE_TAG MKTAG('W','A','V','E') - -typedef struct{ - int bytes_left_in_chunk; - uint8_t audio_buffer[22];///< temporary buffer for ACT frame - char second_packet; ///< 1 - if temporary buffer contains valid (second) G.729 packet -} ACTContext; - -static int probe(AVProbeData *p) -{ - int i; - - if ((AV_RL32(&p->buf[0]) != RIFF_TAG) || - (AV_RL32(&p->buf[8]) != WAVE_TAG) || - (AV_RL32(&p->buf[16]) != 16)) - return 0; - - //We cant be sure that this is ACT and not regular WAV - if (p->buf_size<512) - return 0; - - for(i=44; i<256; i++) - if(p->buf[i]) - return 0; - - if(p->buf[256]!=0x84) - return 0; - - for(i=264; i<512; i++) - if(p->buf[i]) - return 0; - - return AVPROBE_SCORE_MAX; -} - -static int read_header(AVFormatContext *s) -{ - ACTContext* ctx = s->priv_data; - AVIOContext *pb = s->pb; - int size; - AVStream* st; - - int min,sec,msec; - - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - - avio_skip(pb, 16); - size=avio_rl32(pb); - ff_get_wav_header(pb, st->codec, size); - - /* - 8000Hz (Fine-rec) file format has 10 bytes long - packets with 10ms of sound data in them - */ - if (st->codec->sample_rate != 8000) { - av_log(s, AV_LOG_ERROR, "Sample rate %d is not supported.\n", st->codec->sample_rate); - return AVERROR_INVALIDDATA; - } - - st->codec->frame_size=80; - st->codec->channels=1; - avpriv_set_pts_info(st, 64, 1, 100); - - st->codec->codec_id=AV_CODEC_ID_G729; - - avio_seek(pb, 257, SEEK_SET); - msec=avio_rl16(pb); - sec=avio_r8(pb); - min=avio_rl32(pb); - - st->duration = av_rescale(1000*(min*60+sec)+msec, st->codec->sample_rate, 1000 * st->codec->frame_size); - - ctx->bytes_left_in_chunk=CHUNK_SIZE; - - avio_seek(pb, 512, SEEK_SET); - - return 0; -} - - -static int read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - ACTContext *ctx = s->priv_data; - AVIOContext *pb = s->pb; - int ret; - int frame_size=s->streams[0]->codec->sample_rate==8000?10:22; - - - if(s->streams[0]->codec->sample_rate==8000) - ret=av_new_packet(pkt, 10); - else - ret=av_new_packet(pkt, 11); - - if(ret) - return ret; - - if(s->streams[0]->codec->sample_rate==4400 && !ctx->second_packet) - { - ret = avio_read(pb, ctx->audio_buffer, frame_size); - - if(ret<0) - return ret; - if(ret!=frame_size) - return AVERROR(EIO); - - pkt->data[0]=ctx->audio_buffer[11]; - pkt->data[1]=ctx->audio_buffer[0]; - pkt->data[2]=ctx->audio_buffer[12]; - pkt->data[3]=ctx->audio_buffer[1]; - pkt->data[4]=ctx->audio_buffer[13]; - pkt->data[5]=ctx->audio_buffer[2]; - pkt->data[6]=ctx->audio_buffer[14]; - pkt->data[7]=ctx->audio_buffer[3]; - pkt->data[8]=ctx->audio_buffer[15]; - pkt->data[9]=ctx->audio_buffer[4]; - pkt->data[10]=ctx->audio_buffer[16]; - - ctx->second_packet=1; - } - else if(s->streams[0]->codec->sample_rate==4400 && ctx->second_packet) - { - pkt->data[0]=ctx->audio_buffer[5]; - pkt->data[1]=ctx->audio_buffer[17]; - pkt->data[2]=ctx->audio_buffer[6]; - pkt->data[3]=ctx->audio_buffer[18]; - pkt->data[4]=ctx->audio_buffer[7]; - pkt->data[5]=ctx->audio_buffer[19]; - pkt->data[6]=ctx->audio_buffer[8]; - pkt->data[7]=ctx->audio_buffer[20]; - pkt->data[8]=ctx->audio_buffer[9]; - pkt->data[9]=ctx->audio_buffer[21]; - pkt->data[10]=ctx->audio_buffer[10]; - - ctx->second_packet=0; - } - else // 8000 Hz - { - ret = avio_read(pb, ctx->audio_buffer, frame_size); - - if(ret<0) - return ret; - if(ret!=frame_size) - return AVERROR(EIO); - - pkt->data[0]=ctx->audio_buffer[5]; - pkt->data[1]=ctx->audio_buffer[0]; - pkt->data[2]=ctx->audio_buffer[6]; - pkt->data[3]=ctx->audio_buffer[1]; - pkt->data[4]=ctx->audio_buffer[7]; - pkt->data[5]=ctx->audio_buffer[2]; - pkt->data[6]=ctx->audio_buffer[8]; - pkt->data[7]=ctx->audio_buffer[3]; - pkt->data[8]=ctx->audio_buffer[9]; - pkt->data[9]=ctx->audio_buffer[4]; - } - - ctx->bytes_left_in_chunk -= frame_size; - - if(ctx->bytes_left_in_chunk < frame_size) - { - avio_skip(pb, ctx->bytes_left_in_chunk); - ctx->bytes_left_in_chunk=CHUNK_SIZE; - } - - pkt->duration=1; - - return ret; -} - -AVInputFormat ff_act_demuxer = { - .name = "act", - .long_name = "ACT Voice file format", - .priv_data_size = sizeof(ACTContext), - .read_probe = probe, - .read_header = read_header, - .read_packet = read_packet, -}; diff --git a/ffmpeg1/libavformat/adtsenc.c b/ffmpeg1/libavformat/adtsenc.c deleted file mode 100644 index 14c72a8..0000000 --- a/ffmpeg1/libavformat/adtsenc.c +++ /dev/null @@ -1,176 +0,0 @@ -/* - * ADTS muxer. - * Copyright (c) 2006 Baptiste Coudurier - * Mans Rullgard - * - * 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 "libavcodec/get_bits.h" -#include "libavcodec/put_bits.h" -#include "libavcodec/avcodec.h" -#include "libavcodec/mpeg4audio.h" -#include "avformat.h" - -#define ADTS_HEADER_SIZE 7 - -typedef struct { - int write_adts; - int objecttype; - int sample_rate_index; - int channel_conf; - int pce_size; - uint8_t pce_data[MAX_PCE_SIZE]; -} ADTSContext; - -#define ADTS_MAX_FRAME_BYTES ((1 << 13) - 1) - -static int adts_decode_extradata(AVFormatContext *s, ADTSContext *adts, uint8_t *buf, int size) -{ - GetBitContext gb; - PutBitContext pb; - MPEG4AudioConfig m4ac; - int off; - - init_get_bits(&gb, buf, size * 8); - off = avpriv_mpeg4audio_get_config(&m4ac, buf, size * 8, 1); - if (off < 0) - return off; - skip_bits_long(&gb, off); - adts->objecttype = m4ac.object_type - 1; - adts->sample_rate_index = m4ac.sampling_index; - adts->channel_conf = m4ac.chan_config; - - if (adts->objecttype > 3U) { - av_log(s, AV_LOG_ERROR, "MPEG-4 AOT %d is not allowed in ADTS\n", adts->objecttype+1); - return -1; - } - if (adts->sample_rate_index == 15) { - av_log(s, AV_LOG_ERROR, "Escape sample rate index illegal in ADTS\n"); - return -1; - } - if (get_bits(&gb, 1)) { - av_log(s, AV_LOG_ERROR, "960/120 MDCT window is not allowed in ADTS\n"); - return -1; - } - if (get_bits(&gb, 1)) { - av_log(s, AV_LOG_ERROR, "Scalable configurations are not allowed in ADTS\n"); - return -1; - } - if (get_bits(&gb, 1)) { - av_log(s, AV_LOG_ERROR, "Extension flag is not allowed in ADTS\n"); - return -1; - } - if (!adts->channel_conf) { - init_put_bits(&pb, adts->pce_data, MAX_PCE_SIZE); - - put_bits(&pb, 3, 5); //ID_PCE - adts->pce_size = (avpriv_copy_pce_data(&pb, &gb) + 3) / 8; - flush_put_bits(&pb); - } - - adts->write_adts = 1; - - return 0; -} - -static int adts_write_header(AVFormatContext *s) -{ - ADTSContext *adts = s->priv_data; - AVCodecContext *avc = s->streams[0]->codec; - - if (avc->extradata_size > 0 && - adts_decode_extradata(s, adts, avc->extradata, avc->extradata_size) < 0) - return -1; - - return 0; -} - -static int adts_write_frame_header(ADTSContext *ctx, - uint8_t *buf, int size, int pce_size) -{ - PutBitContext pb; - - unsigned full_frame_size = (unsigned)ADTS_HEADER_SIZE + size + pce_size; - if (full_frame_size > ADTS_MAX_FRAME_BYTES) { - av_log(NULL, AV_LOG_ERROR, "ADTS frame size too large: %u (max %d)\n", - full_frame_size, ADTS_MAX_FRAME_BYTES); - return AVERROR_INVALIDDATA; - } - - init_put_bits(&pb, buf, ADTS_HEADER_SIZE); - - /* adts_fixed_header */ - put_bits(&pb, 12, 0xfff); /* syncword */ - put_bits(&pb, 1, 0); /* ID */ - put_bits(&pb, 2, 0); /* layer */ - put_bits(&pb, 1, 1); /* protection_absent */ - put_bits(&pb, 2, ctx->objecttype); /* profile_objecttype */ - put_bits(&pb, 4, ctx->sample_rate_index); - put_bits(&pb, 1, 0); /* private_bit */ - put_bits(&pb, 3, ctx->channel_conf); /* channel_configuration */ - put_bits(&pb, 1, 0); /* original_copy */ - put_bits(&pb, 1, 0); /* home */ - - /* adts_variable_header */ - put_bits(&pb, 1, 0); /* copyright_identification_bit */ - put_bits(&pb, 1, 0); /* copyright_identification_start */ - put_bits(&pb, 13, full_frame_size); /* aac_frame_length */ - put_bits(&pb, 11, 0x7ff); /* adts_buffer_fullness */ - put_bits(&pb, 2, 0); /* number_of_raw_data_blocks_in_frame */ - - flush_put_bits(&pb); - - return 0; -} - -static int adts_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - ADTSContext *adts = s->priv_data; - AVIOContext *pb = s->pb; - uint8_t buf[ADTS_HEADER_SIZE]; - - if (!pkt->size) - return 0; - if (adts->write_adts) { - int err = adts_write_frame_header(adts, buf, pkt->size, - adts->pce_size); - if (err < 0) - return err; - avio_write(pb, buf, ADTS_HEADER_SIZE); - if (adts->pce_size) { - avio_write(pb, adts->pce_data, adts->pce_size); - adts->pce_size = 0; - } - } - avio_write(pb, pkt->data, pkt->size); - avio_flush(pb); - - return 0; -} - -AVOutputFormat ff_adts_muxer = { - .name = "adts", - .long_name = NULL_IF_CONFIG_SMALL("ADTS AAC (Advanced Audio Coding)"), - .mime_type = "audio/aac", - .extensions = "aac,adts", - .priv_data_size = sizeof(ADTSContext), - .audio_codec = AV_CODEC_ID_AAC, - .video_codec = AV_CODEC_ID_NONE, - .write_header = adts_write_header, - .write_packet = adts_write_packet, -}; diff --git a/ffmpeg1/libavformat/adxdec.c b/ffmpeg1/libavformat/adxdec.c deleted file mode 100644 index 49e1930..0000000 --- a/ffmpeg1/libavformat/adxdec.c +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (c) 2011 Justin Ruggles - * - * 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 - */ - -/** - * @file - * CRI ADX demuxer - */ - -#include "libavutil/intreadwrite.h" -#include "libavcodec/adx.h" -#include "avformat.h" -#include "internal.h" - -#define BLOCK_SIZE 18 -#define BLOCK_SAMPLES 32 - -typedef struct ADXDemuxerContext { - int header_size; -} ADXDemuxerContext; - -static int adx_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - ADXDemuxerContext *c = s->priv_data; - AVCodecContext *avctx = s->streams[0]->codec; - int ret, size; - - size = BLOCK_SIZE * avctx->channels; - - pkt->pos = avio_tell(s->pb); - pkt->stream_index = 0; - - ret = av_get_packet(s->pb, pkt, size); - if (ret != size) { - av_free_packet(pkt); - return ret < 0 ? ret : AVERROR(EIO); - } - if (AV_RB16(pkt->data) & 0x8000) { - av_free_packet(pkt); - return AVERROR_EOF; - } - pkt->size = size; - pkt->duration = 1; - pkt->pts = (pkt->pos - c->header_size) / size; - - return 0; -} - -static int adx_read_header(AVFormatContext *s) -{ - ADXDemuxerContext *c = s->priv_data; - AVCodecContext *avctx; - int ret; - - AVStream *st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - avctx = s->streams[0]->codec; - - if (avio_rb16(s->pb) != 0x8000) - return AVERROR_INVALIDDATA; - c->header_size = avio_rb16(s->pb) + 4; - avio_seek(s->pb, -4, SEEK_CUR); - - avctx->extradata = av_mallocz(c->header_size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!avctx->extradata) - return AVERROR(ENOMEM); - if (avio_read(s->pb, avctx->extradata, c->header_size) < c->header_size) { - av_freep(&avctx->extradata); - return AVERROR(EIO); - } - avctx->extradata_size = c->header_size; - - ret = avpriv_adx_decode_header(avctx, avctx->extradata, - avctx->extradata_size, &c->header_size, - NULL); - if (ret) - return ret; - - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = s->iformat->raw_codec_id; - - avpriv_set_pts_info(st, 64, BLOCK_SAMPLES, avctx->sample_rate); - - return 0; -} - -AVInputFormat ff_adx_demuxer = { - .name = "adx", - .long_name = NULL_IF_CONFIG_SMALL("CRI ADX"), - .priv_data_size = sizeof(ADXDemuxerContext), - .read_header = adx_read_header, - .read_packet = adx_read_packet, - .extensions = "adx", - .raw_codec_id = AV_CODEC_ID_ADPCM_ADX, - .flags = AVFMT_GENERIC_INDEX, -}; diff --git a/ffmpeg1/libavformat/aea.c b/ffmpeg1/libavformat/aea.c deleted file mode 100644 index 15b9b1c..0000000 --- a/ffmpeg1/libavformat/aea.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - * MD STUDIO audio demuxer - * - * Copyright (c) 2009 Benjamin Larsson - * - * 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 "libavutil/channel_layout.h" -#include "libavutil/intreadwrite.h" -#include "avformat.h" -#include "pcm.h" - -#define AT1_SU_SIZE 212 - -static int aea_read_probe(AVProbeData *p) -{ - if (p->buf_size <= 2048+212) - return 0; - - /* Magic is '00 08 00 00' in Little Endian*/ - if (AV_RL32(p->buf)==0x800) { - int bsm_s, bsm_e, inb_s, inb_e, ch; - ch = p->buf[264]; - bsm_s = p->buf[2048]; - inb_s = p->buf[2048+1]; - inb_e = p->buf[2048+210]; - bsm_e = p->buf[2048+211]; - - if (ch != 1 && ch != 2) - return 0; - - /* Check so that the redundant bsm bytes and info bytes are valid - * the block size mode bytes have to be the same - * the info bytes have to be the same - */ - if (bsm_s == bsm_e && inb_s == inb_e) - return AVPROBE_SCORE_MAX / 4 + 1; - } - return 0; -} - -static int aea_read_header(AVFormatContext *s) -{ - AVStream *st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - - /* Parse the amount of channels and skip to pos 2048(0x800) */ - avio_skip(s->pb, 264); - st->codec->channels = avio_r8(s->pb); - avio_skip(s->pb, 1783); - - - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = AV_CODEC_ID_ATRAC1; - st->codec->sample_rate = 44100; - st->codec->bit_rate = 292000; - - if (st->codec->channels != 1 && st->codec->channels != 2) { - av_log(s,AV_LOG_ERROR,"Channels %d not supported!\n",st->codec->channels); - return -1; - } - - st->codec->channel_layout = (st->codec->channels == 1) ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO; - - st->codec->block_align = AT1_SU_SIZE * st->codec->channels; - return 0; -} - -static int aea_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - int ret = av_get_packet(s->pb, pkt, s->streams[0]->codec->block_align); - - pkt->stream_index = 0; - if (ret <= 0) - return AVERROR(EIO); - - return ret; -} - -AVInputFormat ff_aea_demuxer = { - .name = "aea", - .long_name = NULL_IF_CONFIG_SMALL("MD STUDIO audio"), - .read_probe = aea_read_probe, - .read_header = aea_read_header, - .read_packet = aea_read_packet, - .read_seek = ff_pcm_read_seek, - .flags = AVFMT_GENERIC_INDEX, - .extensions = "aea", -}; diff --git a/ffmpeg1/libavformat/afc.c b/ffmpeg1/libavformat/afc.c deleted file mode 100644 index 183a8e0..0000000 --- a/ffmpeg1/libavformat/afc.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * AFC demuxer - * Copyright (c) 2012 Paul B Mahol - * - * 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 "libavutil/channel_layout.h" -#include "avformat.h" -#include "internal.h" - -typedef struct AFCDemuxContext { - int64_t data_end; -} AFCDemuxContext; - -static int afc_read_header(AVFormatContext *s) -{ - AFCDemuxContext *c = s->priv_data; - AVStream *st; - - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = AV_CODEC_ID_ADPCM_AFC; - st->codec->channels = 2; - st->codec->channel_layout = AV_CH_LAYOUT_STEREO; - st->codec->extradata_size = 1; - - st->codec->extradata = av_mallocz(1 + FF_INPUT_BUFFER_PADDING_SIZE); - if (!st->codec->extradata) - return AVERROR(ENOMEM); - st->codec->extradata[0] = 8 * st->codec->channels; - - c->data_end = avio_rb32(s->pb) + 32LL; - st->duration = avio_rb32(s->pb); - st->codec->sample_rate = avio_rb16(s->pb); - avio_skip(s->pb, 22); - avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); - - return 0; -} - -static int afc_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - AFCDemuxContext *c = s->priv_data; - int64_t size; - int ret; - - size = FFMIN(c->data_end - avio_tell(s->pb), 18 * 128); - if (size <= 0) - return AVERROR_EOF; - - ret = av_get_packet(s->pb, pkt, size); - pkt->stream_index = 0; - return ret; -} - -AVInputFormat ff_afc_demuxer = { - .name = "afc", - .long_name = NULL_IF_CONFIG_SMALL("AFC"), - .priv_data_size = sizeof(AFCDemuxContext), - .read_header = afc_read_header, - .read_packet = afc_read_packet, - .extensions = "afc", - .flags = AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK, -}; diff --git a/ffmpeg1/libavformat/aiff.h b/ffmpeg1/libavformat/aiff.h deleted file mode 100644 index b3ef577..0000000 --- a/ffmpeg1/libavformat/aiff.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * AIFF/AIFF-C muxer/demuxer common header - * Copyright (c) 2006 Patrick Guimond - * - * 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 - */ - -/** - * @file - * common header for AIFF muxer and demuxer - */ - -#ifndef AVFORMAT_AIFF_H -#define AVFORMAT_AIFF_H - -#include "avformat.h" -#include "internal.h" - -static const AVCodecTag ff_codec_aiff_tags[] = { - { AV_CODEC_ID_PCM_S16BE, MKTAG('N','O','N','E') }, - { AV_CODEC_ID_PCM_S8, MKTAG('N','O','N','E') }, - { AV_CODEC_ID_PCM_U8, MKTAG('r','a','w',' ') }, - { AV_CODEC_ID_PCM_S24BE, MKTAG('N','O','N','E') }, - { AV_CODEC_ID_PCM_S32BE, MKTAG('N','O','N','E') }, - { AV_CODEC_ID_PCM_F32BE, MKTAG('f','l','3','2') }, - { AV_CODEC_ID_PCM_F64BE, MKTAG('f','l','6','4') }, - { AV_CODEC_ID_PCM_ALAW, MKTAG('a','l','a','w') }, - { AV_CODEC_ID_PCM_MULAW, MKTAG('u','l','a','w') }, - { AV_CODEC_ID_PCM_S24BE, MKTAG('i','n','2','4') }, - { AV_CODEC_ID_PCM_S32BE, MKTAG('i','n','3','2') }, - { AV_CODEC_ID_MACE3, MKTAG('M','A','C','3') }, - { AV_CODEC_ID_MACE6, MKTAG('M','A','C','6') }, - { AV_CODEC_ID_GSM, MKTAG('G','S','M',' ') }, - { AV_CODEC_ID_ADPCM_G726, MKTAG('G','7','2','6') }, - { AV_CODEC_ID_PCM_S16BE, MKTAG('t','w','o','s') }, - { AV_CODEC_ID_PCM_S16LE, MKTAG('s','o','w','t') }, - { AV_CODEC_ID_ADPCM_IMA_QT, MKTAG('i','m','a','4') }, - { AV_CODEC_ID_QDM2, MKTAG('Q','D','M','2') }, - { AV_CODEC_ID_QCELP, MKTAG('Q','c','l','p') }, - { AV_CODEC_ID_NONE, 0 }, -}; - -#endif /* AVFORMAT_AIFF_H */ diff --git a/ffmpeg1/libavformat/aiffdec.c b/ffmpeg1/libavformat/aiffdec.c deleted file mode 100644 index 8d466fa..0000000 --- a/ffmpeg1/libavformat/aiffdec.c +++ /dev/null @@ -1,358 +0,0 @@ -/* - * AIFF/AIFF-C demuxer - * Copyright (c) 2006 Patrick Guimond - * - * 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 "libavutil/intreadwrite.h" -#include "libavutil/mathematics.h" -#include "libavutil/dict.h" -#include "avformat.h" -#include "internal.h" -#include "pcm.h" -#include "aiff.h" -#include "isom.h" -#include "id3v2.h" -#include "mov_chan.h" - -#define AIFF 0 -#define AIFF_C_VERSION1 0xA2805140 - -typedef struct { - int64_t data_end; - int block_duration; -} AIFFInputContext; - -static enum AVCodecID aiff_codec_get_id(int bps) -{ - if (bps <= 8) - return AV_CODEC_ID_PCM_S8; - if (bps <= 16) - return AV_CODEC_ID_PCM_S16BE; - if (bps <= 24) - return AV_CODEC_ID_PCM_S24BE; - if (bps <= 32) - return AV_CODEC_ID_PCM_S32BE; - - /* bigger than 32 isn't allowed */ - return AV_CODEC_ID_NONE; -} - -/* returns the size of the found tag */ -static int get_tag(AVIOContext *pb, uint32_t * tag) -{ - int size; - - if (url_feof(pb)) - return AVERROR(EIO); - - *tag = avio_rl32(pb); - size = avio_rb32(pb); - - if (size < 0) - size = 0x7fffffff; - - return size; -} - -/* Metadata string read */ -static void get_meta(AVFormatContext *s, const char *key, int size) -{ - uint8_t *str = av_malloc(size+1); - - if (str) { - int res = avio_read(s->pb, str, size); - if (res < 0){ - av_free(str); - return; - } - size += (size&1)-res; - str[res] = 0; - av_dict_set(&s->metadata, key, str, AV_DICT_DONT_STRDUP_VAL); - }else - size+= size&1; - - avio_skip(s->pb, size); -} - -/* Returns the number of sound data frames or negative on error */ -static unsigned int get_aiff_header(AVFormatContext *s, int size, - unsigned version) -{ - AVIOContext *pb = s->pb; - AVCodecContext *codec = s->streams[0]->codec; - AIFFInputContext *aiff = s->priv_data; - int exp; - uint64_t val; - double sample_rate; - unsigned int num_frames; - - if (size & 1) - size++; - codec->codec_type = AVMEDIA_TYPE_AUDIO; - codec->channels = avio_rb16(pb); - num_frames = avio_rb32(pb); - codec->bits_per_coded_sample = avio_rb16(pb); - - exp = avio_rb16(pb); - val = avio_rb64(pb); - sample_rate = ldexp(val, exp - 16383 - 63); - codec->sample_rate = sample_rate; - size -= 18; - - /* get codec id for AIFF-C */ - if (version == AIFF_C_VERSION1) { - codec->codec_tag = avio_rl32(pb); - codec->codec_id = ff_codec_get_id(ff_codec_aiff_tags, codec->codec_tag); - size -= 4; - } - - if (version != AIFF_C_VERSION1 || codec->codec_id == AV_CODEC_ID_PCM_S16BE) { - codec->codec_id = aiff_codec_get_id(codec->bits_per_coded_sample); - codec->bits_per_coded_sample = av_get_bits_per_sample(codec->codec_id); - aiff->block_duration = 1; - } else { - switch (codec->codec_id) { - case AV_CODEC_ID_PCM_F32BE: - case AV_CODEC_ID_PCM_F64BE: - case AV_CODEC_ID_PCM_S16LE: - case AV_CODEC_ID_PCM_ALAW: - case AV_CODEC_ID_PCM_MULAW: - aiff->block_duration = 1; - break; - case AV_CODEC_ID_ADPCM_IMA_QT: - codec->block_align = 34*codec->channels; - break; - case AV_CODEC_ID_MACE3: - codec->block_align = 2*codec->channels; - break; - case AV_CODEC_ID_MACE6: - codec->block_align = 1*codec->channels; - break; - case AV_CODEC_ID_GSM: - codec->block_align = 33; - break; - case AV_CODEC_ID_QCELP: - codec->block_align = 35; - break; - default: - aiff->block_duration = 1; - break; - } - if (codec->block_align > 0) - aiff->block_duration = av_get_audio_frame_duration(codec, - codec->block_align); - } - - /* Block align needs to be computed in all cases, as the definition - * is specific to applications -> here we use the WAVE format definition */ - if (!codec->block_align) - codec->block_align = (av_get_bits_per_sample(codec->codec_id) * codec->channels) >> 3; - - if (aiff->block_duration) { - codec->bit_rate = codec->sample_rate * (codec->block_align << 3) / - aiff->block_duration; - } - - /* Chunk is over */ - if (size) - avio_skip(pb, size); - - return num_frames; -} - -static int aiff_probe(AVProbeData *p) -{ - /* check file header */ - if (p->buf[0] == 'F' && p->buf[1] == 'O' && - p->buf[2] == 'R' && p->buf[3] == 'M' && - p->buf[8] == 'A' && p->buf[9] == 'I' && - p->buf[10] == 'F' && (p->buf[11] == 'F' || p->buf[11] == 'C')) - return AVPROBE_SCORE_MAX; - else - return 0; -} - -/* aiff input */ -static int aiff_read_header(AVFormatContext *s) -{ - int ret, size, filesize; - int64_t offset = 0; - uint32_t tag; - unsigned version = AIFF_C_VERSION1; - AVIOContext *pb = s->pb; - AVStream * st; - AIFFInputContext *aiff = s->priv_data; - ID3v2ExtraMeta *id3v2_extra_meta = NULL; - - /* check FORM header */ - filesize = get_tag(pb, &tag); - if (filesize < 0 || tag != MKTAG('F', 'O', 'R', 'M')) - return AVERROR_INVALIDDATA; - - /* AIFF data type */ - tag = avio_rl32(pb); - if (tag == MKTAG('A', 'I', 'F', 'F')) /* Got an AIFF file */ - version = AIFF; - else if (tag != MKTAG('A', 'I', 'F', 'C')) /* An AIFF-C file then */ - return AVERROR_INVALIDDATA; - - filesize -= 4; - - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - - while (filesize > 0) { - /* parse different chunks */ - size = get_tag(pb, &tag); - if (size < 0) - return size; - - filesize -= size + 8; - - switch (tag) { - case MKTAG('C', 'O', 'M', 'M'): /* Common chunk */ - /* Then for the complete header info */ - st->nb_frames = get_aiff_header(s, size, version); - if (st->nb_frames < 0) - return st->nb_frames; - if (offset > 0) // COMM is after SSND - goto got_sound; - break; - case MKTAG('I', 'D', '3', ' '): - ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta); - if (id3v2_extra_meta) - if ((ret = ff_id3v2_parse_apic(s, &id3v2_extra_meta)) < 0) { - ff_id3v2_free_extra_meta(&id3v2_extra_meta); - return ret; - } - ff_id3v2_free_extra_meta(&id3v2_extra_meta); - break; - case MKTAG('F', 'V', 'E', 'R'): /* Version chunk */ - version = avio_rb32(pb); - break; - case MKTAG('N', 'A', 'M', 'E'): /* Sample name chunk */ - get_meta(s, "title" , size); - break; - case MKTAG('A', 'U', 'T', 'H'): /* Author chunk */ - get_meta(s, "author" , size); - break; - case MKTAG('(', 'c', ')', ' '): /* Copyright chunk */ - get_meta(s, "copyright", size); - break; - case MKTAG('A', 'N', 'N', 'O'): /* Annotation chunk */ - get_meta(s, "comment" , size); - break; - case MKTAG('S', 'S', 'N', 'D'): /* Sampled sound chunk */ - aiff->data_end = avio_tell(pb) + size; - offset = avio_rb32(pb); /* Offset of sound data */ - avio_rb32(pb); /* BlockSize... don't care */ - offset += avio_tell(pb); /* Compute absolute data offset */ - if (st->codec->block_align && !pb->seekable) /* Assume COMM already parsed */ - goto got_sound; - if (!pb->seekable) { - av_log(s, AV_LOG_ERROR, "file is not seekable\n"); - return -1; - } - avio_skip(pb, size - 8); - break; - case MKTAG('w', 'a', 'v', 'e'): - if ((uint64_t)size > (1<<30)) - return -1; - st->codec->extradata = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!st->codec->extradata) - return AVERROR(ENOMEM); - st->codec->extradata_size = size; - avio_read(pb, st->codec->extradata, size); - if (st->codec->codec_id == AV_CODEC_ID_QDM2 && size>=12*4 && !st->codec->block_align) { - st->codec->block_align = AV_RB32(st->codec->extradata+11*4); - aiff->block_duration = AV_RB32(st->codec->extradata+9*4); - } - break; - case MKTAG('C','H','A','N'): - if(ff_mov_read_chan(s, pb, st, size) < 0) - return AVERROR_INVALIDDATA; - break; - default: /* Jump */ - if (size & 1) /* Always even aligned */ - size++; - avio_skip(pb, size); - } - } - -got_sound: - if (!st->codec->block_align) { - av_log(s, AV_LOG_ERROR, "could not find COMM tag or invalid block_align value\n"); - return -1; - } - - /* Now positioned, get the sound data start and end */ - avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); - st->start_time = 0; - st->duration = st->nb_frames * aiff->block_duration; - - /* Position the stream at the first block */ - avio_seek(pb, offset, SEEK_SET); - - return 0; -} - -#define MAX_SIZE 4096 - -static int aiff_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - AVStream *st = s->streams[0]; - AIFFInputContext *aiff = s->priv_data; - int64_t max_size; - int res, size; - - /* calculate size of remaining data */ - max_size = aiff->data_end - avio_tell(s->pb); - if (max_size <= 0) - return AVERROR_EOF; - - /* Now for that packet */ - if (st->codec->block_align >= 33) // GSM, QCLP, IMA4 - size = st->codec->block_align; - else - size = (MAX_SIZE / st->codec->block_align) * st->codec->block_align; - size = FFMIN(max_size, size); - res = av_get_packet(s->pb, pkt, size); - if (res < 0) - return res; - - if (size >= st->codec->block_align) - pkt->flags &= ~AV_PKT_FLAG_CORRUPT; - /* Only one stream in an AIFF file */ - pkt->stream_index = 0; - pkt->duration = (res / st->codec->block_align) * aiff->block_duration; - return 0; -} - -AVInputFormat ff_aiff_demuxer = { - .name = "aiff", - .long_name = NULL_IF_CONFIG_SMALL("Audio IFF"), - .priv_data_size = sizeof(AIFFInputContext), - .read_probe = aiff_probe, - .read_header = aiff_read_header, - .read_packet = aiff_read_packet, - .read_seek = ff_pcm_read_seek, - .codec_tag = (const AVCodecTag* const []){ ff_codec_aiff_tags, 0 }, -}; diff --git a/ffmpeg1/libavformat/aiffenc.c b/ffmpeg1/libavformat/aiffenc.c deleted file mode 100644 index 7c0b4fb..0000000 --- a/ffmpeg1/libavformat/aiffenc.c +++ /dev/null @@ -1,332 +0,0 @@ -/* - * AIFF/AIFF-C muxer - * Copyright (c) 2006 Patrick Guimond - * - * 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 "libavutil/intfloat.h" -#include "libavutil/opt.h" -#include "avformat.h" -#include "internal.h" -#include "aiff.h" -#include "avio_internal.h" -#include "isom.h" -#include "id3v2.h" - -typedef struct { - const AVClass *class; - int64_t form; - int64_t frames; - int64_t ssnd; - int audio_stream_idx; - AVPacketList *pict_list; - int write_id3v2; - int id3v2_version; -} AIFFOutputContext; - -static int put_id3v2_tags(AVFormatContext *s, AIFFOutputContext *aiff) -{ - int ret; - uint64_t pos, end, size; - ID3v2EncContext id3v2 = { 0 }; - AVIOContext *pb = s->pb; - AVPacketList *pict_list = aiff->pict_list; - - if (!pb->seekable) - return 0; - - if (!s->metadata && !aiff->pict_list) - return 0; - - avio_wl32(pb, MKTAG('I', 'D', '3', ' ')); - avio_wb32(pb, 0); - pos = avio_tell(pb); - - ff_id3v2_start(&id3v2, pb, aiff->id3v2_version, ID3v2_DEFAULT_MAGIC); - ff_id3v2_write_metadata(s, &id3v2); - while (pict_list) { - if ((ret = ff_id3v2_write_apic(s, &id3v2, &pict_list->pkt)) < 0) - return ret; - pict_list = pict_list->next; - } - ff_id3v2_finish(&id3v2, pb); - - end = avio_tell(pb); - size = end - pos; - - /* Update chunk size */ - avio_seek(pb, pos - 4, SEEK_SET); - avio_wb32(pb, size); - avio_seek(pb, end, SEEK_SET); - - if (size & 1) - avio_w8(pb, 0); - - return 0; -} - -static void put_meta(AVFormatContext *s, const char *key, uint32_t id) -{ - AVDictionaryEntry *tag; - AVIOContext *pb = s->pb; - - if (tag = av_dict_get(s->metadata, key, NULL, 0)) { - int size = strlen(tag->value); - - avio_wl32(pb, id); - avio_wb32(pb, FFALIGN(size, 2)); - avio_write(pb, tag->value, size); - if (size & 1) - avio_w8(pb, 0); - } -} - -static int aiff_write_header(AVFormatContext *s) -{ - AIFFOutputContext *aiff = s->priv_data; - AVIOContext *pb = s->pb; - AVCodecContext *enc; - uint64_t sample_rate; - int i, aifc = 0; - - aiff->audio_stream_idx = -1; - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - if (aiff->audio_stream_idx < 0 && st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - aiff->audio_stream_idx = i; - } else if (st->codec->codec_type != AVMEDIA_TYPE_VIDEO) { - av_log(s, AV_LOG_ERROR, "Only audio streams and pictures are allowed in AIFF.\n"); - return AVERROR(EINVAL); - } - } - if (aiff->audio_stream_idx < 0) { - av_log(s, AV_LOG_ERROR, "No audio stream present.\n"); - return AVERROR(EINVAL); - } - - enc = s->streams[aiff->audio_stream_idx]->codec; - - /* First verify if format is ok */ - if (!enc->codec_tag) - return -1; - if (enc->codec_tag != MKTAG('N','O','N','E')) - aifc = 1; - - /* FORM AIFF header */ - ffio_wfourcc(pb, "FORM"); - aiff->form = avio_tell(pb); - avio_wb32(pb, 0); /* file length */ - ffio_wfourcc(pb, aifc ? "AIFC" : "AIFF"); - - if (aifc) { // compressed audio - if (!enc->block_align) { - av_log(s, AV_LOG_ERROR, "block align not set\n"); - return -1; - } - /* Version chunk */ - ffio_wfourcc(pb, "FVER"); - avio_wb32(pb, 4); - avio_wb32(pb, 0xA2805140); - } - - if (enc->channels > 2 && enc->channel_layout) { - ffio_wfourcc(pb, "CHAN"); - avio_wb32(pb, 12); - ff_mov_write_chan(pb, enc->channel_layout); - } - - put_meta(s, "title", MKTAG('N', 'A', 'M', 'E')); - put_meta(s, "author", MKTAG('A', 'U', 'T', 'H')); - put_meta(s, "copyright", MKTAG('(', 'c', ')', ' ')); - put_meta(s, "comment", MKTAG('A', 'N', 'N', 'O')); - - /* Common chunk */ - ffio_wfourcc(pb, "COMM"); - avio_wb32(pb, aifc ? 24 : 18); /* size */ - avio_wb16(pb, enc->channels); /* Number of channels */ - - aiff->frames = avio_tell(pb); - avio_wb32(pb, 0); /* Number of frames */ - - if (!enc->bits_per_coded_sample) - enc->bits_per_coded_sample = av_get_bits_per_sample(enc->codec_id); - if (!enc->bits_per_coded_sample) { - av_log(s, AV_LOG_ERROR, "could not compute bits per sample\n"); - return -1; - } - if (!enc->block_align) - enc->block_align = (enc->bits_per_coded_sample * enc->channels) >> 3; - - avio_wb16(pb, enc->bits_per_coded_sample); /* Sample size */ - - sample_rate = av_double2int(enc->sample_rate); - avio_wb16(pb, (sample_rate >> 52) + (16383 - 1023)); - avio_wb64(pb, UINT64_C(1) << 63 | sample_rate << 11); - - if (aifc) { - avio_wl32(pb, enc->codec_tag); - avio_wb16(pb, 0); - } - - if (enc->codec_tag == MKTAG('Q','D','M','2') && enc->extradata_size) { - ffio_wfourcc(pb, "wave"); - avio_wb32(pb, enc->extradata_size); - avio_write(pb, enc->extradata, enc->extradata_size); - } - - /* Sound data chunk */ - ffio_wfourcc(pb, "SSND"); - aiff->ssnd = avio_tell(pb); /* Sound chunk size */ - avio_wb32(pb, 0); /* Sound samples data size */ - avio_wb32(pb, 0); /* Data offset */ - avio_wb32(pb, 0); /* Block-size (block align) */ - - avpriv_set_pts_info(s->streams[aiff->audio_stream_idx], 64, 1, - s->streams[aiff->audio_stream_idx]->codec->sample_rate); - - /* Data is starting here */ - avio_flush(pb); - - return 0; -} - -static int aiff_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - AIFFOutputContext *aiff = s->priv_data; - AVIOContext *pb = s->pb; - if (pkt->stream_index == aiff->audio_stream_idx) - avio_write(pb, pkt->data, pkt->size); - else { - int ret; - AVPacketList *pict_list, *last; - - if (s->streams[pkt->stream_index]->codec->codec_type != AVMEDIA_TYPE_VIDEO) - return 0; - - /* warn only once for each stream */ - if (s->streams[pkt->stream_index]->nb_frames == 1) { - av_log(s, AV_LOG_WARNING, "Got more than one picture in stream %d," - " ignoring.\n", pkt->stream_index); - } - if (s->streams[pkt->stream_index]->nb_frames >= 1) - return 0; - - pict_list = av_mallocz(sizeof(AVPacketList)); - if (!pict_list) - return AVERROR(ENOMEM); - - if ((ret = av_copy_packet(&pict_list->pkt, pkt)) < 0) { - av_freep(&pict_list); - return ret; - } - - if (!aiff->pict_list) - aiff->pict_list = pict_list; - else { - last = aiff->pict_list; - while (last->next) - last = last->next; - last->next = pict_list; - } - } - - return 0; -} - -static int aiff_write_trailer(AVFormatContext *s) -{ - int ret; - AVIOContext *pb = s->pb; - AIFFOutputContext *aiff = s->priv_data; - AVPacketList *pict_list = aiff->pict_list; - AVCodecContext *enc = s->streams[aiff->audio_stream_idx]->codec; - - /* Chunks sizes must be even */ - int64_t file_size, end_size; - end_size = file_size = avio_tell(pb); - if (file_size & 1) { - avio_w8(pb, 0); - end_size++; - } - - if (s->pb->seekable) { - /* Number of sample frames */ - avio_seek(pb, aiff->frames, SEEK_SET); - avio_wb32(pb, (file_size-aiff->ssnd-12)/enc->block_align); - - /* Sound Data chunk size */ - avio_seek(pb, aiff->ssnd, SEEK_SET); - avio_wb32(pb, file_size - aiff->ssnd - 4); - - /* return to the end */ - avio_seek(pb, end_size, SEEK_SET); - - /* Write ID3 tags */ - if (aiff->write_id3v2) - if ((ret = put_id3v2_tags(s, aiff)) < 0) - return ret; - - /* File length */ - file_size = avio_tell(pb); - avio_seek(pb, aiff->form, SEEK_SET); - avio_wb32(pb, file_size - aiff->form - 4); - - avio_flush(pb); - } - - while (pict_list) { - AVPacketList *next = pict_list->next; - av_free_packet(&pict_list->pkt); - av_freep(&pict_list); - pict_list = next; - } - - return 0; -} - -#define OFFSET(x) offsetof(AIFFOutputContext, x) -#define ENC AV_OPT_FLAG_ENCODING_PARAM -static const AVOption options[] = { - { "write_id3v2", "Enable ID3 tags writing.", - OFFSET(write_id3v2), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, ENC }, - { "id3v2_version", "Select ID3v2 version to write. Currently 3 and 4 are supported.", - OFFSET(id3v2_version), AV_OPT_TYPE_INT, {.i64 = 4}, 3, 4, ENC }, - { NULL }, -}; - -static const AVClass aiff_muxer_class = { - .class_name = "AIFF muxer", - .item_name = av_default_item_name, - .option = options, - .version = LIBAVUTIL_VERSION_INT, -}; - -AVOutputFormat ff_aiff_muxer = { - .name = "aiff", - .long_name = NULL_IF_CONFIG_SMALL("Audio IFF"), - .mime_type = "audio/aiff", - .extensions = "aif,aiff,afc,aifc", - .priv_data_size = sizeof(AIFFOutputContext), - .audio_codec = AV_CODEC_ID_PCM_S16BE, - .video_codec = AV_CODEC_ID_PNG, - .write_header = aiff_write_header, - .write_packet = aiff_write_packet, - .write_trailer = aiff_write_trailer, - .codec_tag = (const AVCodecTag* const []){ ff_codec_aiff_tags, 0 }, - .priv_class = &aiff_muxer_class, -}; diff --git a/ffmpeg1/libavformat/allformats.c b/ffmpeg1/libavformat/allformats.c deleted file mode 100644 index 8c746ff..0000000 --- a/ffmpeg1/libavformat/allformats.c +++ /dev/null @@ -1,341 +0,0 @@ -/* - * Register all the formats and protocols - * Copyright (c) 2000, 2001, 2002 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 "rtp.h" -#include "rdt.h" -#include "url.h" -#include "version.h" - -#define REGISTER_MUXER(X, x) \ - { \ - extern AVOutputFormat ff_##x##_muxer; \ - if (CONFIG_##X##_MUXER) \ - av_register_output_format(&ff_##x##_muxer); \ - } - -#define REGISTER_DEMUXER(X, x) \ - { \ - extern AVInputFormat ff_##x##_demuxer; \ - if (CONFIG_##X##_DEMUXER) \ - av_register_input_format(&ff_##x##_demuxer); \ - } - -#define REGISTER_MUXDEMUX(X, x) REGISTER_MUXER(X, x); REGISTER_DEMUXER(X, x) - -#define REGISTER_PROTOCOL(X, x) \ - { \ - extern URLProtocol ff_##x##_protocol; \ - if (CONFIG_##X##_PROTOCOL) \ - ffurl_register_protocol(&ff_##x##_protocol, \ - sizeof(ff_##x##_protocol)); \ - } - -void av_register_all(void) -{ - static int initialized; - - if (initialized) - return; - initialized = 1; - - avcodec_register_all(); - - /* (de)muxers */ - REGISTER_MUXER (A64, a64); - REGISTER_DEMUXER (AAC, aac); - REGISTER_MUXDEMUX(AC3, ac3); - REGISTER_DEMUXER (ACT, act); - REGISTER_DEMUXER (ADF, adf); - REGISTER_MUXER (ADTS, adts); - REGISTER_MUXDEMUX(ADX, adx); - REGISTER_DEMUXER (AEA, aea); - REGISTER_DEMUXER (AFC, afc); - REGISTER_MUXDEMUX(AIFF, aiff); - REGISTER_MUXDEMUX(AMR, amr); - REGISTER_DEMUXER (ANM, anm); - REGISTER_DEMUXER (APC, apc); - REGISTER_DEMUXER (APE, ape); - REGISTER_DEMUXER (AQTITLE, aqtitle); - REGISTER_MUXDEMUX(ASF, asf); - REGISTER_MUXDEMUX(ASS, ass); - REGISTER_MUXDEMUX(AST, ast); - REGISTER_MUXER (ASF_STREAM, asf_stream); - REGISTER_MUXDEMUX(AU, au); - REGISTER_MUXDEMUX(AVI, avi); - REGISTER_DEMUXER (AVISYNTH, avisynth); - REGISTER_MUXER (AVM2, avm2); - REGISTER_DEMUXER (AVR, avr); - REGISTER_DEMUXER (AVS, avs); - REGISTER_DEMUXER (BETHSOFTVID, bethsoftvid); - REGISTER_DEMUXER (BFI, bfi); - REGISTER_DEMUXER (BINTEXT, bintext); - REGISTER_DEMUXER (BINK, bink); - REGISTER_MUXDEMUX(BIT, bit); - REGISTER_DEMUXER (BMV, bmv); - REGISTER_DEMUXER (BRSTM, brstm); - REGISTER_DEMUXER (C93, c93); - REGISTER_MUXDEMUX(CAF, caf); - REGISTER_MUXDEMUX(CAVSVIDEO, cavsvideo); - REGISTER_DEMUXER (CDG, cdg); - REGISTER_DEMUXER (CDXL, cdxl); - REGISTER_DEMUXER (CONCAT, concat); - REGISTER_MUXER (CRC, crc); - REGISTER_MUXDEMUX(DAUD, daud); - REGISTER_DEMUXER (DFA, dfa); - REGISTER_MUXDEMUX(DIRAC, dirac); - REGISTER_MUXDEMUX(DNXHD, dnxhd); - REGISTER_DEMUXER (DSICIN, dsicin); - REGISTER_MUXDEMUX(DTS, dts); - REGISTER_DEMUXER (DTSHD, dtshd); - REGISTER_MUXDEMUX(DV, dv); - REGISTER_DEMUXER (DXA, dxa); - REGISTER_DEMUXER (EA, ea); - REGISTER_DEMUXER (EA_CDATA, ea_cdata); - REGISTER_MUXDEMUX(EAC3, eac3); - REGISTER_DEMUXER (EPAF, epaf); - REGISTER_MUXER (F4V, f4v); - REGISTER_MUXDEMUX(FFM, ffm); - REGISTER_MUXDEMUX(FFMETADATA, ffmetadata); - REGISTER_MUXDEMUX(FILMSTRIP, filmstrip); - REGISTER_MUXDEMUX(FLAC, flac); - REGISTER_DEMUXER (FLIC, flic); - REGISTER_MUXDEMUX(FLV, flv); - REGISTER_DEMUXER (FOURXM, fourxm); - REGISTER_MUXER (FRAMECRC, framecrc); - REGISTER_MUXER (FRAMEMD5, framemd5); - REGISTER_DEMUXER (FRM, frm); - REGISTER_MUXDEMUX(G722, g722); - REGISTER_MUXDEMUX(G723_1, g723_1); - REGISTER_DEMUXER (G729, g729); - REGISTER_MUXDEMUX(GIF, gif); - REGISTER_DEMUXER (GSM, gsm); - REGISTER_MUXDEMUX(GXF, gxf); - REGISTER_MUXDEMUX(H261, h261); - REGISTER_MUXDEMUX(H263, h263); - REGISTER_MUXDEMUX(H264, h264); - REGISTER_MUXDEMUX(HLS, hls); - REGISTER_MUXDEMUX(ICO, ico); - REGISTER_DEMUXER (IDCIN, idcin); - REGISTER_DEMUXER (IDF, idf); - REGISTER_DEMUXER (IFF, iff); - REGISTER_MUXDEMUX(ILBC, ilbc); - REGISTER_MUXDEMUX(IMAGE2, image2); - REGISTER_MUXDEMUX(IMAGE2PIPE, image2pipe); - REGISTER_DEMUXER (INGENIENT, ingenient); - REGISTER_DEMUXER (IPMOVIE, ipmovie); - REGISTER_MUXER (IPOD, ipod); - REGISTER_MUXDEMUX(IRCAM, ircam); - REGISTER_MUXER (ISMV, ismv); - REGISTER_DEMUXER (ISS, iss); - REGISTER_DEMUXER (IV8, iv8); - REGISTER_MUXDEMUX(IVF, ivf); - REGISTER_MUXDEMUX(JACOSUB, jacosub); - REGISTER_DEMUXER (JV, jv); - REGISTER_MUXDEMUX(LATM, latm); - REGISTER_DEMUXER (LMLM4, lmlm4); - REGISTER_DEMUXER (LOAS, loas); - REGISTER_DEMUXER (LVF, lvf); - REGISTER_DEMUXER (LXF, lxf); - REGISTER_MUXDEMUX(M4V, m4v); - REGISTER_MUXER (MD5, md5); - REGISTER_MUXDEMUX(MATROSKA, matroska); - REGISTER_MUXER (MATROSKA_AUDIO, matroska_audio); - REGISTER_DEMUXER (MGSTS, mgsts); - REGISTER_MUXDEMUX(MICRODVD, microdvd); - REGISTER_MUXDEMUX(MJPEG, mjpeg); - REGISTER_MUXDEMUX(MLP, mlp); - REGISTER_DEMUXER (MM, mm); - REGISTER_MUXDEMUX(MMF, mmf); - REGISTER_MUXDEMUX(MOV, mov); - REGISTER_MUXER (MP2, mp2); - REGISTER_MUXDEMUX(MP3, mp3); - REGISTER_MUXER (MP4, mp4); - REGISTER_DEMUXER (MPC, mpc); - REGISTER_DEMUXER (MPC8, mpc8); - REGISTER_MUXER (MPEG1SYSTEM, mpeg1system); - REGISTER_MUXER (MPEG1VCD, mpeg1vcd); - REGISTER_MUXER (MPEG1VIDEO, mpeg1video); - REGISTER_MUXER (MPEG2DVD, mpeg2dvd); - REGISTER_MUXER (MPEG2SVCD, mpeg2svcd); - REGISTER_MUXER (MPEG2VIDEO, mpeg2video); - REGISTER_MUXER (MPEG2VOB, mpeg2vob); - REGISTER_DEMUXER (MPEGPS, mpegps); - REGISTER_MUXDEMUX(MPEGTS, mpegts); - REGISTER_DEMUXER (MPEGTSRAW, mpegtsraw); - REGISTER_DEMUXER (MPEGVIDEO, mpegvideo); - REGISTER_MUXER (MPJPEG, mpjpeg); - REGISTER_DEMUXER (MPL2, mpl2); - REGISTER_DEMUXER (MPSUB, mpsub); - REGISTER_DEMUXER (MSNWC_TCP, msnwc_tcp); - REGISTER_DEMUXER (MTV, mtv); - REGISTER_DEMUXER (MV, mv); - REGISTER_DEMUXER (MVI, mvi); - REGISTER_MUXDEMUX(MXF, mxf); - REGISTER_MUXER (MXF_D10, mxf_d10); - REGISTER_DEMUXER (MXG, mxg); - REGISTER_DEMUXER (NC, nc); - REGISTER_DEMUXER (NISTSPHERE, nistsphere); - REGISTER_DEMUXER (NSV, nsv); - REGISTER_MUXER (NULL, null); - REGISTER_MUXDEMUX(NUT, nut); - REGISTER_DEMUXER (NUV, nuv); - REGISTER_MUXDEMUX(OGG, ogg); - REGISTER_MUXDEMUX(OMA, oma); - REGISTER_DEMUXER (PAF, paf); - REGISTER_MUXDEMUX(PCM_ALAW, pcm_alaw); - REGISTER_MUXDEMUX(PCM_MULAW, pcm_mulaw); - REGISTER_MUXDEMUX(PCM_F64BE, pcm_f64be); - REGISTER_MUXDEMUX(PCM_F64LE, pcm_f64le); - REGISTER_MUXDEMUX(PCM_F32BE, pcm_f32be); - REGISTER_MUXDEMUX(PCM_F32LE, pcm_f32le); - REGISTER_MUXDEMUX(PCM_S32BE, pcm_s32be); - REGISTER_MUXDEMUX(PCM_S32LE, pcm_s32le); - REGISTER_MUXDEMUX(PCM_S24BE, pcm_s24be); - REGISTER_MUXDEMUX(PCM_S24LE, pcm_s24le); - REGISTER_MUXDEMUX(PCM_S16BE, pcm_s16be); - REGISTER_MUXDEMUX(PCM_S16LE, pcm_s16le); - REGISTER_MUXDEMUX(PCM_S8, pcm_s8); - REGISTER_MUXDEMUX(PCM_U32BE, pcm_u32be); - REGISTER_MUXDEMUX(PCM_U32LE, pcm_u32le); - REGISTER_MUXDEMUX(PCM_U24BE, pcm_u24be); - REGISTER_MUXDEMUX(PCM_U24LE, pcm_u24le); - REGISTER_MUXDEMUX(PCM_U16BE, pcm_u16be); - REGISTER_MUXDEMUX(PCM_U16LE, pcm_u16le); - REGISTER_MUXDEMUX(PCM_U8, pcm_u8); - REGISTER_DEMUXER (PJS, pjs); - REGISTER_DEMUXER (PMP, pmp); - REGISTER_MUXER (PSP, psp); - REGISTER_DEMUXER (PVA, pva); - REGISTER_DEMUXER (PVF, pvf); - REGISTER_DEMUXER (QCP, qcp); - REGISTER_DEMUXER (R3D, r3d); - REGISTER_MUXDEMUX(RAWVIDEO, rawvideo); - REGISTER_DEMUXER (REALTEXT, realtext); - REGISTER_DEMUXER (RL2, rl2); - REGISTER_MUXDEMUX(RM, rm); - REGISTER_MUXDEMUX(ROQ, roq); - REGISTER_DEMUXER (RPL, rpl); - REGISTER_MUXDEMUX(RSO, rso); - REGISTER_MUXDEMUX(RTP, rtp); - REGISTER_MUXDEMUX(RTSP, rtsp); - REGISTER_DEMUXER (SAMI, sami); - REGISTER_MUXDEMUX(SAP, sap); - REGISTER_DEMUXER (SBG, sbg); - REGISTER_DEMUXER (SDP, sdp); -#if CONFIG_RTPDEC - av_register_rtp_dynamic_payload_handlers(); - av_register_rdt_dynamic_payload_handlers(); -#endif - REGISTER_DEMUXER (SEGAFILM, segafilm); - REGISTER_MUXER (SEGMENT, segment); - REGISTER_MUXER (SEGMENT, stream_segment); - REGISTER_DEMUXER (SHORTEN, shorten); - REGISTER_DEMUXER (SIFF, siff); - REGISTER_DEMUXER (SMACKER, smacker); - REGISTER_MUXDEMUX(SMJPEG, smjpeg); - REGISTER_MUXER (SMOOTHSTREAMING, smoothstreaming); - REGISTER_DEMUXER (SMUSH, smush); - REGISTER_DEMUXER (SOL, sol); - REGISTER_MUXDEMUX(SOX, sox); - REGISTER_MUXDEMUX(SPDIF, spdif); - REGISTER_MUXDEMUX(SRT, srt); - REGISTER_DEMUXER (STR, str); - REGISTER_DEMUXER (SUBVIEWER1, subviewer1); - REGISTER_DEMUXER (SUBVIEWER, subviewer); - REGISTER_MUXDEMUX(SWF, swf); - REGISTER_DEMUXER (TAK, tak); - REGISTER_MUXER (TEE, tee); - REGISTER_DEMUXER (TEDCAPTIONS, tedcaptions); - REGISTER_MUXER (TG2, tg2); - REGISTER_MUXER (TGP, tgp); - REGISTER_DEMUXER (THP, thp); - REGISTER_DEMUXER (TIERTEXSEQ, tiertexseq); - REGISTER_MUXER (MKVTIMESTAMP_V2, mkvtimestamp_v2); - REGISTER_DEMUXER (TMV, tmv); - REGISTER_MUXDEMUX(TRUEHD, truehd); - REGISTER_DEMUXER (TTA, tta); - REGISTER_DEMUXER (TXD, txd); - REGISTER_DEMUXER (TTY, tty); - REGISTER_MUXDEMUX(VC1, vc1); - REGISTER_MUXDEMUX(VC1T, vc1t); - REGISTER_DEMUXER (VIVO, vivo); - REGISTER_DEMUXER (VMD, vmd); - REGISTER_DEMUXER (VOBSUB, vobsub); - REGISTER_MUXDEMUX(VOC, voc); - REGISTER_DEMUXER (VPLAYER, vplayer); - REGISTER_DEMUXER (VQF, vqf); - REGISTER_MUXDEMUX(W64, w64); - REGISTER_MUXDEMUX(WAV, wav); - REGISTER_DEMUXER (WC3, wc3); - REGISTER_MUXER (WEBM, webm); - REGISTER_DEMUXER (WEBVTT, webvtt); - REGISTER_DEMUXER (WSAUD, wsaud); - REGISTER_DEMUXER (WSVQA, wsvqa); - REGISTER_MUXDEMUX(WTV, wtv); - REGISTER_MUXDEMUX(WV, wv); - REGISTER_DEMUXER (XA, xa); - REGISTER_DEMUXER (XBIN, xbin); - REGISTER_DEMUXER (XMV, xmv); - REGISTER_DEMUXER (XWMA, xwma); - REGISTER_DEMUXER (YOP, yop); - REGISTER_MUXDEMUX(YUV4MPEGPIPE, yuv4mpegpipe); - - /* protocols */ - REGISTER_PROTOCOL(BLURAY, bluray); - REGISTER_PROTOCOL(CACHE, cache); - REGISTER_PROTOCOL(CONCAT, concat); - REGISTER_PROTOCOL(CRYPTO, crypto); - REGISTER_PROTOCOL(DATA, data); - REGISTER_PROTOCOL(FFRTMPCRYPT, ffrtmpcrypt); - REGISTER_PROTOCOL(FFRTMPHTTP, ffrtmphttp); - REGISTER_PROTOCOL(FILE, file); - REGISTER_PROTOCOL(GOPHER, gopher); - REGISTER_PROTOCOL(HLS, hls); - REGISTER_PROTOCOL(HTTP, http); - REGISTER_PROTOCOL(HTTPPROXY, httpproxy); - REGISTER_PROTOCOL(HTTPS, https); - REGISTER_PROTOCOL(MMSH, mmsh); - REGISTER_PROTOCOL(MMST, mmst); - REGISTER_PROTOCOL(MD5, md5); - REGISTER_PROTOCOL(PIPE, pipe); - REGISTER_PROTOCOL(RTMP, rtmp); - REGISTER_PROTOCOL(RTMPE, rtmpe); - REGISTER_PROTOCOL(RTMPS, rtmps); - REGISTER_PROTOCOL(RTMPT, rtmpt); - REGISTER_PROTOCOL(RTMPTE, rtmpte); - REGISTER_PROTOCOL(RTMPTS, rtmpts); - REGISTER_PROTOCOL(RTP, rtp); - REGISTER_PROTOCOL(SCTP, sctp); - REGISTER_PROTOCOL(SRTP, srtp); - REGISTER_PROTOCOL(TCP, tcp); - REGISTER_PROTOCOL(TLS, tls); - REGISTER_PROTOCOL(UDP, udp); - - /* external libraries */ - REGISTER_DEMUXER (LIBMODPLUG, libmodplug); - REGISTER_MUXDEMUX(LIBNUT, libnut); - REGISTER_PROTOCOL(LIBRTMP, librtmp); - REGISTER_PROTOCOL(LIBRTMPE, librtmpe); - REGISTER_PROTOCOL(LIBRTMPS, librtmps); - REGISTER_PROTOCOL(LIBRTMPT, librtmpt); - REGISTER_PROTOCOL(LIBRTMPTE, librtmpte); -} diff --git a/ffmpeg1/libavformat/amr.c b/ffmpeg1/libavformat/amr.c deleted file mode 100644 index 07ab1ba..0000000 --- a/ffmpeg1/libavformat/amr.c +++ /dev/null @@ -1,182 +0,0 @@ -/* - * amr file format - * Copyright (c) 2001 ffmpeg project - * - * 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 - */ - -/* -Write and read amr data according to RFC3267, http://www.ietf.org/rfc/rfc3267.txt?number=3267 - -Only mono files are supported. - -*/ - -#include "libavutil/avassert.h" -#include "libavutil/channel_layout.h" -#include "avformat.h" -#include "internal.h" - -static const char AMR_header[] = "#!AMR\n"; -static const char AMRWB_header[] = "#!AMR-WB\n"; - -#if CONFIG_AMR_MUXER -static int amr_write_header(AVFormatContext *s) -{ - AVIOContext *pb = s->pb; - AVCodecContext *enc = s->streams[0]->codec; - - s->priv_data = NULL; - - if (enc->codec_id == AV_CODEC_ID_AMR_NB) { - avio_write(pb, AMR_header, sizeof(AMR_header) - 1); /* magic number */ - } else if (enc->codec_id == AV_CODEC_ID_AMR_WB) { - avio_write(pb, AMRWB_header, sizeof(AMRWB_header) - 1); /* magic number */ - } else { - return -1; - } - avio_flush(pb); - return 0; -} - -static int amr_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - avio_write(s->pb, pkt->data, pkt->size); - avio_flush(s->pb); - return 0; -} -#endif /* CONFIG_AMR_MUXER */ - -static int amr_probe(AVProbeData *p) -{ - // Only check for "#!AMR" which could be amr-wb, amr-nb. - // This will also trigger multichannel files: "#!AMR_MC1.0\n" and - // "#!AMR-WB_MC1.0\n" (not supported) - - if (!memcmp(p->buf, AMR_header, 5)) - return AVPROBE_SCORE_MAX; - else - return 0; -} - -/* amr input */ -static int amr_read_header(AVFormatContext *s) -{ - AVIOContext *pb = s->pb; - AVStream *st; - uint8_t header[9]; - - avio_read(pb, header, 6); - - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - if (memcmp(header, AMR_header, 6)) { - avio_read(pb, header + 6, 3); - if (memcmp(header, AMRWB_header, 9)) { - return -1; - } - - st->codec->codec_tag = MKTAG('s', 'a', 'w', 'b'); - st->codec->codec_id = AV_CODEC_ID_AMR_WB; - st->codec->sample_rate = 16000; - } else { - st->codec->codec_tag = MKTAG('s', 'a', 'm', 'r'); - st->codec->codec_id = AV_CODEC_ID_AMR_NB; - st->codec->sample_rate = 8000; - } - st->codec->channels = 1; - st->codec->channel_layout = AV_CH_LAYOUT_MONO; - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); - - return 0; -} - -static int amr_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - AVCodecContext *enc = s->streams[0]->codec; - int read, size = 0, toc, mode; - int64_t pos = avio_tell(s->pb); - - if (url_feof(s->pb)) { - return AVERROR(EIO); - } - - // FIXME this is wrong, this should rather be in a AVParset - toc = avio_r8(s->pb); - mode = (toc >> 3) & 0x0F; - - if (enc->codec_id == AV_CODEC_ID_AMR_NB) { - static const uint8_t packed_size[16] = { - 12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0 - }; - - size = packed_size[mode] + 1; - } else if (enc->codec_id == AV_CODEC_ID_AMR_WB) { - static const uint8_t packed_size[16] = { - 18, 24, 33, 37, 41, 47, 51, 59, 61, 6, 6, 0, 0, 0, 1, 1 - }; - - size = packed_size[mode]; - } else { - av_assert0(0); - } - - if (!size || av_new_packet(pkt, size)) - return AVERROR(EIO); - - /* Both AMR formats have 50 frames per second */ - s->streams[0]->codec->bit_rate = size*8*50; - - pkt->stream_index = 0; - pkt->pos = pos; - pkt->data[0] = toc; - pkt->duration = enc->codec_id == AV_CODEC_ID_AMR_NB ? 160 : 320; - read = avio_read(s->pb, pkt->data + 1, size - 1); - - if (read != size - 1) { - av_free_packet(pkt); - return AVERROR(EIO); - } - - return 0; -} - -#if CONFIG_AMR_DEMUXER -AVInputFormat ff_amr_demuxer = { - .name = "amr", - .long_name = NULL_IF_CONFIG_SMALL("3GPP AMR"), - .read_probe = amr_probe, - .read_header = amr_read_header, - .read_packet = amr_read_packet, - .flags = AVFMT_GENERIC_INDEX, -}; -#endif - -#if CONFIG_AMR_MUXER -AVOutputFormat ff_amr_muxer = { - .name = "amr", - .long_name = NULL_IF_CONFIG_SMALL("3GPP AMR"), - .mime_type = "audio/amr", - .extensions = "amr", - .audio_codec = AV_CODEC_ID_AMR_NB, - .video_codec = AV_CODEC_ID_NONE, - .write_header = amr_write_header, - .write_packet = amr_write_packet, -}; -#endif diff --git a/ffmpeg1/libavformat/anm.c b/ffmpeg1/libavformat/anm.c deleted file mode 100644 index 1c58575..0000000 --- a/ffmpeg1/libavformat/anm.c +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Deluxe Paint Animation demuxer - * Copyright (c) 2009 Peter Ross - * - * 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 - */ - -/** - * @file - * Deluxe Paint Animation demuxer - */ - -#include "libavutil/intreadwrite.h" -#include "avformat.h" -#include "internal.h" - -typedef struct { - int base_record; - unsigned int nb_records; - int size; -} Page; - -typedef struct { - unsigned int nb_pages; /**< total pages in file */ - unsigned int nb_records; /**< total records in file */ - int page_table_offset; -#define MAX_PAGES 256 /**< Deluxe Paint hardcoded value */ - Page pt[MAX_PAGES]; /**< page table */ - int page; /**< current page (or AVERROR_xxx code) */ - int record; /**< current record (with in page) */ -} AnmDemuxContext; - -#define LPF_TAG MKTAG('L','P','F',' ') -#define ANIM_TAG MKTAG('A','N','I','M') - -static int probe(AVProbeData *p) -{ - /* verify tags and video dimensions */ - if (AV_RL32(&p->buf[0]) == LPF_TAG && - AV_RL32(&p->buf[16]) == ANIM_TAG && - AV_RL16(&p->buf[20]) && AV_RL16(&p->buf[22])) - return AVPROBE_SCORE_MAX; - return 0; -} - -/** - * @return page containing the requested record or AVERROR_XXX - */ -static int find_record(const AnmDemuxContext *anm, int record) -{ - int i; - - if (record >= anm->nb_records) - return AVERROR_EOF; - - for (i = 0; i < MAX_PAGES; i++) { - const Page *p = &anm->pt[i]; - if (p->nb_records > 0 && record >= p->base_record && record < p->base_record + p->nb_records) - return i; - } - - return AVERROR_INVALIDDATA; -} - -static int read_header(AVFormatContext *s) -{ - AnmDemuxContext *anm = s->priv_data; - AVIOContext *pb = s->pb; - AVStream *st; - int i, ret; - - avio_skip(pb, 4); /* magic number */ - if (avio_rl16(pb) != MAX_PAGES) { - avpriv_request_sample(s, "max_pages != " AV_STRINGIFY(MAX_PAGES)); - return AVERROR_PATCHWELCOME; - } - - anm->nb_pages = avio_rl16(pb); - anm->nb_records = avio_rl32(pb); - avio_skip(pb, 2); /* max records per page */ - anm->page_table_offset = avio_rl16(pb); - if (avio_rl32(pb) != ANIM_TAG) - return AVERROR_INVALIDDATA; - - /* video stream */ - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = AV_CODEC_ID_ANM; - st->codec->codec_tag = 0; /* no fourcc */ - st->codec->width = avio_rl16(pb); - st->codec->height = avio_rl16(pb); - if (avio_r8(pb) != 0) - goto invalid; - avio_skip(pb, 1); /* frame rate multiplier info */ - - /* ignore last delta record (used for looping) */ - if (avio_r8(pb)) /* has_last_delta */ - anm->nb_records = FFMAX(anm->nb_records - 1, 0); - - avio_skip(pb, 1); /* last_delta_valid */ - - if (avio_r8(pb) != 0) - goto invalid; - - if (avio_r8(pb) != 1) - goto invalid; - - avio_skip(pb, 1); /* other recs per frame */ - - if (avio_r8(pb) != 1) - goto invalid; - - avio_skip(pb, 32); /* record_types */ - st->nb_frames = avio_rl32(pb); - avpriv_set_pts_info(st, 64, 1, avio_rl16(pb)); - avio_skip(pb, 58); - - /* color cycling and palette data */ - st->codec->extradata_size = 16*8 + 4*256; - st->codec->extradata = av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!st->codec->extradata) { - return AVERROR(ENOMEM); - } - ret = avio_read(pb, st->codec->extradata, st->codec->extradata_size); - if (ret < 0) - return ret; - - /* read page table */ - ret = avio_seek(pb, anm->page_table_offset, SEEK_SET); - if (ret < 0) - return ret; - - for (i = 0; i < MAX_PAGES; i++) { - Page *p = &anm->pt[i]; - p->base_record = avio_rl16(pb); - p->nb_records = avio_rl16(pb); - p->size = avio_rl16(pb); - } - - /* find page of first frame */ - anm->page = find_record(anm, 0); - if (anm->page < 0) { - return anm->page; - } - - anm->record = -1; - return 0; - -invalid: - avpriv_request_sample(s, "Invalid header element"); - return AVERROR_PATCHWELCOME; -} - -static int read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - AnmDemuxContext *anm = s->priv_data; - AVIOContext *pb = s->pb; - Page *p; - int tmp, record_size; - - if (url_feof(s->pb)) - return AVERROR(EIO); - - if (anm->page < 0) - return anm->page; - -repeat: - p = &anm->pt[anm->page]; - - /* parse page header */ - if (anm->record < 0) { - avio_seek(pb, anm->page_table_offset + MAX_PAGES*6 + (anm->page<<16), SEEK_SET); - avio_skip(pb, 8 + 2*p->nb_records); - anm->record = 0; - } - - /* if we have fetched all records in this page, then find the - next page and repeat */ - if (anm->record >= p->nb_records) { - anm->page = find_record(anm, p->base_record + p->nb_records); - if (anm->page < 0) - return anm->page; - anm->record = -1; - goto repeat; - } - - /* fetch record size */ - tmp = avio_tell(pb); - avio_seek(pb, anm->page_table_offset + MAX_PAGES*6 + (anm->page<<16) + - 8 + anm->record * 2, SEEK_SET); - record_size = avio_rl16(pb); - avio_seek(pb, tmp, SEEK_SET); - - /* fetch record */ - pkt->size = av_get_packet(s->pb, pkt, record_size); - if (pkt->size < 0) - return pkt->size; - if (p->base_record + anm->record == 0) - pkt->flags |= AV_PKT_FLAG_KEY; - - anm->record++; - return 0; -} - -AVInputFormat ff_anm_demuxer = { - .name = "anm", - .long_name = NULL_IF_CONFIG_SMALL("Deluxe Paint Animation"), - .priv_data_size = sizeof(AnmDemuxContext), - .read_probe = probe, - .read_header = read_header, - .read_packet = read_packet, -}; diff --git a/ffmpeg1/libavformat/apc.c b/ffmpeg1/libavformat/apc.c deleted file mode 100644 index bb28a62..0000000 --- a/ffmpeg1/libavformat/apc.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * CRYO APC audio format demuxer - * Copyright (c) 2007 Anssi Hannula - * - * 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 - -#include "libavutil/channel_layout.h" -#include "avformat.h" - -static int apc_probe(AVProbeData *p) -{ - if (!strncmp(p->buf, "CRYO_APC", 8)) - return AVPROBE_SCORE_MAX; - - return 0; -} - -static int apc_read_header(AVFormatContext *s) -{ - AVIOContext *pb = s->pb; - AVStream *st; - - avio_rl32(pb); /* CRYO */ - avio_rl32(pb); /* _APC */ - avio_rl32(pb); /* 1.20 */ - - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = AV_CODEC_ID_ADPCM_IMA_APC; - - avio_rl32(pb); /* number of samples */ - st->codec->sample_rate = avio_rl32(pb); - - st->codec->extradata_size = 2 * 4; - st->codec->extradata = av_malloc(st->codec->extradata_size + - FF_INPUT_BUFFER_PADDING_SIZE); - if (!st->codec->extradata) - return AVERROR(ENOMEM); - - /* initial predictor values for adpcm decoder */ - avio_read(pb, st->codec->extradata, 2 * 4); - - if (avio_rl32(pb)) { - st->codec->channels = 2; - st->codec->channel_layout = AV_CH_LAYOUT_STEREO; - } else { - st->codec->channels = 1; - st->codec->channel_layout = AV_CH_LAYOUT_MONO; - } - - st->codec->bits_per_coded_sample = 4; - st->codec->bit_rate = st->codec->bits_per_coded_sample * st->codec->channels - * st->codec->sample_rate; - st->codec->block_align = 1; - - return 0; -} - -#define MAX_READ_SIZE 4096 - -static int apc_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - if (av_get_packet(s->pb, pkt, MAX_READ_SIZE) <= 0) - return AVERROR(EIO); - pkt->flags &= ~AV_PKT_FLAG_CORRUPT; - pkt->stream_index = 0; - return 0; -} - -AVInputFormat ff_apc_demuxer = { - .name = "apc", - .long_name = NULL_IF_CONFIG_SMALL("CRYO APC"), - .read_probe = apc_probe, - .read_header = apc_read_header, - .read_packet = apc_read_packet, -}; diff --git a/ffmpeg1/libavformat/ape.c b/ffmpeg1/libavformat/ape.c deleted file mode 100644 index 09ed9c5..0000000 --- a/ffmpeg1/libavformat/ape.c +++ /dev/null @@ -1,443 +0,0 @@ -/* - * Monkey's Audio APE demuxer - * Copyright (c) 2007 Benjamin Zores - * based upon libdemac from Dave Chapman. - * - * 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 - -#include "libavutil/intreadwrite.h" -#include "avformat.h" -#include "internal.h" -#include "apetag.h" - -/* The earliest and latest file formats supported by this library */ -#define APE_MIN_VERSION 3930 -#define APE_MAX_VERSION 3990 - -#define MAC_FORMAT_FLAG_8_BIT 1 // is 8-bit [OBSOLETE] -#define MAC_FORMAT_FLAG_CRC 2 // uses the new CRC32 error detection [OBSOLETE] -#define MAC_FORMAT_FLAG_HAS_PEAK_LEVEL 4 // uint32 nPeakLevel after the header [OBSOLETE] -#define MAC_FORMAT_FLAG_24_BIT 8 // is 24-bit [OBSOLETE] -#define MAC_FORMAT_FLAG_HAS_SEEK_ELEMENTS 16 // has the number of seek elements after the peak level -#define MAC_FORMAT_FLAG_CREATE_WAV_HEADER 32 // create the wave header on decompression (not stored) - -#define APE_EXTRADATA_SIZE 6 - -typedef struct { - int64_t pos; - int nblocks; - int size; - int skip; - int64_t pts; -} APEFrame; - -typedef struct { - /* Derived fields */ - uint32_t junklength; - uint32_t firstframe; - uint32_t totalsamples; - int currentframe; - APEFrame *frames; - - /* Info from Descriptor Block */ - char magic[4]; - int16_t fileversion; - int16_t padding1; - uint32_t descriptorlength; - uint32_t headerlength; - uint32_t seektablelength; - uint32_t wavheaderlength; - uint32_t audiodatalength; - uint32_t audiodatalength_high; - uint32_t wavtaillength; - uint8_t md5[16]; - - /* Info from Header Block */ - uint16_t compressiontype; - uint16_t formatflags; - uint32_t blocksperframe; - uint32_t finalframeblocks; - uint32_t totalframes; - uint16_t bps; - uint16_t channels; - uint32_t samplerate; - - /* Seektable */ - uint32_t *seektable; -} APEContext; - -static int ape_probe(AVProbeData * p) -{ - if (p->buf[0] == 'M' && p->buf[1] == 'A' && p->buf[2] == 'C' && p->buf[3] == ' ') - return AVPROBE_SCORE_MAX; - - return 0; -} - -static void ape_dumpinfo(AVFormatContext * s, APEContext * ape_ctx) -{ -#ifdef DEBUG - int i; - - av_log(s, AV_LOG_DEBUG, "Descriptor Block:\n\n"); - av_log(s, AV_LOG_DEBUG, "magic = \"%c%c%c%c\"\n", ape_ctx->magic[0], ape_ctx->magic[1], ape_ctx->magic[2], ape_ctx->magic[3]); - av_log(s, AV_LOG_DEBUG, "fileversion = %"PRId16"\n", ape_ctx->fileversion); - av_log(s, AV_LOG_DEBUG, "descriptorlength = %"PRIu32"\n", ape_ctx->descriptorlength); - av_log(s, AV_LOG_DEBUG, "headerlength = %"PRIu32"\n", ape_ctx->headerlength); - av_log(s, AV_LOG_DEBUG, "seektablelength = %"PRIu32"\n", ape_ctx->seektablelength); - av_log(s, AV_LOG_DEBUG, "wavheaderlength = %"PRIu32"\n", ape_ctx->wavheaderlength); - av_log(s, AV_LOG_DEBUG, "audiodatalength = %"PRIu32"\n", ape_ctx->audiodatalength); - av_log(s, AV_LOG_DEBUG, "audiodatalength_high = %"PRIu32"\n", ape_ctx->audiodatalength_high); - av_log(s, AV_LOG_DEBUG, "wavtaillength = %"PRIu32"\n", ape_ctx->wavtaillength); - av_log(s, AV_LOG_DEBUG, "md5 = "); - for (i = 0; i < 16; i++) - av_log(s, AV_LOG_DEBUG, "%02x", ape_ctx->md5[i]); - av_log(s, AV_LOG_DEBUG, "\n"); - - av_log(s, AV_LOG_DEBUG, "\nHeader Block:\n\n"); - - av_log(s, AV_LOG_DEBUG, "compressiontype = %"PRIu16"\n", ape_ctx->compressiontype); - av_log(s, AV_LOG_DEBUG, "formatflags = %"PRIu16"\n", ape_ctx->formatflags); - av_log(s, AV_LOG_DEBUG, "blocksperframe = %"PRIu32"\n", ape_ctx->blocksperframe); - av_log(s, AV_LOG_DEBUG, "finalframeblocks = %"PRIu32"\n", ape_ctx->finalframeblocks); - av_log(s, AV_LOG_DEBUG, "totalframes = %"PRIu32"\n", ape_ctx->totalframes); - av_log(s, AV_LOG_DEBUG, "bps = %"PRIu16"\n", ape_ctx->bps); - av_log(s, AV_LOG_DEBUG, "channels = %"PRIu16"\n", ape_ctx->channels); - av_log(s, AV_LOG_DEBUG, "samplerate = %"PRIu32"\n", ape_ctx->samplerate); - - av_log(s, AV_LOG_DEBUG, "\nSeektable\n\n"); - if ((ape_ctx->seektablelength / sizeof(uint32_t)) != ape_ctx->totalframes) { - av_log(s, AV_LOG_DEBUG, "No seektable\n"); - } else { - for (i = 0; i < ape_ctx->seektablelength / sizeof(uint32_t); i++) { - if (i < ape_ctx->totalframes - 1) { - av_log(s, AV_LOG_DEBUG, "%8d %"PRIu32" (%"PRIu32" bytes)\n", - i, ape_ctx->seektable[i], - ape_ctx->seektable[i + 1] - ape_ctx->seektable[i]); - } else { - av_log(s, AV_LOG_DEBUG, "%8d %"PRIu32"\n", i, ape_ctx->seektable[i]); - } - } - } - - av_log(s, AV_LOG_DEBUG, "\nFrames\n\n"); - for (i = 0; i < ape_ctx->totalframes; i++) - av_log(s, AV_LOG_DEBUG, "%8d %8"PRId64" %8d (%d samples)\n", i, - ape_ctx->frames[i].pos, ape_ctx->frames[i].size, - ape_ctx->frames[i].nblocks); - - av_log(s, AV_LOG_DEBUG, "\nCalculated information:\n\n"); - av_log(s, AV_LOG_DEBUG, "junklength = %"PRIu32"\n", ape_ctx->junklength); - av_log(s, AV_LOG_DEBUG, "firstframe = %"PRIu32"\n", ape_ctx->firstframe); - av_log(s, AV_LOG_DEBUG, "totalsamples = %"PRIu32"\n", ape_ctx->totalsamples); -#endif -} - -static int ape_read_header(AVFormatContext * s) -{ - AVIOContext *pb = s->pb; - APEContext *ape = s->priv_data; - AVStream *st; - uint32_t tag; - int i; - int total_blocks, final_size = 0; - int64_t pts, file_size; - - /* Skip any leading junk such as id3v2 tags */ - ape->junklength = avio_tell(pb); - - tag = avio_rl32(pb); - if (tag != MKTAG('M', 'A', 'C', ' ')) - return AVERROR_INVALIDDATA; - - ape->fileversion = avio_rl16(pb); - - if (ape->fileversion < APE_MIN_VERSION || ape->fileversion > APE_MAX_VERSION) { - av_log(s, AV_LOG_ERROR, "Unsupported file version - %d.%02d\n", - ape->fileversion / 1000, (ape->fileversion % 1000) / 10); - return AVERROR_PATCHWELCOME; - } - - if (ape->fileversion >= 3980) { - ape->padding1 = avio_rl16(pb); - ape->descriptorlength = avio_rl32(pb); - ape->headerlength = avio_rl32(pb); - ape->seektablelength = avio_rl32(pb); - ape->wavheaderlength = avio_rl32(pb); - ape->audiodatalength = avio_rl32(pb); - ape->audiodatalength_high = avio_rl32(pb); - ape->wavtaillength = avio_rl32(pb); - avio_read(pb, ape->md5, 16); - - /* Skip any unknown bytes at the end of the descriptor. - This is for future compatibility */ - if (ape->descriptorlength > 52) - avio_skip(pb, ape->descriptorlength - 52); - - /* Read header data */ - ape->compressiontype = avio_rl16(pb); - ape->formatflags = avio_rl16(pb); - ape->blocksperframe = avio_rl32(pb); - ape->finalframeblocks = avio_rl32(pb); - ape->totalframes = avio_rl32(pb); - ape->bps = avio_rl16(pb); - ape->channels = avio_rl16(pb); - ape->samplerate = avio_rl32(pb); - } else { - ape->descriptorlength = 0; - ape->headerlength = 32; - - ape->compressiontype = avio_rl16(pb); - ape->formatflags = avio_rl16(pb); - ape->channels = avio_rl16(pb); - ape->samplerate = avio_rl32(pb); - ape->wavheaderlength = avio_rl32(pb); - ape->wavtaillength = avio_rl32(pb); - ape->totalframes = avio_rl32(pb); - ape->finalframeblocks = avio_rl32(pb); - - if (ape->formatflags & MAC_FORMAT_FLAG_HAS_PEAK_LEVEL) { - avio_skip(pb, 4); /* Skip the peak level */ - ape->headerlength += 4; - } - - if (ape->formatflags & MAC_FORMAT_FLAG_HAS_SEEK_ELEMENTS) { - ape->seektablelength = avio_rl32(pb); - ape->headerlength += 4; - ape->seektablelength *= sizeof(int32_t); - } else - ape->seektablelength = ape->totalframes * sizeof(int32_t); - - if (ape->formatflags & MAC_FORMAT_FLAG_8_BIT) - ape->bps = 8; - else if (ape->formatflags & MAC_FORMAT_FLAG_24_BIT) - ape->bps = 24; - else - ape->bps = 16; - - if (ape->fileversion >= 3950) - ape->blocksperframe = 73728 * 4; - else if (ape->fileversion >= 3900 || (ape->fileversion >= 3800 && ape->compressiontype >= 4000)) - ape->blocksperframe = 73728; - else - ape->blocksperframe = 9216; - - /* Skip any stored wav header */ - if (!(ape->formatflags & MAC_FORMAT_FLAG_CREATE_WAV_HEADER)) - avio_skip(pb, ape->wavheaderlength); - } - - if(!ape->totalframes){ - av_log(s, AV_LOG_ERROR, "No frames in the file!\n"); - return AVERROR(EINVAL); - } - if(ape->totalframes > UINT_MAX / sizeof(APEFrame)){ - av_log(s, AV_LOG_ERROR, "Too many frames: %"PRIu32"\n", - ape->totalframes); - return AVERROR_INVALIDDATA; - } - if (ape->seektablelength && (ape->seektablelength / sizeof(*ape->seektable)) < ape->totalframes) { - av_log(s, AV_LOG_ERROR, - "Number of seek entries is less than number of frames: %zu vs. %"PRIu32"\n", - ape->seektablelength / sizeof(*ape->seektable), ape->totalframes); - return AVERROR_INVALIDDATA; - } - ape->frames = av_malloc(ape->totalframes * sizeof(APEFrame)); - if(!ape->frames) - return AVERROR(ENOMEM); - ape->firstframe = ape->junklength + ape->descriptorlength + ape->headerlength + ape->seektablelength + ape->wavheaderlength; - ape->currentframe = 0; - - - ape->totalsamples = ape->finalframeblocks; - if (ape->totalframes > 1) - ape->totalsamples += ape->blocksperframe * (ape->totalframes - 1); - - if (ape->seektablelength > 0) { - ape->seektable = av_malloc(ape->seektablelength); - if (!ape->seektable) - return AVERROR(ENOMEM); - for (i = 0; i < ape->seektablelength / sizeof(uint32_t); i++) - ape->seektable[i] = avio_rl32(pb); - }else{ - av_log(s, AV_LOG_ERROR, "Missing seektable\n"); - return AVERROR_INVALIDDATA; - } - - ape->frames[0].pos = ape->firstframe; - ape->frames[0].nblocks = ape->blocksperframe; - ape->frames[0].skip = 0; - for (i = 1; i < ape->totalframes; i++) { - ape->frames[i].pos = ape->seektable[i] + ape->junklength; - ape->frames[i].nblocks = ape->blocksperframe; - ape->frames[i - 1].size = ape->frames[i].pos - ape->frames[i - 1].pos; - ape->frames[i].skip = (ape->frames[i].pos - ape->frames[0].pos) & 3; - } - ape->frames[ape->totalframes - 1].nblocks = ape->finalframeblocks; - /* calculate final packet size from total file size, if available */ - file_size = avio_size(pb); - if (file_size > 0) { - final_size = file_size - ape->frames[ape->totalframes - 1].pos - - ape->wavtaillength; - final_size -= final_size & 3; - } - if (file_size <= 0 || final_size <= 0) - final_size = ape->finalframeblocks * 8; - ape->frames[ape->totalframes - 1].size = final_size; - - for (i = 0; i < ape->totalframes; i++) { - if(ape->frames[i].skip){ - ape->frames[i].pos -= ape->frames[i].skip; - ape->frames[i].size += ape->frames[i].skip; - } - ape->frames[i].size = (ape->frames[i].size + 3) & ~3; - } - - - ape_dumpinfo(s, ape); - - av_log(s, AV_LOG_DEBUG, "Decoding file - v%d.%02d, compression level %"PRIu16"\n", - ape->fileversion / 1000, (ape->fileversion % 1000) / 10, - ape->compressiontype); - - /* now we are ready: build format streams */ - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - - total_blocks = (ape->totalframes == 0) ? 0 : ((ape->totalframes - 1) * ape->blocksperframe) + ape->finalframeblocks; - - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = AV_CODEC_ID_APE; - st->codec->codec_tag = MKTAG('A', 'P', 'E', ' '); - st->codec->channels = ape->channels; - st->codec->sample_rate = ape->samplerate; - st->codec->bits_per_coded_sample = ape->bps; - - st->nb_frames = ape->totalframes; - st->start_time = 0; - st->duration = total_blocks; - avpriv_set_pts_info(st, 64, 1, ape->samplerate); - - st->codec->extradata = av_malloc(APE_EXTRADATA_SIZE); - st->codec->extradata_size = APE_EXTRADATA_SIZE; - AV_WL16(st->codec->extradata + 0, ape->fileversion); - AV_WL16(st->codec->extradata + 2, ape->compressiontype); - AV_WL16(st->codec->extradata + 4, ape->formatflags); - - pts = 0; - for (i = 0; i < ape->totalframes; i++) { - ape->frames[i].pts = pts; - av_add_index_entry(st, ape->frames[i].pos, ape->frames[i].pts, 0, 0, AVINDEX_KEYFRAME); - pts += ape->blocksperframe; - } - - /* try to read APE tags */ - if (pb->seekable) { - ff_ape_parse_tag(s); - avio_seek(pb, 0, SEEK_SET); - } - - return 0; -} - -static int ape_read_packet(AVFormatContext * s, AVPacket * pkt) -{ - int ret; - int nblocks; - APEContext *ape = s->priv_data; - uint32_t extra_size = 8; - - if (url_feof(s->pb)) - return AVERROR_EOF; - if (ape->currentframe >= ape->totalframes) - return AVERROR_EOF; - - if (avio_seek(s->pb, ape->frames[ape->currentframe].pos, SEEK_SET) < 0) - return AVERROR(EIO); - - /* Calculate how many blocks there are in this frame */ - if (ape->currentframe == (ape->totalframes - 1)) - nblocks = ape->finalframeblocks; - else - nblocks = ape->blocksperframe; - - if (ape->frames[ape->currentframe].size <= 0 || - ape->frames[ape->currentframe].size > INT_MAX - extra_size) { - av_log(s, AV_LOG_ERROR, "invalid packet size: %d\n", - ape->frames[ape->currentframe].size); - ape->currentframe++; - return AVERROR(EIO); - } - - if (av_new_packet(pkt, ape->frames[ape->currentframe].size + extra_size) < 0) - return AVERROR(ENOMEM); - - AV_WL32(pkt->data , nblocks); - AV_WL32(pkt->data + 4, ape->frames[ape->currentframe].skip); - ret = avio_read(s->pb, pkt->data + extra_size, ape->frames[ape->currentframe].size); - - pkt->pts = ape->frames[ape->currentframe].pts; - pkt->stream_index = 0; - - /* note: we need to modify the packet size here to handle the last - packet */ - pkt->size = ret + extra_size; - - ape->currentframe++; - - return 0; -} - -static int ape_read_close(AVFormatContext * s) -{ - APEContext *ape = s->priv_data; - - av_freep(&ape->frames); - av_freep(&ape->seektable); - return 0; -} - -static int ape_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) -{ - AVStream *st = s->streams[stream_index]; - APEContext *ape = s->priv_data; - int index = av_index_search_timestamp(st, timestamp, flags); - - if (index < 0) - return -1; - - if (avio_seek(s->pb, st->index_entries[index].pos, SEEK_SET) < 0) - return -1; - ape->currentframe = index; - return 0; -} - -AVInputFormat ff_ape_demuxer = { - .name = "ape", - .long_name = NULL_IF_CONFIG_SMALL("Monkey's Audio"), - .priv_data_size = sizeof(APEContext), - .read_probe = ape_probe, - .read_header = ape_read_header, - .read_packet = ape_read_packet, - .read_close = ape_read_close, - .read_seek = ape_read_seek, - .extensions = "ape,apl,mac", -}; diff --git a/ffmpeg1/libavformat/apetag.c b/ffmpeg1/libavformat/apetag.c deleted file mode 100644 index a445c84..0000000 --- a/ffmpeg1/libavformat/apetag.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - * APE tag handling - * Copyright (c) 2007 Benjamin Zores - * based upon libdemac from Dave Chapman. - * - * 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 "libavutil/intreadwrite.h" -#include "libavutil/dict.h" -#include "avformat.h" -#include "apetag.h" -#include "internal.h" - -#define APE_TAG_FLAG_CONTAINS_HEADER (1 << 31) -#define APE_TAG_FLAG_IS_HEADER (1 << 29) -#define APE_TAG_FLAG_IS_BINARY (1 << 1) - -static int ape_tag_read_field(AVFormatContext *s) -{ - AVIOContext *pb = s->pb; - uint8_t key[1024], *value; - uint32_t size, flags; - int i, c; - - size = avio_rl32(pb); /* field size */ - flags = avio_rl32(pb); /* field flags */ - for (i = 0; i < sizeof(key) - 1; i++) { - c = avio_r8(pb); - if (c < 0x20 || c > 0x7E) - break; - else - key[i] = c; - } - key[i] = 0; - if (c != 0) { - av_log(s, AV_LOG_WARNING, "Invalid APE tag key '%s'.\n", key); - return -1; - } - if (size >= UINT_MAX) - return -1; - if (flags & APE_TAG_FLAG_IS_BINARY) { - uint8_t filename[1024]; - enum AVCodecID id; - AVStream *st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - - size -= avio_get_str(pb, size, filename, sizeof(filename)); - if (size <= 0) { - av_log(s, AV_LOG_WARNING, "Skipping binary tag '%s'.\n", key); - return 0; - } - - av_dict_set(&st->metadata, key, filename, 0); - - if ((id = ff_guess_image2_codec(filename)) != AV_CODEC_ID_NONE) { - AVPacket pkt; - int ret; - - ret = av_get_packet(s->pb, &pkt, size); - if (ret < 0) { - av_log(s, AV_LOG_ERROR, "Error reading cover art.\n"); - return ret; - } - - st->disposition |= AV_DISPOSITION_ATTACHED_PIC; - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = id; - - st->attached_pic = pkt; - st->attached_pic.stream_index = st->index; - st->attached_pic.flags |= AV_PKT_FLAG_KEY; - } else { - st->codec->extradata = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!st->codec->extradata) - return AVERROR(ENOMEM); - if (avio_read(pb, st->codec->extradata, size) != size) { - av_freep(&st->codec->extradata); - return AVERROR(EIO); - } - st->codec->extradata_size = size; - st->codec->codec_type = AVMEDIA_TYPE_ATTACHMENT; - } - } else { - value = av_malloc(size+1); - if (!value) - return AVERROR(ENOMEM); - c = avio_read(pb, value, size); - if (c < 0) { - av_free(value); - return c; - } - value[c] = 0; - av_dict_set(&s->metadata, key, value, AV_DICT_DONT_STRDUP_VAL); - } - return 0; -} - -int64_t ff_ape_parse_tag(AVFormatContext *s) -{ - AVIOContext *pb = s->pb; - int file_size = avio_size(pb); - uint32_t val, fields, tag_bytes; - uint8_t buf[8]; - int64_t tag_start; - int i; - - if (file_size < APE_TAG_FOOTER_BYTES) - return 0; - - avio_seek(pb, file_size - APE_TAG_FOOTER_BYTES, SEEK_SET); - - avio_read(pb, buf, 8); /* APETAGEX */ - if (strncmp(buf, APE_TAG_PREAMBLE, 8)) { - return 0; - } - - val = avio_rl32(pb); /* APE tag version */ - if (val > APE_TAG_VERSION) { - av_log(s, AV_LOG_ERROR, "Unsupported tag version. (>=%d)\n", APE_TAG_VERSION); - return 0; - } - - tag_bytes = avio_rl32(pb); /* tag size */ - if (tag_bytes - APE_TAG_FOOTER_BYTES > (1024 * 1024 * 16)) { - av_log(s, AV_LOG_ERROR, "Tag size is way too big\n"); - return 0; - } - - if (tag_bytes > file_size - APE_TAG_FOOTER_BYTES) { - av_log(s, AV_LOG_ERROR, "Invalid tag size %u.\n", tag_bytes); - return 0; - } - tag_start = file_size - tag_bytes - APE_TAG_FOOTER_BYTES; - - fields = avio_rl32(pb); /* number of fields */ - if (fields > 65536) { - av_log(s, AV_LOG_ERROR, "Too many tag fields (%d)\n", fields); - return 0; - } - - val = avio_rl32(pb); /* flags */ - if (val & APE_TAG_FLAG_IS_HEADER) { - av_log(s, AV_LOG_ERROR, "APE Tag is a header\n"); - return 0; - } - - avio_seek(pb, file_size - tag_bytes, SEEK_SET); - - for (i=0; i - * based upon libdemac from Dave Chapman. - * - * 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 AVFORMAT_APETAG_H -#define AVFORMAT_APETAG_H - -#include "avformat.h" - -#define APE_TAG_PREAMBLE "APETAGEX" -#define APE_TAG_VERSION 2000 -#define APE_TAG_FOOTER_BYTES 32 - -/** - * Read and parse an APE tag - * - * @return offset of the tag start in the file - */ -int64_t ff_ape_parse_tag(AVFormatContext *s); - -/** - * Write an APEv2 tag - */ -void ff_ape_write(AVFormatContext *s); - -#endif /* AVFORMAT_APETAG_H */ diff --git a/ffmpeg1/libavformat/apetagenc.c b/ffmpeg1/libavformat/apetagenc.c deleted file mode 100644 index 42f5836..0000000 --- a/ffmpeg1/libavformat/apetagenc.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * APE tag writer - * Copyright (c) 2012 Paul B Mahol - * - * 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 "libavutil/dict.h" -#include "avio_internal.h" -#include "avformat.h" -#include "apetag.h" - -static int string_is_ascii(const uint8_t *str) -{ - while (*str && *str >= 0x20 && *str <= 0x7e ) str++; - return !*str; -} - -void ff_ape_write(AVFormatContext *s) -{ - int64_t tag_bytes; - AVDictionaryEntry *t = NULL; - AVIOContext *pb = s->pb; - int tags = 0, vlen; - - tag_bytes = avio_tell(s->pb); - while ((t = av_dict_get(s->metadata, "", t, AV_DICT_IGNORE_SUFFIX))) { - if (!string_is_ascii(t->key)) { - av_log(s, AV_LOG_WARNING, "Non ASCII keys are not allowed\n"); - continue; - } - - vlen = strlen(t->value); - avio_wl32(pb, vlen + 1); - avio_wl32(pb, 0); // flags - avio_put_str(pb, t->key); - avio_put_str(pb, t->value); - tags++; - } - tag_bytes = avio_tell(s->pb) - tag_bytes; - - if (!tags) - return; - - avio_write(pb, APE_TAG_PREAMBLE, 8); - avio_wl32(pb, APE_TAG_VERSION); - avio_wl32(pb, tag_bytes + APE_TAG_FOOTER_BYTES); - avio_wl32(pb, tags); // item count - avio_wl32(pb, 0); // global flags - ffio_fill(pb, 0, 8); // reserved -} diff --git a/ffmpeg1/libavformat/aqtitledec.c b/ffmpeg1/libavformat/aqtitledec.c deleted file mode 100644 index 325946c..0000000 --- a/ffmpeg1/libavformat/aqtitledec.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (c) 2012 Clément BÅ“sch - * - * 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 - */ - -/** - * @file - * AQTitle subtitles format demuxer - * - * @see http://web.archive.org/web/20070210095721/http://www.volny.cz/aberka/czech/aqt.html - * @see https://trac.annodex.net/wiki/AQTitle - */ - -#include "avformat.h" -#include "internal.h" -#include "subtitles.h" -#include "libavutil/opt.h" - -typedef struct { - const AVClass *class; - FFDemuxSubtitlesQueue q; - AVRational frame_rate; -} AQTitleContext; - -static int aqt_probe(AVProbeData *p) -{ - int frame; - const char *ptr = p->buf; - - if (sscanf(ptr, "-->> %d", &frame) == 1) - return AVPROBE_SCORE_MAX / 2; - return 0; -} - -static int aqt_read_header(AVFormatContext *s) -{ - AQTitleContext *aqt = s->priv_data; - AVStream *st = avformat_new_stream(s, NULL); - int new_event = 1; - int64_t pos = 0, frame = AV_NOPTS_VALUE; - AVPacket *sub = NULL; - - if (!st) - return AVERROR(ENOMEM); - avpriv_set_pts_info(st, 64, aqt->frame_rate.den, aqt->frame_rate.num); - st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE; - st->codec->codec_id = AV_CODEC_ID_TEXT; - - while (!url_feof(s->pb)) { - char line[4096]; - int len = ff_get_line(s->pb, line, sizeof(line)); - - if (!len) - break; - - line[strcspn(line, "\r\n")] = 0; - - if (sscanf(line, "-->> %"PRId64, &frame) == 1) { - new_event = 1; - pos = avio_tell(s->pb); - if (sub) { - sub->duration = frame - sub->pts; - sub = NULL; - } - } else if (*line) { - if (!new_event) { - sub = ff_subtitles_queue_insert(&aqt->q, "\n", 1, 1); - if (!sub) - return AVERROR(ENOMEM); - } - sub = ff_subtitles_queue_insert(&aqt->q, line, strlen(line), !new_event); - if (!sub) - return AVERROR(ENOMEM); - if (new_event) { - sub->pts = frame; - sub->duration = -1; - sub->pos = pos; - } - new_event = 0; - } - } - - ff_subtitles_queue_finalize(&aqt->q); - return 0; -} - -static int aqt_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - AQTitleContext *aqt = s->priv_data; - return ff_subtitles_queue_read_packet(&aqt->q, pkt); -} - -static int aqt_read_seek(AVFormatContext *s, int stream_index, - int64_t min_ts, int64_t ts, int64_t max_ts, int flags) -{ - AQTitleContext *aqt = s->priv_data; - return ff_subtitles_queue_seek(&aqt->q, s, stream_index, - min_ts, ts, max_ts, flags); -} - -static int aqt_read_close(AVFormatContext *s) -{ - AQTitleContext *aqt = s->priv_data; - ff_subtitles_queue_clean(&aqt->q); - return 0; -} - -#define OFFSET(x) offsetof(AQTitleContext, x) -#define SD AV_OPT_FLAG_SUBTITLE_PARAM|AV_OPT_FLAG_DECODING_PARAM -static const AVOption aqt_options[] = { - { "subfps", "set the movie frame rate", OFFSET(frame_rate), AV_OPT_TYPE_RATIONAL, {.dbl=25}, 0, INT_MAX, SD }, - { NULL } -}; - -static const AVClass aqt_class = { - .class_name = "aqtdec", - .item_name = av_default_item_name, - .option = aqt_options, - .version = LIBAVUTIL_VERSION_INT, -}; - -AVInputFormat ff_aqtitle_demuxer = { - .name = "aqtitle", - .long_name = NULL_IF_CONFIG_SMALL("AQTitle subtitles"), - .priv_data_size = sizeof(AQTitleContext), - .read_probe = aqt_probe, - .read_header = aqt_read_header, - .read_packet = aqt_read_packet, - .read_seek2 = aqt_read_seek, - .read_close = aqt_read_close, - .extensions = "aqt", - .priv_class = &aqt_class, -}; diff --git a/ffmpeg1/libavformat/asf.c b/ffmpeg1/libavformat/asf.c deleted file mode 100644 index dd64a3f..0000000 --- a/ffmpeg1/libavformat/asf.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (c) 2000, 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 - */ - -#include "asf.h" - -const ff_asf_guid ff_asf_header = { - 0x30, 0x26, 0xB2, 0x75, 0x8E, 0x66, 0xCF, 0x11, 0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C -}; - -const ff_asf_guid ff_asf_file_header = { - 0xA1, 0xDC, 0xAB, 0x8C, 0x47, 0xA9, 0xCF, 0x11, 0x8E, 0xE4, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65 -}; - -const ff_asf_guid ff_asf_stream_header = { - 0x91, 0x07, 0xDC, 0xB7, 0xB7, 0xA9, 0xCF, 0x11, 0x8E, 0xE6, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65 -}; - -const ff_asf_guid ff_asf_ext_stream_header = { - 0xCB, 0xA5, 0xE6, 0x14, 0x72, 0xC6, 0x32, 0x43, 0x83, 0x99, 0xA9, 0x69, 0x52, 0x06, 0x5B, 0x5A -}; - -const ff_asf_guid ff_asf_audio_stream = { - 0x40, 0x9E, 0x69, 0xF8, 0x4D, 0x5B, 0xCF, 0x11, 0xA8, 0xFD, 0x00, 0x80, 0x5F, 0x5C, 0x44, 0x2B -}; - -const ff_asf_guid ff_asf_audio_conceal_none = { - // 0x40, 0xa4, 0xf1, 0x49, 0x4ece, 0x11d0, 0xa3, 0xac, 0x00, 0xa0, 0xc9, 0x03, 0x48, 0xf6 - // New value lifted from avifile - 0x00, 0x57, 0xfb, 0x20, 0x55, 0x5B, 0xCF, 0x11, 0xa8, 0xfd, 0x00, 0x80, 0x5f, 0x5c, 0x44, 0x2b -}; - -const ff_asf_guid ff_asf_audio_conceal_spread = { - 0x50, 0xCD, 0xC3, 0xBF, 0x8F, 0x61, 0xCF, 0x11, 0x8B, 0xB2, 0x00, 0xAA, 0x00, 0xB4, 0xE2, 0x20 -}; - -const ff_asf_guid ff_asf_video_stream = { - 0xC0, 0xEF, 0x19, 0xBC, 0x4D, 0x5B, 0xCF, 0x11, 0xA8, 0xFD, 0x00, 0x80, 0x5F, 0x5C, 0x44, 0x2B -}; - -const ff_asf_guid ff_asf_jfif_media = { - 0x00, 0xE1, 0x1B, 0xB6, 0x4E, 0x5B, 0xCF, 0x11, 0xA8, 0xFD, 0x00, 0x80, 0x5F, 0x5C, 0x44, 0x2B -}; - -const ff_asf_guid ff_asf_video_conceal_none = { - 0x00, 0x57, 0xFB, 0x20, 0x55, 0x5B, 0xCF, 0x11, 0xA8, 0xFD, 0x00, 0x80, 0x5F, 0x5C, 0x44, 0x2B -}; - -const ff_asf_guid ff_asf_command_stream = { - 0xC0, 0xCF, 0xDA, 0x59, 0xE6, 0x59, 0xD0, 0x11, 0xA3, 0xAC, 0x00, 0xA0, 0xC9, 0x03, 0x48, 0xF6 -}; - -const ff_asf_guid ff_asf_comment_header = { - 0x33, 0x26, 0xb2, 0x75, 0x8E, 0x66, 0xCF, 0x11, 0xa6, 0xd9, 0x00, 0xaa, 0x00, 0x62, 0xce, 0x6c -}; - -const ff_asf_guid ff_asf_codec_comment_header = { - 0x40, 0x52, 0xD1, 0x86, 0x1D, 0x31, 0xD0, 0x11, 0xA3, 0xA4, 0x00, 0xA0, 0xC9, 0x03, 0x48, 0xF6 -}; -const ff_asf_guid ff_asf_codec_comment1_header = { - 0x41, 0x52, 0xd1, 0x86, 0x1D, 0x31, 0xD0, 0x11, 0xa3, 0xa4, 0x00, 0xa0, 0xc9, 0x03, 0x48, 0xf6 -}; - -const ff_asf_guid ff_asf_data_header = { - 0x36, 0x26, 0xb2, 0x75, 0x8E, 0x66, 0xCF, 0x11, 0xa6, 0xd9, 0x00, 0xaa, 0x00, 0x62, 0xce, 0x6c -}; - -const ff_asf_guid ff_asf_head1_guid = { - 0xb5, 0x03, 0xbf, 0x5f, 0x2E, 0xA9, 0xCF, 0x11, 0x8e, 0xe3, 0x00, 0xc0, 0x0c, 0x20, 0x53, 0x65 -}; - -const ff_asf_guid ff_asf_head2_guid = { - 0x11, 0xd2, 0xd3, 0xab, 0xBA, 0xA9, 0xCF, 0x11, 0x8e, 0xe6, 0x00, 0xc0, 0x0c, 0x20, 0x53, 0x65 -}; - -const ff_asf_guid ff_asf_extended_content_header = { - 0x40, 0xA4, 0xD0, 0xD2, 0x07, 0xE3, 0xD2, 0x11, 0x97, 0xF0, 0x00, 0xA0, 0xC9, 0x5E, 0xA8, 0x50 -}; - -const ff_asf_guid ff_asf_simple_index_header = { - 0x90, 0x08, 0x00, 0x33, 0xB1, 0xE5, 0xCF, 0x11, 0x89, 0xF4, 0x00, 0xA0, 0xC9, 0x03, 0x49, 0xCB -}; - -const ff_asf_guid ff_asf_ext_stream_embed_stream_header = { - 0xe2, 0x65, 0xfb, 0x3a, 0xEF, 0x47, 0xF2, 0x40, 0xac, 0x2c, 0x70, 0xa9, 0x0d, 0x71, 0xd3, 0x43 -}; - -const ff_asf_guid ff_asf_ext_stream_audio_stream = { - 0x9d, 0x8c, 0x17, 0x31, 0xE1, 0x03, 0x28, 0x45, 0xb5, 0x82, 0x3d, 0xf9, 0xdb, 0x22, 0xf5, 0x03 -}; - -const ff_asf_guid ff_asf_metadata_header = { - 0xea, 0xcb, 0xf8, 0xc5, 0xaf, 0x5b, 0x77, 0x48, 0x84, 0x67, 0xaa, 0x8c, 0x44, 0xfa, 0x4c, 0xca -}; - -const ff_asf_guid ff_asf_metadata_library_header = { - 0x94, 0x1c, 0x23, 0x44, 0x98, 0x94, 0xd1, 0x49, 0xa1, 0x41, 0x1d, 0x13, 0x4e, 0x45, 0x70, 0x54 -}; - -const ff_asf_guid ff_asf_marker_header = { - 0x01, 0xCD, 0x87, 0xF4, 0x51, 0xA9, 0xCF, 0x11, 0x8E, 0xE6, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65 -}; - -/* I am not a number !!! This GUID is the one found on the PC used to - * generate the stream */ -const ff_asf_guid ff_asf_my_guid = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -const ff_asf_guid ff_asf_language_guid = { - 0xa9, 0x46, 0x43, 0x7c, 0xe0, 0xef, 0xfc, 0x4b, 0xb2, 0x29, 0x39, 0x3e, 0xde, 0x41, 0x5c, 0x85 -}; - -const ff_asf_guid ff_asf_content_encryption = { - 0xfb, 0xb3, 0x11, 0x22, 0x23, 0xbd, 0xd2, 0x11, 0xb4, 0xb7, 0x00, 0xa0, 0xc9, 0x55, 0xfc, 0x6e -}; - -const ff_asf_guid ff_asf_ext_content_encryption = { - 0x14, 0xe6, 0x8a, 0x29, 0x22, 0x26, 0x17, 0x4c, 0xb9, 0x35, 0xda, 0xe0, 0x7e, 0xe9, 0x28, 0x9c -}; - -const ff_asf_guid ff_asf_digital_signature = { - 0xfc, 0xb3, 0x11, 0x22, 0x23, 0xbd, 0xd2, 0x11, 0xb4, 0xb7, 0x00, 0xa0, 0xc9, 0x55, 0xfc, 0x6e -}; - -/* List of official tags at http://msdn.microsoft.com/en-us/library/dd743066(VS.85).aspx */ -const AVMetadataConv ff_asf_metadata_conv[] = { - { "WM/AlbumArtist", "album_artist" }, - { "WM/AlbumTitle", "album" }, - { "Author", "artist" }, - { "Description", "comment" }, - { "WM/Composer", "composer" }, - { "WM/EncodedBy", "encoded_by" }, - { "WM/EncodingSettings", "encoder" }, - { "WM/Genre", "genre" }, - { "WM/Language", "language" }, - { "WM/OriginalFilename", "filename" }, - { "WM/PartOfSet", "disc" }, - { "WM/Publisher", "publisher" }, - { "WM/Tool", "encoder" }, - { "WM/TrackNumber", "track" }, - { "WM/MediaStationCallSign", "service_provider" }, - { "WM/MediaStationName", "service_name" }, -// { "Year" , "date" }, TODO: conversion year<->date - { 0 } -}; diff --git a/ffmpeg1/libavformat/asf.h b/ffmpeg1/libavformat/asf.h deleted file mode 100644 index 5ffc746..0000000 --- a/ffmpeg1/libavformat/asf.h +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright (c) 2000, 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 AVFORMAT_ASF_H -#define AVFORMAT_ASF_H - -#include -#include "avformat.h" -#include "metadata.h" -#include "riff.h" - -#define PACKET_SIZE 3200 - -typedef struct ASFPayload { - uint8_t type; - uint16_t size; -} ASFPayload; - -typedef struct ASFStream { - int num; - unsigned char seq; - /* use for reading */ - AVPacket pkt; - int frag_offset; - int timestamp; - int64_t duration; - - int ds_span; /* descrambling */ - int ds_packet_size; - int ds_chunk_size; - - int64_t packet_pos; - - uint16_t stream_language_index; - - int palette_changed; - uint32_t palette[256]; - - int payload_ext_ct; - ASFPayload payload[8]; -} ASFStream; - -typedef struct ASFMainHeader { - ff_asf_guid guid; ///< generated by client computer - uint64_t file_size; /**< in bytes - * invalid if broadcasting */ - uint64_t create_time; /**< time of creation, in 100-nanosecond units since 1.1.1601 - * invalid if broadcasting */ - uint64_t play_time; /**< play time, in 100-nanosecond units - * invalid if broadcasting */ - uint64_t send_time; /**< time to send file, in 100-nanosecond units - * invalid if broadcasting (could be ignored) */ - uint32_t preroll; /**< timestamp of the first packet, in milliseconds - * if nonzero - subtract from time */ - uint32_t ignore; ///< preroll is 64bit - but let's just ignore it - uint32_t flags; /**< 0x01 - broadcast - * 0x02 - seekable - * rest is reserved should be 0 */ - uint32_t min_pktsize; /**< size of a data packet - * invalid if broadcasting */ - uint32_t max_pktsize; /**< shall be the same as for min_pktsize - * invalid if broadcasting */ - uint32_t max_bitrate; /**< bandwidth of stream in bps - * should be the sum of bitrates of the - * individual media streams */ -} ASFMainHeader; - - -typedef struct ASFIndex { - uint32_t packet_number; - uint16_t packet_count; -} ASFIndex; - -extern const ff_asf_guid ff_asf_header; -extern const ff_asf_guid ff_asf_file_header; -extern const ff_asf_guid ff_asf_stream_header; -extern const ff_asf_guid ff_asf_ext_stream_header; -extern const ff_asf_guid ff_asf_audio_stream; -extern const ff_asf_guid ff_asf_audio_conceal_none; -extern const ff_asf_guid ff_asf_audio_conceal_spread; -extern const ff_asf_guid ff_asf_video_stream; -extern const ff_asf_guid ff_asf_jfif_media; -extern const ff_asf_guid ff_asf_video_conceal_none; -extern const ff_asf_guid ff_asf_command_stream; -extern const ff_asf_guid ff_asf_comment_header; -extern const ff_asf_guid ff_asf_codec_comment_header; -extern const ff_asf_guid ff_asf_codec_comment1_header; -extern const ff_asf_guid ff_asf_data_header; -extern const ff_asf_guid ff_asf_head1_guid; -extern const ff_asf_guid ff_asf_head2_guid; -extern const ff_asf_guid ff_asf_extended_content_header; -extern const ff_asf_guid ff_asf_simple_index_header; -extern const ff_asf_guid ff_asf_ext_stream_embed_stream_header; -extern const ff_asf_guid ff_asf_ext_stream_audio_stream; -extern const ff_asf_guid ff_asf_metadata_header; -extern const ff_asf_guid ff_asf_metadata_library_header; -extern const ff_asf_guid ff_asf_marker_header; -extern const ff_asf_guid ff_asf_my_guid; -extern const ff_asf_guid ff_asf_language_guid; -extern const ff_asf_guid ff_asf_content_encryption; -extern const ff_asf_guid ff_asf_ext_content_encryption; -extern const ff_asf_guid ff_asf_digital_signature; - -extern const AVMetadataConv ff_asf_metadata_conv[]; - -#define ASF_PACKET_FLAG_ERROR_CORRECTION_PRESENT 0x80 //1000 0000 - - -// ASF data packet structure -// ========================= -// -// -// ----------------------------------- -// | Error Correction Data | Optional -// ----------------------------------- -// | Payload Parsing Information (PPI) | -// ----------------------------------- -// | Payload Data | -// ----------------------------------- -// | Padding Data | -// ----------------------------------- - - -// PPI_FLAG - Payload parsing information flags -#define ASF_PPI_FLAG_MULTIPLE_PAYLOADS_PRESENT 1 - -#define ASF_PPI_FLAG_SEQUENCE_FIELD_IS_BYTE 0x02 //0000 0010 -#define ASF_PPI_FLAG_SEQUENCE_FIELD_IS_WORD 0x04 //0000 0100 -#define ASF_PPI_FLAG_SEQUENCE_FIELD_IS_DWORD 0x06 //0000 0110 -#define ASF_PPI_MASK_SEQUENCE_FIELD_SIZE 0x06 //0000 0110 - -#define ASF_PPI_FLAG_PADDING_LENGTH_FIELD_IS_BYTE 0x08 //0000 1000 -#define ASF_PPI_FLAG_PADDING_LENGTH_FIELD_IS_WORD 0x10 //0001 0000 -#define ASF_PPI_FLAG_PADDING_LENGTH_FIELD_IS_DWORD 0x18 //0001 1000 -#define ASF_PPI_MASK_PADDING_LENGTH_FIELD_SIZE 0x18 //0001 1000 - -#define ASF_PPI_FLAG_PACKET_LENGTH_FIELD_IS_BYTE 0x20 //0010 0000 -#define ASF_PPI_FLAG_PACKET_LENGTH_FIELD_IS_WORD 0x40 //0100 0000 -#define ASF_PPI_FLAG_PACKET_LENGTH_FIELD_IS_DWORD 0x60 //0110 0000 -#define ASF_PPI_MASK_PACKET_LENGTH_FIELD_SIZE 0x60 //0110 0000 - -// PL_FLAG - Payload flags -#define ASF_PL_FLAG_REPLICATED_DATA_LENGTH_FIELD_IS_BYTE 0x01 //0000 0001 -#define ASF_PL_FLAG_REPLICATED_DATA_LENGTH_FIELD_IS_WORD 0x02 //0000 0010 -#define ASF_PL_FLAG_REPLICATED_DATA_LENGTH_FIELD_IS_DWORD 0x03 //0000 0011 -#define ASF_PL_MASK_REPLICATED_DATA_LENGTH_FIELD_SIZE 0x03 //0000 0011 - -#define ASF_PL_FLAG_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_IS_BYTE 0x04 //0000 0100 -#define ASF_PL_FLAG_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_IS_WORD 0x08 //0000 1000 -#define ASF_PL_FLAG_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_IS_DWORD 0x0c //0000 1100 -#define ASF_PL_MASK_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_SIZE 0x0c //0000 1100 - -#define ASF_PL_FLAG_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_IS_BYTE 0x10 //0001 0000 -#define ASF_PL_FLAG_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_IS_WORD 0x20 //0010 0000 -#define ASF_PL_FLAG_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_IS_DWORD 0x30 //0011 0000 -#define ASF_PL_MASK_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_SIZE 0x30 //0011 0000 - -#define ASF_PL_FLAG_STREAM_NUMBER_LENGTH_FIELD_IS_BYTE 0x40 //0100 0000 -#define ASF_PL_MASK_STREAM_NUMBER_LENGTH_FIELD_SIZE 0xc0 //1100 0000 - -#define ASF_PL_FLAG_PAYLOAD_LENGTH_FIELD_IS_BYTE 0x40 //0100 0000 -#define ASF_PL_FLAG_PAYLOAD_LENGTH_FIELD_IS_WORD 0x80 //1000 0000 -#define ASF_PL_MASK_PAYLOAD_LENGTH_FIELD_SIZE 0xc0 //1100 0000 - -#define ASF_PL_FLAG_KEY_FRAME 0x80 //1000 0000 - -extern AVInputFormat ff_asf_demuxer; - -void ff_put_guid(AVIOContext *s, const ff_asf_guid *g); - -#endif /* AVFORMAT_ASF_H */ diff --git a/ffmpeg1/libavformat/asfcrypt.c b/ffmpeg1/libavformat/asfcrypt.c deleted file mode 100644 index a402758..0000000 --- a/ffmpeg1/libavformat/asfcrypt.c +++ /dev/null @@ -1,185 +0,0 @@ -/* - * ASF decryption - * Copyright (c) 2007 Reimar Doeffinger - * This is a rewrite of code contained in freeme/freeme2 - * - * 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 "libavutil/bswap.h" -#include "libavutil/common.h" -#include "libavutil/des.h" -#include "libavutil/intreadwrite.h" -#include "libavutil/rc4.h" -#include "asfcrypt.h" - -/** - * @brief find multiplicative inverse modulo 2 ^ 32 - * @param v number to invert, must be odd! - * @return number so that result * v = 1 (mod 2^32) - */ -static uint32_t inverse(uint32_t v) -{ - // v ^ 3 gives the inverse (mod 16), could also be implemented - // as table etc. (only lowest 4 bits matter!) - uint32_t inverse = v * v * v; - // uses a fixpoint-iteration that doubles the number - // of correct lowest bits each time - inverse *= 2 - v * inverse; - inverse *= 2 - v * inverse; - inverse *= 2 - v * inverse; - return inverse; -} - -/** - * @brief read keys from keybuf into keys - * @param keybuf buffer containing the keys - * @param keys output key array containing the keys for encryption in - * native endianness - */ -static void multiswap_init(const uint8_t keybuf[48], uint32_t keys[12]) -{ - int i; - for (i = 0; i < 12; i++) - keys[i] = AV_RL32(keybuf + (i << 2)) | 1; -} - -/** - * @brief invert the keys so that encryption become decryption keys and - * the other way round. - * @param keys key array of ints to invert - */ -static void multiswap_invert_keys(uint32_t keys[12]) -{ - int i; - for (i = 0; i < 5; i++) - keys[i] = inverse(keys[i]); - for (i = 6; i < 11; i++) - keys[i] = inverse(keys[i]); -} - -static uint32_t multiswap_step(const uint32_t keys[12], uint32_t v) -{ - int i; - v *= keys[0]; - for (i = 1; i < 5; i++) { - v = (v >> 16) | (v << 16); - v *= keys[i]; - } - v += keys[5]; - return v; -} - -static uint32_t multiswap_inv_step(const uint32_t keys[12], uint32_t v) -{ - int i; - v -= keys[5]; - for (i = 4; i > 0; i--) { - v *= keys[i]; - v = (v >> 16) | (v << 16); - } - v *= keys[0]; - return v; -} - -/** - * @brief "MultiSwap" encryption - * @param keys 32 bit numbers in machine endianness, - * 0-4 and 6-10 must be inverted from decryption - * @param key another key, this one must be the same for the decryption - * @param data data to encrypt - * @return encrypted data - */ -static uint64_t multiswap_enc(const uint32_t keys[12], - uint64_t key, uint64_t data) -{ - uint32_t a = data; - uint32_t b = data >> 32; - uint32_t c; - uint32_t tmp; - a += key; - tmp = multiswap_step(keys, a); - b += tmp; - c = (key >> 32) + tmp; - tmp = multiswap_step(keys + 6, b); - c += tmp; - return ((uint64_t)c << 32) | tmp; -} - -/** - * @brief "MultiSwap" decryption - * @param keys 32 bit numbers in machine endianness, - * 0-4 and 6-10 must be inverted from encryption - * @param key another key, this one must be the same as for the encryption - * @param data data to decrypt - * @return decrypted data - */ -static uint64_t multiswap_dec(const uint32_t keys[12], - uint64_t key, uint64_t data) -{ - uint32_t a; - uint32_t b; - uint32_t c = data >> 32; - uint32_t tmp = data; - c -= tmp; - b = multiswap_inv_step(keys + 6, tmp); - tmp = c - (key >> 32); - b -= tmp; - a = multiswap_inv_step(keys, tmp); - a -= key; - return ((uint64_t)b << 32) | a; -} - -void ff_asfcrypt_dec(const uint8_t key[20], uint8_t *data, int len) -{ - struct AVDES des; - struct AVRC4 rc4; - int num_qwords = len >> 3; - uint8_t *qwords = data; - uint64_t rc4buff[8] = { 0 }; - uint64_t packetkey; - uint32_t ms_keys[12]; - uint64_t ms_state; - int i; - if (len < 16) { - for (i = 0; i < len; i++) - data[i] ^= key[i]; - return; - } - - av_rc4_init(&rc4, key, 12 * 8, 1); - av_rc4_crypt(&rc4, (uint8_t *)rc4buff, NULL, sizeof(rc4buff), NULL, 1); - multiswap_init((uint8_t *)rc4buff, ms_keys); - - packetkey = AV_RN64(&qwords[num_qwords * 8 - 8]); - packetkey ^= rc4buff[7]; - av_des_init(&des, key + 12, 64, 1); - av_des_crypt(&des, (uint8_t *)&packetkey, (uint8_t *)&packetkey, 1, NULL, 1); - packetkey ^= rc4buff[6]; - - av_rc4_init(&rc4, (uint8_t *)&packetkey, 64, 1); - av_rc4_crypt(&rc4, data, data, len, NULL, 1); - - ms_state = 0; - for (i = 0; i < num_qwords - 1; i++, qwords += 8) - ms_state = multiswap_enc(ms_keys, ms_state, AV_RL64(qwords)); - multiswap_invert_keys(ms_keys); - packetkey = (packetkey << 32) | (packetkey >> 32); - packetkey = av_le2ne64(packetkey); - packetkey = multiswap_dec(ms_keys, ms_state, packetkey); - AV_WL64(qwords, packetkey); -} diff --git a/ffmpeg1/libavformat/asfcrypt.h b/ffmpeg1/libavformat/asfcrypt.h deleted file mode 100644 index 8b80d63..0000000 --- a/ffmpeg1/libavformat/asfcrypt.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * ASF decryption - * Copyright (c) 2007 Reimar Doeffinger - * - * 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 AVFORMAT_ASFCRYPT_H -#define AVFORMAT_ASFCRYPT_H - -#include - -void ff_asfcrypt_dec(const uint8_t key[20], uint8_t *data, int len); - -#endif /* AVFORMAT_ASFCRYPT_H */ diff --git a/ffmpeg1/libavformat/asfdec.c b/ffmpeg1/libavformat/asfdec.c deleted file mode 100644 index 1d7f26c..0000000 --- a/ffmpeg1/libavformat/asfdec.c +++ /dev/null @@ -1,1553 +0,0 @@ -/* - * ASF compatible demuxer - * Copyright (c) 2000, 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 - */ - -//#define DEBUG - -#include "libavutil/attributes.h" -#include "libavutil/avassert.h" -#include "libavutil/avstring.h" -#include "libavutil/bswap.h" -#include "libavutil/common.h" -#include "libavutil/dict.h" -#include "libavutil/mathematics.h" -#include "libavutil/opt.h" -#include "avformat.h" -#include "avio_internal.h" -#include "avlanguage.h" -#include "id3v2.h" -#include "internal.h" -#include "riff.h" -#include "asf.h" -#include "asfcrypt.h" - -typedef struct { - const AVClass *class; - int asfid2avid[128]; ///< conversion table from asf ID 2 AVStream ID - ASFStream streams[128]; ///< it's max number and it's not that big - uint32_t stream_bitrates[128]; ///< max number of streams, bitrate for each (for streaming) - AVRational dar[128]; - char stream_languages[128][6]; ///< max number of streams, language for each (RFC1766, e.g. en-US) - /* non streamed additonnal info */ - /* packet filling */ - int packet_size_left; - /* only for reading */ - uint64_t data_offset; ///< beginning of the first data packet - uint64_t data_object_offset; ///< data object offset (excl. GUID & size) - uint64_t data_object_size; ///< size of the data object - int index_read; - - ASFMainHeader hdr; - - int packet_flags; - int packet_property; - int packet_timestamp; - int packet_segsizetype; - int packet_segments; - int packet_seq; - int packet_replic_size; - int packet_key_frame; - int packet_padsize; - unsigned int packet_frag_offset; - unsigned int packet_frag_size; - int64_t packet_frag_timestamp; - int packet_multi_size; - int packet_obj_size; - int packet_time_delta; - int packet_time_start; - int64_t packet_pos; - - int stream_index; - - ASFStream *asf_st; ///< currently decoded stream - - int no_resync_search; -} ASFContext; - -static const AVOption options[] = { - { "no_resync_search", "Don't try to resynchronize by looking for a certain optional start code", offsetof(ASFContext, no_resync_search), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, AV_OPT_FLAG_DECODING_PARAM }, - { NULL }, -}; - -static const AVClass asf_class = { - .class_name = "asf demuxer", - .item_name = av_default_item_name, - .option = options, - .version = LIBAVUTIL_VERSION_INT, -}; - -#undef NDEBUG -#include - -#define ASF_MAX_STREAMS 127 -#define FRAME_HEADER_SIZE 16 -// Fix Me! FRAME_HEADER_SIZE may be different. (17 is known to be too large) - -#ifdef DEBUG -static const ff_asf_guid stream_bitrate_guid = { /* (http://get.to/sdp) */ - 0xce, 0x75, 0xf8, 0x7b, 0x8d, 0x46, 0xd1, 0x11, 0x8d, 0x82, 0x00, 0x60, 0x97, 0xc9, 0xa2, 0xb2 -}; - -#define PRINT_IF_GUID(g, cmp) \ - if (!ff_guidcmp(g, &cmp)) \ - av_dlog(NULL, "(GUID: %s) ", # cmp) - -static void print_guid(ff_asf_guid *g) -{ - int i; - PRINT_IF_GUID(g, ff_asf_header); - else PRINT_IF_GUID(g, ff_asf_file_header); - else PRINT_IF_GUID(g, ff_asf_stream_header); - else PRINT_IF_GUID(g, ff_asf_audio_stream); - else PRINT_IF_GUID(g, ff_asf_audio_conceal_none); - else PRINT_IF_GUID(g, ff_asf_video_stream); - else PRINT_IF_GUID(g, ff_asf_video_conceal_none); - else PRINT_IF_GUID(g, ff_asf_command_stream); - else PRINT_IF_GUID(g, ff_asf_comment_header); - else PRINT_IF_GUID(g, ff_asf_codec_comment_header); - else PRINT_IF_GUID(g, ff_asf_codec_comment1_header); - else PRINT_IF_GUID(g, ff_asf_data_header); - else PRINT_IF_GUID(g, ff_asf_simple_index_header); - else PRINT_IF_GUID(g, ff_asf_head1_guid); - else PRINT_IF_GUID(g, ff_asf_head2_guid); - else PRINT_IF_GUID(g, ff_asf_my_guid); - else PRINT_IF_GUID(g, ff_asf_ext_stream_header); - else PRINT_IF_GUID(g, ff_asf_extended_content_header); - else PRINT_IF_GUID(g, ff_asf_ext_stream_embed_stream_header); - else PRINT_IF_GUID(g, ff_asf_ext_stream_audio_stream); - else PRINT_IF_GUID(g, ff_asf_metadata_header); - else PRINT_IF_GUID(g, ff_asf_metadata_library_header); - else PRINT_IF_GUID(g, ff_asf_marker_header); - else PRINT_IF_GUID(g, stream_bitrate_guid); - else PRINT_IF_GUID(g, ff_asf_language_guid); - else - av_dlog(NULL, "(GUID: unknown) "); - for (i = 0; i < 16; i++) - av_dlog(NULL, " 0x%02x,", (*g)[i]); - av_dlog(NULL, "}\n"); -} -#undef PRINT_IF_GUID -#else -#define print_guid(g) -#endif - -static int asf_probe(AVProbeData *pd) -{ - /* check file header */ - if (!ff_guidcmp(pd->buf, &ff_asf_header)) - return AVPROBE_SCORE_MAX; - else - return 0; -} - -/* size of type 2 (BOOL) is 32bit for "Extended Content Description Object" - * but 16 bit for "Metadata Object" and "Metadata Library Object" */ -static int get_value(AVIOContext *pb, int type, int type2_size) -{ - switch (type) { - case 2: - return (type2_size == 32) ? avio_rl32(pb) : avio_rl16(pb); - case 3: - return avio_rl32(pb); - case 4: - return avio_rl64(pb); - case 5: - return avio_rl16(pb); - default: - return INT_MIN; - } -} - -/* MSDN claims that this should be "compatible with the ID3 frame, APIC", - * but in reality this is only loosely similar */ -static int asf_read_picture(AVFormatContext *s, int len) -{ - AVPacket pkt = { 0 }; - const CodecMime *mime = ff_id3v2_mime_tags; - enum AVCodecID id = AV_CODEC_ID_NONE; - char mimetype[64]; - uint8_t *desc = NULL; - AVStream *st = NULL; - int ret, type, picsize, desc_len; - - /* type + picsize + mime + desc */ - if (len < 1 + 4 + 2 + 2) { - av_log(s, AV_LOG_ERROR, "Invalid attached picture size: %d.\n", len); - return AVERROR_INVALIDDATA; - } - - /* picture type */ - type = avio_r8(s->pb); - len--; - if (type >= FF_ARRAY_ELEMS(ff_id3v2_picture_types) || type < 0) { - av_log(s, AV_LOG_WARNING, "Unknown attached picture type: %d.\n", type); - type = 0; - } - - /* picture data size */ - picsize = avio_rl32(s->pb); - len -= 4; - - /* picture MIME type */ - len -= avio_get_str16le(s->pb, len, mimetype, sizeof(mimetype)); - while (mime->id != AV_CODEC_ID_NONE) { - if (!strncmp(mime->str, mimetype, sizeof(mimetype))) { - id = mime->id; - break; - } - mime++; - } - if (id == AV_CODEC_ID_NONE) { - av_log(s, AV_LOG_ERROR, "Unknown attached picture mimetype: %s.\n", - mimetype); - return 0; - } - - if (picsize >= len) { - av_log(s, AV_LOG_ERROR, "Invalid attached picture data size: %d >= %d.\n", - picsize, len); - return AVERROR_INVALIDDATA; - } - - /* picture description */ - desc_len = (len - picsize) * 2 + 1; - desc = av_malloc(desc_len); - if (!desc) - return AVERROR(ENOMEM); - len -= avio_get_str16le(s->pb, len - picsize, desc, desc_len); - - ret = av_get_packet(s->pb, &pkt, picsize); - if (ret < 0) - goto fail; - - st = avformat_new_stream(s, NULL); - if (!st) { - ret = AVERROR(ENOMEM); - goto fail; - } - st->disposition |= AV_DISPOSITION_ATTACHED_PIC; - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = id; - st->attached_pic = pkt; - st->attached_pic.stream_index = st->index; - st->attached_pic.flags |= AV_PKT_FLAG_KEY; - - if (*desc) - av_dict_set(&st->metadata, "title", desc, AV_DICT_DONT_STRDUP_VAL); - else - av_freep(&desc); - - av_dict_set(&st->metadata, "comment", ff_id3v2_picture_types[type], 0); - - return 0; - -fail: - av_freep(&desc); - av_free_packet(&pkt); - return ret; -} - -static void get_id3_tag(AVFormatContext *s, int len) -{ - ID3v2ExtraMeta *id3v2_extra_meta = NULL; - - ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta); - if (id3v2_extra_meta) - ff_id3v2_parse_apic(s, &id3v2_extra_meta); - ff_id3v2_free_extra_meta(&id3v2_extra_meta); -} - -static void get_tag(AVFormatContext *s, const char *key, int type, int len, int type2_size) -{ - char *value; - int64_t off = avio_tell(s->pb); -#define LEN 22 - - if ((unsigned)len >= (UINT_MAX - LEN) / 2) - return; - - value = av_malloc(2 * len + LEN); - if (!value) - goto finish; - - if (type == 0) { // UTF16-LE - avio_get_str16le(s->pb, len, value, 2 * len + 1); - } else if (type == -1) { // ASCII - avio_read(s->pb, value, len); - value[len]=0; - } else if (type == 1) { // byte array - if (!strcmp(key, "WM/Picture")) { // handle cover art - asf_read_picture(s, len); - } else if (!strcmp(key, "ID3")) { // handle ID3 tag - get_id3_tag(s, len); - } else { - av_log(s, AV_LOG_VERBOSE, "Unsupported byte array in tag %s.\n", key); - } - goto finish; - } else if (type > 1 && type <= 5) { // boolean or DWORD or QWORD or WORD - uint64_t num = get_value(s->pb, type, type2_size); - snprintf(value, LEN, "%"PRIu64, num); - } else if (type == 6) { // (don't) handle GUID - av_log(s, AV_LOG_DEBUG, "Unsupported GUID value in tag %s.\n", key); - goto finish; - } else { - av_log(s, AV_LOG_DEBUG, - "Unsupported value type %d in tag %s.\n", type, key); - goto finish; - } - if (*value) - av_dict_set(&s->metadata, key, value, 0); - -finish: - av_freep(&value); - avio_seek(s->pb, off + len, SEEK_SET); -} - -static int asf_read_file_properties(AVFormatContext *s, int64_t size) -{ - ASFContext *asf = s->priv_data; - AVIOContext *pb = s->pb; - - ff_get_guid(pb, &asf->hdr.guid); - asf->hdr.file_size = avio_rl64(pb); - asf->hdr.create_time = avio_rl64(pb); - avio_rl64(pb); /* number of packets */ - asf->hdr.play_time = avio_rl64(pb); - asf->hdr.send_time = avio_rl64(pb); - asf->hdr.preroll = avio_rl32(pb); - asf->hdr.ignore = avio_rl32(pb); - asf->hdr.flags = avio_rl32(pb); - asf->hdr.min_pktsize = avio_rl32(pb); - asf->hdr.max_pktsize = avio_rl32(pb); - if (asf->hdr.min_pktsize >= (1U << 29)) - return AVERROR_INVALIDDATA; - asf->hdr.max_bitrate = avio_rl32(pb); - s->packet_size = asf->hdr.max_pktsize; - - return 0; -} - -static int asf_read_stream_properties(AVFormatContext *s, int64_t size) -{ - ASFContext *asf = s->priv_data; - AVIOContext *pb = s->pb; - AVStream *st; - ASFStream *asf_st; - ff_asf_guid g; - enum AVMediaType type; - int type_specific_size, sizeX; - unsigned int tag1; - int64_t pos1, pos2, start_time; - int test_for_ext_stream_audio, is_dvr_ms_audio = 0; - - if (s->nb_streams == ASF_MAX_STREAMS) { - av_log(s, AV_LOG_ERROR, "too many streams\n"); - return AVERROR(EINVAL); - } - - pos1 = avio_tell(pb); - - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - avpriv_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */ - asf_st = av_mallocz(sizeof(ASFStream)); - if (!asf_st) - return AVERROR(ENOMEM); - st->priv_data = asf_st; - start_time = asf->hdr.preroll; - - asf_st->stream_language_index = 128; // invalid stream index means no language info - - if (!(asf->hdr.flags & 0x01)) { // if we aren't streaming... - int64_t fsize = avio_size(pb); - if (fsize <= 0 || (int64_t)asf->hdr.file_size <= 0 || FFABS(fsize - (int64_t)asf->hdr.file_size) < 10000) - st->duration = asf->hdr.play_time / - (10000000 / 1000) - start_time; - } - ff_get_guid(pb, &g); - - test_for_ext_stream_audio = 0; - if (!ff_guidcmp(&g, &ff_asf_audio_stream)) { - type = AVMEDIA_TYPE_AUDIO; - } else if (!ff_guidcmp(&g, &ff_asf_video_stream)) { - type = AVMEDIA_TYPE_VIDEO; - } else if (!ff_guidcmp(&g, &ff_asf_jfif_media)) { - type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = AV_CODEC_ID_MJPEG; - } else if (!ff_guidcmp(&g, &ff_asf_command_stream)) { - type = AVMEDIA_TYPE_DATA; - } else if (!ff_guidcmp(&g, &ff_asf_ext_stream_embed_stream_header)) { - test_for_ext_stream_audio = 1; - type = AVMEDIA_TYPE_UNKNOWN; - } else { - return -1; - } - ff_get_guid(pb, &g); - avio_skip(pb, 8); /* total_size */ - type_specific_size = avio_rl32(pb); - avio_rl32(pb); - st->id = avio_rl16(pb) & 0x7f; /* stream id */ - // mapping of asf ID to AV stream ID; - asf->asfid2avid[st->id] = s->nb_streams - 1; - - avio_rl32(pb); - - if (test_for_ext_stream_audio) { - ff_get_guid(pb, &g); - if (!ff_guidcmp(&g, &ff_asf_ext_stream_audio_stream)) { - type = AVMEDIA_TYPE_AUDIO; - is_dvr_ms_audio = 1; - ff_get_guid(pb, &g); - avio_rl32(pb); - avio_rl32(pb); - avio_rl32(pb); - ff_get_guid(pb, &g); - avio_rl32(pb); - } - } - - st->codec->codec_type = type; - if (type == AVMEDIA_TYPE_AUDIO) { - int ret = ff_get_wav_header(pb, st->codec, type_specific_size); - if (ret < 0) - return ret; - if (is_dvr_ms_audio) { - // codec_id and codec_tag are unreliable in dvr_ms - // files. Set them later by probing stream. - st->request_probe = 1; - st->codec->codec_tag = 0; - } - if (st->codec->codec_id == AV_CODEC_ID_AAC) - st->need_parsing = AVSTREAM_PARSE_NONE; - else - st->need_parsing = AVSTREAM_PARSE_FULL; - /* We have to init the frame size at some point .... */ - pos2 = avio_tell(pb); - if (size >= (pos2 + 8 - pos1 + 24)) { - asf_st->ds_span = avio_r8(pb); - asf_st->ds_packet_size = avio_rl16(pb); - asf_st->ds_chunk_size = avio_rl16(pb); - avio_rl16(pb); // ds_data_size - avio_r8(pb); // ds_silence_data - } - if (asf_st->ds_span > 1) { - if (!asf_st->ds_chunk_size || - (asf_st->ds_packet_size / asf_st->ds_chunk_size <= 1) || - asf_st->ds_packet_size % asf_st->ds_chunk_size) - asf_st->ds_span = 0; // disable descrambling - } - } else if (type == AVMEDIA_TYPE_VIDEO && - size - (avio_tell(pb) - pos1 + 24) >= 51) { - avio_rl32(pb); - avio_rl32(pb); - avio_r8(pb); - avio_rl16(pb); /* size */ - sizeX = avio_rl32(pb); /* size */ - st->codec->width = avio_rl32(pb); - st->codec->height = avio_rl32(pb); - /* not available for asf */ - avio_rl16(pb); /* panes */ - st->codec->bits_per_coded_sample = avio_rl16(pb); /* depth */ - tag1 = avio_rl32(pb); - avio_skip(pb, 20); - if (sizeX > 40) { - st->codec->extradata_size = ffio_limit(pb, sizeX - 40); - st->codec->extradata = av_mallocz(st->codec->extradata_size + - FF_INPUT_BUFFER_PADDING_SIZE); - avio_read(pb, st->codec->extradata, st->codec->extradata_size); - } - - /* Extract palette from extradata if bpp <= 8 */ - /* This code assumes that extradata contains only palette */ - /* This is true for all paletted codecs implemented in libavcodec */ - if (st->codec->extradata_size && (st->codec->bits_per_coded_sample <= 8)) { -#if HAVE_BIGENDIAN - int i; - for (i = 0; i < FFMIN(st->codec->extradata_size, AVPALETTE_SIZE) / 4; i++) - asf_st->palette[i] = av_bswap32(((uint32_t *)st->codec->extradata)[i]); -#else - memcpy(asf_st->palette, st->codec->extradata, - FFMIN(st->codec->extradata_size, AVPALETTE_SIZE)); -#endif - asf_st->palette_changed = 1; - } - - st->codec->codec_tag = tag1; - st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, tag1); - if (tag1 == MKTAG('D', 'V', 'R', ' ')) { - st->need_parsing = AVSTREAM_PARSE_FULL; - /* issue658 contains wrong w/h and MS even puts a fake seq header - * with wrong w/h in extradata while a correct one is in the stream. - * maximum lameness */ - st->codec->width = - st->codec->height = 0; - av_freep(&st->codec->extradata); - st->codec->extradata_size = 0; - } - if (st->codec->codec_id == AV_CODEC_ID_H264) - st->need_parsing = AVSTREAM_PARSE_FULL_ONCE; - } - pos2 = avio_tell(pb); - avio_skip(pb, size - (pos2 - pos1 + 24)); - - return 0; -} - -static int asf_read_ext_stream_properties(AVFormatContext *s, int64_t size) -{ - ASFContext *asf = s->priv_data; - AVIOContext *pb = s->pb; - ff_asf_guid g; - int ext_len, payload_ext_ct, stream_ct, i; - uint32_t leak_rate, stream_num; - unsigned int stream_languageid_index; - - avio_rl64(pb); // starttime - avio_rl64(pb); // endtime - leak_rate = avio_rl32(pb); // leak-datarate - avio_rl32(pb); // bucket-datasize - avio_rl32(pb); // init-bucket-fullness - avio_rl32(pb); // alt-leak-datarate - avio_rl32(pb); // alt-bucket-datasize - avio_rl32(pb); // alt-init-bucket-fullness - avio_rl32(pb); // max-object-size - avio_rl32(pb); // flags (reliable,seekable,no_cleanpoints?,resend-live-cleanpoints, rest of bits reserved) - stream_num = avio_rl16(pb); // stream-num - - stream_languageid_index = avio_rl16(pb); // stream-language-id-index - if (stream_num < 128) - asf->streams[stream_num].stream_language_index = stream_languageid_index; - - avio_rl64(pb); // avg frametime in 100ns units - stream_ct = avio_rl16(pb); // stream-name-count - payload_ext_ct = avio_rl16(pb); // payload-extension-system-count - - if (stream_num < 128) { - asf->stream_bitrates[stream_num] = leak_rate; - asf->streams[stream_num].payload_ext_ct = 0; - } - - for (i = 0; i < stream_ct; i++) { - avio_rl16(pb); - ext_len = avio_rl16(pb); - avio_skip(pb, ext_len); - } - - for (i = 0; i < payload_ext_ct; i++) { - int size; - ff_get_guid(pb, &g); - size = avio_rl16(pb); - ext_len = avio_rl32(pb); - avio_skip(pb, ext_len); - if (stream_num < 128 && i < FF_ARRAY_ELEMS(asf->streams[stream_num].payload)) { - ASFPayload *p = &asf->streams[stream_num].payload[i]; - p->type = g[0]; - p->size = size; - av_log(s, AV_LOG_DEBUG, "Payload extension %x %d\n", g[0], p->size ); - asf->streams[stream_num].payload_ext_ct ++; - } - } - - return 0; -} - -static int asf_read_content_desc(AVFormatContext *s, int64_t size) -{ - AVIOContext *pb = s->pb; - int len1, len2, len3, len4, len5; - - len1 = avio_rl16(pb); - len2 = avio_rl16(pb); - len3 = avio_rl16(pb); - len4 = avio_rl16(pb); - len5 = avio_rl16(pb); - get_tag(s, "title", 0, len1, 32); - get_tag(s, "author", 0, len2, 32); - get_tag(s, "copyright", 0, len3, 32); - get_tag(s, "comment", 0, len4, 32); - avio_skip(pb, len5); - - return 0; -} - -static int asf_read_ext_content_desc(AVFormatContext *s, int64_t size) -{ - AVIOContext *pb = s->pb; - ASFContext *asf = s->priv_data; - int desc_count, i, ret; - - desc_count = avio_rl16(pb); - for (i = 0; i < desc_count; i++) { - int name_len, value_type, value_len; - char name[1024]; - - name_len = avio_rl16(pb); - if (name_len % 2) // must be even, broken lavf versions wrote len-1 - name_len += 1; - if ((ret = avio_get_str16le(pb, name_len, name, sizeof(name))) < name_len) - avio_skip(pb, name_len - ret); - value_type = avio_rl16(pb); - value_len = avio_rl16(pb); - if (!value_type && value_len % 2) - value_len += 1; - /* My sample has that stream set to 0 maybe that mean the container. - * ASF stream count starts at 1. I am using 0 to the container value - * since it's unused. */ - if (!strcmp(name, "AspectRatioX")) - asf->dar[0].num = get_value(s->pb, value_type, 32); - else if (!strcmp(name, "AspectRatioY")) - asf->dar[0].den = get_value(s->pb, value_type, 32); - else - get_tag(s, name, value_type, value_len, 32); - } - - return 0; -} - -static int asf_read_language_list(AVFormatContext *s, int64_t size) -{ - AVIOContext *pb = s->pb; - ASFContext *asf = s->priv_data; - int j, ret; - int stream_count = avio_rl16(pb); - for (j = 0; j < stream_count; j++) { - char lang[6]; - unsigned int lang_len = avio_r8(pb); - if ((ret = avio_get_str16le(pb, lang_len, lang, - sizeof(lang))) < lang_len) - avio_skip(pb, lang_len - ret); - if (j < 128) - av_strlcpy(asf->stream_languages[j], lang, - sizeof(*asf->stream_languages)); - } - - return 0; -} - -static int asf_read_metadata(AVFormatContext *s, int64_t size) -{ - AVIOContext *pb = s->pb; - ASFContext *asf = s->priv_data; - int n, stream_num, name_len, value_len; - int ret, i; - n = avio_rl16(pb); - - for (i = 0; i < n; i++) { - char name[1024]; - int value_type; - - avio_rl16(pb); // lang_list_index - stream_num = avio_rl16(pb); - name_len = avio_rl16(pb); - value_type = avio_rl16(pb); /* value_type */ - value_len = avio_rl32(pb); - - if ((ret = avio_get_str16le(pb, name_len, name, sizeof(name))) < name_len) - avio_skip(pb, name_len - ret); - av_dlog(s, "%d stream %d name_len %2d type %d len %4d <%s>\n", - i, stream_num, name_len, value_type, value_len, name); - - if (!strcmp(name, "AspectRatioX")){ - int aspect_x = get_value(s->pb, value_type, 16); - if(stream_num < 128) - asf->dar[stream_num].num = aspect_x; - } else if(!strcmp(name, "AspectRatioY")){ - int aspect_y = get_value(s->pb, value_type, 16); - if(stream_num < 128) - asf->dar[stream_num].den = aspect_y; - } else { - get_tag(s, name, value_type, value_len, 16); - } - } - - return 0; -} - -static int asf_read_marker(AVFormatContext *s, int64_t size) -{ - AVIOContext *pb = s->pb; - int i, count, name_len, ret; - char name[1024]; - - avio_rl64(pb); // reserved 16 bytes - avio_rl64(pb); // ... - count = avio_rl32(pb); // markers count - avio_rl16(pb); // reserved 2 bytes - name_len = avio_rl16(pb); // name length - for (i = 0; i < name_len; i++) - avio_r8(pb); // skip the name - - for (i = 0; i < count; i++) { - int64_t pres_time; - int name_len; - - avio_rl64(pb); // offset, 8 bytes - pres_time = avio_rl64(pb); // presentation time - avio_rl16(pb); // entry length - avio_rl32(pb); // send time - avio_rl32(pb); // flags - name_len = avio_rl32(pb); // name length - if ((ret = avio_get_str16le(pb, name_len * 2, name, - sizeof(name))) < name_len) - avio_skip(pb, name_len - ret); - avpriv_new_chapter(s, i, (AVRational) { 1, 10000000 }, pres_time, - AV_NOPTS_VALUE, name); - } - - return 0; -} - -static int asf_read_header(AVFormatContext *s) -{ - ASFContext *asf = s->priv_data; - ff_asf_guid g; - AVIOContext *pb = s->pb; - int i; - int64_t gsize; - - ff_get_guid(pb, &g); - if (ff_guidcmp(&g, &ff_asf_header)) - return AVERROR_INVALIDDATA; - avio_rl64(pb); - avio_rl32(pb); - avio_r8(pb); - avio_r8(pb); - memset(&asf->asfid2avid, -1, sizeof(asf->asfid2avid)); - for (;;) { - uint64_t gpos = avio_tell(pb); - ff_get_guid(pb, &g); - gsize = avio_rl64(pb); - print_guid(&g); - if (!ff_guidcmp(&g, &ff_asf_data_header)) { - asf->data_object_offset = avio_tell(pb); - /* If not streaming, gsize is not unlimited (how?), - * and there is enough space in the file.. */ - if (!(asf->hdr.flags & 0x01) && gsize >= 100) - asf->data_object_size = gsize - 24; - else - asf->data_object_size = (uint64_t)-1; - break; - } - if (gsize < 24) - return AVERROR_INVALIDDATA; - if (!ff_guidcmp(&g, &ff_asf_file_header)) { - int ret = asf_read_file_properties(s, gsize); - if (ret < 0) - return ret; - } else if (!ff_guidcmp(&g, &ff_asf_stream_header)) { - asf_read_stream_properties(s, gsize); - } else if (!ff_guidcmp(&g, &ff_asf_comment_header)) { - asf_read_content_desc(s, gsize); - } else if (!ff_guidcmp(&g, &ff_asf_language_guid)) { - asf_read_language_list(s, gsize); - } else if (!ff_guidcmp(&g, &ff_asf_extended_content_header)) { - asf_read_ext_content_desc(s, gsize); - } else if (!ff_guidcmp(&g, &ff_asf_metadata_header)) { - asf_read_metadata(s, gsize); - } else if (!ff_guidcmp(&g, &ff_asf_metadata_library_header)) { - asf_read_metadata(s, gsize); - } else if (!ff_guidcmp(&g, &ff_asf_ext_stream_header)) { - asf_read_ext_stream_properties(s, gsize); - - // there could be a optional stream properties object to follow - // if so the next iteration will pick it up - continue; - } else if (!ff_guidcmp(&g, &ff_asf_head1_guid)) { - ff_get_guid(pb, &g); - avio_skip(pb, 6); - continue; - } else if (!ff_guidcmp(&g, &ff_asf_marker_header)) { - asf_read_marker(s, gsize); - } else if (url_feof(pb)) { - return AVERROR_EOF; - } else { - if (!s->keylen) { - if (!ff_guidcmp(&g, &ff_asf_content_encryption)) { - unsigned int len; - AVPacket pkt; - av_log(s, AV_LOG_WARNING, - "DRM protected stream detected, decoding will likely fail!\n"); - len= avio_rl32(pb); - av_log(s, AV_LOG_DEBUG, "Secret data:\n"); - av_get_packet(pb, &pkt, len); av_hex_dump_log(s, AV_LOG_DEBUG, pkt.data, pkt.size); av_free_packet(&pkt); - len= avio_rl32(pb); - get_tag(s, "ASF_Protection_Type", -1, len, 32); - len= avio_rl32(pb); - get_tag(s, "ASF_Key_ID", -1, len, 32); - len= avio_rl32(pb); - get_tag(s, "ASF_License_URL", -1, len, 32); - } else if (!ff_guidcmp(&g, &ff_asf_ext_content_encryption)) { - av_log(s, AV_LOG_WARNING, - "Ext DRM protected stream detected, decoding will likely fail!\n"); - av_dict_set(&s->metadata, "encryption", "ASF Extended Content Encryption", 0); - } else if (!ff_guidcmp(&g, &ff_asf_digital_signature)) { - av_log(s, AV_LOG_INFO, "Digital signature detected!\n"); - } - } - } - if (avio_tell(pb) != gpos + gsize) - av_log(s, AV_LOG_DEBUG, - "gpos mismatch our pos=%"PRIu64", end=%"PRId64"\n", - avio_tell(pb) - gpos, gsize); - avio_seek(pb, gpos + gsize, SEEK_SET); - } - ff_get_guid(pb, &g); - avio_rl64(pb); - avio_r8(pb); - avio_r8(pb); - if (url_feof(pb)) - return AVERROR_EOF; - asf->data_offset = avio_tell(pb); - asf->packet_size_left = 0; - - for (i = 0; i < 128; i++) { - int stream_num = asf->asfid2avid[i]; - if (stream_num >= 0) { - AVStream *st = s->streams[stream_num]; - if (!st->codec->bit_rate) - st->codec->bit_rate = asf->stream_bitrates[i]; - if (asf->dar[i].num > 0 && asf->dar[i].den > 0) { - av_reduce(&st->sample_aspect_ratio.num, - &st->sample_aspect_ratio.den, - asf->dar[i].num, asf->dar[i].den, INT_MAX); - } else if ((asf->dar[0].num > 0) && (asf->dar[0].den > 0) && - // Use ASF container value if the stream doesn't set AR. - (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)) - av_reduce(&st->sample_aspect_ratio.num, - &st->sample_aspect_ratio.den, - asf->dar[0].num, asf->dar[0].den, INT_MAX); - - av_dlog(s, "i=%d, st->codec->codec_type:%d, asf->dar %d:%d sar=%d:%d\n", - i, st->codec->codec_type, asf->dar[i].num, asf->dar[i].den, - st->sample_aspect_ratio.num, st->sample_aspect_ratio.den); - - // copy and convert language codes to the frontend - if (asf->streams[i].stream_language_index < 128) { - const char *rfc1766 = asf->stream_languages[asf->streams[i].stream_language_index]; - if (rfc1766 && strlen(rfc1766) > 1) { - const char primary_tag[3] = { rfc1766[0], rfc1766[1], '\0' }; // ignore country code if any - const char *iso6392 = av_convert_lang_to(primary_tag, - AV_LANG_ISO639_2_BIBL); - if (iso6392) - av_dict_set(&st->metadata, "language", iso6392, 0); - } - } - } - } - - ff_metadata_conv(&s->metadata, NULL, ff_asf_metadata_conv); - - return 0; -} - -#define DO_2BITS(bits, var, defval) \ - switch (bits & 3) { \ - case 3: \ - var = avio_rl32(pb); \ - rsize += 4; \ - break; \ - case 2: \ - var = avio_rl16(pb); \ - rsize += 2; \ - break; \ - case 1: \ - var = avio_r8(pb); \ - rsize++; \ - break; \ - default: \ - var = defval; \ - break; \ - } - -/** - * Load a single ASF packet into the demuxer. - * @param s demux context - * @param pb context to read data from - * @return 0 on success, <0 on error - */ -static int ff_asf_get_packet(AVFormatContext *s, AVIOContext *pb) -{ - ASFContext *asf = s->priv_data; - uint32_t packet_length, padsize; - int rsize = 8; - int c, d, e, off; - - // if we do not know packet size, allow skipping up to 32 kB - off = 32768; - if (asf->no_resync_search) - off = 3; - else if (s->packet_size > 0) - off = (avio_tell(pb) - s->data_offset) % s->packet_size + 3; - - c = d = e = -1; - while (off-- > 0) { - c = d; - d = e; - e = avio_r8(pb); - if (c == 0x82 && !d && !e) - break; - } - - if (c != 0x82) { - /* This code allows handling of -EAGAIN at packet boundaries (i.e. - * if the packet sync code above triggers -EAGAIN). This does not - * imply complete -EAGAIN handling support at random positions in - * the stream. */ - if (pb->error == AVERROR(EAGAIN)) - return AVERROR(EAGAIN); - if (!url_feof(pb)) - av_log(s, AV_LOG_ERROR, - "ff asf bad header %x at:%"PRId64"\n", c, avio_tell(pb)); - } - if ((c & 0x8f) == 0x82) { - if (d || e) { - if (!url_feof(pb)) - av_log(s, AV_LOG_ERROR, "ff asf bad non zero\n"); - return AVERROR_INVALIDDATA; - } - c = avio_r8(pb); - d = avio_r8(pb); - rsize += 3; - } else if(!url_feof(pb)) { - avio_seek(pb, -1, SEEK_CUR); // FIXME - } - - asf->packet_flags = c; - asf->packet_property = d; - - DO_2BITS(asf->packet_flags >> 5, packet_length, s->packet_size); - DO_2BITS(asf->packet_flags >> 1, padsize, 0); // sequence ignored - DO_2BITS(asf->packet_flags >> 3, padsize, 0); // padding length - - // the following checks prevent overflows and infinite loops - if (!packet_length || packet_length >= (1U << 29)) { - av_log(s, AV_LOG_ERROR, - "invalid packet_length %d at:%"PRId64"\n", - packet_length, avio_tell(pb)); - return AVERROR_INVALIDDATA; - } - if (padsize >= packet_length) { - av_log(s, AV_LOG_ERROR, - "invalid padsize %d at:%"PRId64"\n", padsize, avio_tell(pb)); - return AVERROR_INVALIDDATA; - } - - asf->packet_timestamp = avio_rl32(pb); - avio_rl16(pb); /* duration */ - // rsize has at least 11 bytes which have to be present - - if (asf->packet_flags & 0x01) { - asf->packet_segsizetype = avio_r8(pb); - rsize++; - asf->packet_segments = asf->packet_segsizetype & 0x3f; - } else { - 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 AVERROR_INVALIDDATA; - } - asf->packet_size_left = packet_length - padsize - rsize; - if (packet_length < asf->hdr.min_pktsize) - padsize += asf->hdr.min_pktsize - packet_length; - asf->packet_padsize = padsize; - av_dlog(s, "packet: size=%d padsize=%d left=%d\n", - s->packet_size, asf->packet_padsize, asf->packet_size_left); - return 0; -} - -/** - * - * @return <0 if error - */ -static int asf_read_frame_header(AVFormatContext *s, AVIOContext *pb) -{ - ASFContext *asf = s->priv_data; - ASFStream *asfst; - int rsize = 1; - int num = avio_r8(pb); - int i; - int64_t ts0, ts1 av_unused; - - asf->packet_segments--; - asf->packet_key_frame = num >> 7; - asf->stream_index = asf->asfid2avid[num & 0x7f]; - asfst = &asf->streams[num & 0x7f]; - // sequence should be ignored! - DO_2BITS(asf->packet_property >> 4, asf->packet_seq, 0); - DO_2BITS(asf->packet_property >> 2, asf->packet_frag_offset, 0); - DO_2BITS(asf->packet_property, asf->packet_replic_size, 0); - av_dlog(asf, "key:%d stream:%d seq:%d offset:%d replic_size:%d\n", - asf->packet_key_frame, asf->stream_index, asf->packet_seq, - asf->packet_frag_offset, asf->packet_replic_size); - if (rsize+(int64_t)asf->packet_replic_size > asf->packet_size_left) { - av_log(s, AV_LOG_ERROR, "packet_replic_size %d is invalid\n", asf->packet_replic_size); - return AVERROR_INVALIDDATA; - } - if (asf->packet_replic_size >= 8) { - int64_t end = avio_tell(pb) + asf->packet_replic_size; - AVRational aspect; - asf->packet_obj_size = avio_rl32(pb); - if (asf->packet_obj_size >= (1 << 24) || asf->packet_obj_size <= 0) { - av_log(s, AV_LOG_ERROR, "packet_obj_size invalid\n"); - asf->packet_obj_size = 0; - return AVERROR_INVALIDDATA; - } - asf->packet_frag_timestamp = avio_rl32(pb); // timestamp - - for (i = 0; i < asfst->payload_ext_ct; i++) { - ASFPayload *p = &asfst->payload[i]; - int size = p->size; - int64_t payend; - if (size == 0xFFFF) - size = avio_rl16(pb); - payend = avio_tell(pb) + size; - if (payend > end) { - av_log(s, AV_LOG_ERROR, "too long payload\n"); - break; - } - switch (p->type) { - case 0x50: -// duration = avio_rl16(pb); - break; - case 0x54: - aspect.num = avio_r8(pb); - aspect.den = avio_r8(pb); - if (aspect.num > 0 && aspect.den > 0 && asf->stream_index >= 0) { - s->streams[asf->stream_index]->sample_aspect_ratio = aspect; - } - break; - case 0x2A: - avio_skip(pb, 8); - ts0 = avio_rl64(pb); - ts1 = avio_rl64(pb); - if (ts0!= -1) asf->packet_frag_timestamp = ts0/10000; - else asf->packet_frag_timestamp = AV_NOPTS_VALUE; - break; - case 0x5B: - case 0xB7: - case 0xCC: - case 0xC0: - case 0xA0: - //unknown - break; - } - avio_seek(pb, payend, SEEK_SET); - } - - avio_seek(pb, end, SEEK_SET); - rsize += asf->packet_replic_size; // FIXME - check validity - } else if (asf->packet_replic_size == 1) { - // multipacket - frag_offset is beginning timestamp - asf->packet_time_start = asf->packet_frag_offset; - asf->packet_frag_offset = 0; - asf->packet_frag_timestamp = asf->packet_timestamp; - - asf->packet_time_delta = avio_r8(pb); - rsize++; - } else if (asf->packet_replic_size != 0) { - av_log(s, AV_LOG_ERROR, "unexpected packet_replic_size of %d\n", - asf->packet_replic_size); - return AVERROR_INVALIDDATA; - } - if (asf->packet_flags & 0x01) { - DO_2BITS(asf->packet_segsizetype >> 6, asf->packet_frag_size, 0); // 0 is illegal - if (rsize > asf->packet_size_left) { - av_log(s, AV_LOG_ERROR, "packet_replic_size is invalid\n"); - return AVERROR_INVALIDDATA; - } else if (asf->packet_frag_size > asf->packet_size_left - rsize) { - if (asf->packet_frag_size > asf->packet_size_left - rsize + asf->packet_padsize) { - av_log(s, AV_LOG_ERROR, "packet_frag_size is invalid (%d-%d)\n", - asf->packet_size_left, rsize); - return AVERROR_INVALIDDATA; - } else { - int diff = asf->packet_frag_size - (asf->packet_size_left - rsize); - asf->packet_size_left += diff; - asf->packet_padsize -= diff; - } - } - } else { - asf->packet_frag_size = asf->packet_size_left - rsize; - } - if (asf->packet_replic_size == 1) { - asf->packet_multi_size = asf->packet_frag_size; - if (asf->packet_multi_size > asf->packet_size_left) - return AVERROR_INVALIDDATA; - } - asf->packet_size_left -= rsize; - - return 0; -} - -/** - * Parse data from individual ASF packets (which were previously loaded - * with asf_get_packet()). - * @param s demux context - * @param pb context to read data from - * @param pkt pointer to store packet data into - * @return 0 if data was stored in pkt, <0 on error or 1 if more ASF - * packets need to be loaded (through asf_get_packet()) - */ -static int ff_asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pkt) -{ - ASFContext *asf = s->priv_data; - ASFStream *asf_st = 0; - for (;;) { - int ret; - if (url_feof(pb)) - return AVERROR_EOF; - - if (asf->packet_size_left < FRAME_HEADER_SIZE || - asf->packet_segments < 1) { - int ret = asf->packet_size_left + asf->packet_padsize; - - assert(ret >= 0); - /* fail safe */ - avio_skip(pb, ret); - - asf->packet_pos = avio_tell(pb); - if (asf->data_object_size != (uint64_t)-1 && - (asf->packet_pos - asf->data_object_offset >= asf->data_object_size)) - return AVERROR_EOF; /* Do not exceed the size of the data object */ - return 1; - } - if (asf->packet_time_start == 0) { - if (asf_read_frame_header(s, pb) < 0) { - asf->packet_segments = 0; - continue; - } - if (asf->stream_index < 0 || - s->streams[asf->stream_index]->discard >= AVDISCARD_ALL || - (!asf->packet_key_frame && - s->streams[asf->stream_index]->discard >= AVDISCARD_NONKEY)) { - asf->packet_time_start = 0; - /* unhandled packet (should not happen) */ - avio_skip(pb, asf->packet_frag_size); - asf->packet_size_left -= asf->packet_frag_size; - if (asf->stream_index < 0) - av_log(s, AV_LOG_ERROR, "ff asf skip %d (unknown stream)\n", - asf->packet_frag_size); - continue; - } - asf->asf_st = s->streams[asf->stream_index]->priv_data; - } - asf_st = asf->asf_st; - av_assert0(asf_st); - - if (asf->packet_replic_size == 1) { - // frag_offset is here used as the beginning timestamp - asf->packet_frag_timestamp = asf->packet_time_start; - asf->packet_time_start += asf->packet_time_delta; - asf->packet_obj_size = asf->packet_frag_size = avio_r8(pb); - asf->packet_size_left--; - asf->packet_multi_size--; - if (asf->packet_multi_size < asf->packet_obj_size) { - asf->packet_time_start = 0; - avio_skip(pb, asf->packet_multi_size); - asf->packet_size_left -= asf->packet_multi_size; - continue; - } - asf->packet_multi_size -= asf->packet_obj_size; - } - if (asf_st->frag_offset + asf->packet_frag_size <= asf_st->pkt.size && - asf_st->frag_offset + asf->packet_frag_size > asf->packet_obj_size) { - av_log(s, AV_LOG_INFO, "ignoring invalid packet_obj_size (%d %d %d %d)\n", - asf_st->frag_offset, asf->packet_frag_size, - asf->packet_obj_size, asf_st->pkt.size); - asf->packet_obj_size = asf_st->pkt.size; - } - - if (asf_st->pkt.size != asf->packet_obj_size || - // FIXME is this condition sufficient? - asf_st->frag_offset + asf->packet_frag_size > asf_st->pkt.size) { - if (asf_st->pkt.data) { - av_log(s, AV_LOG_INFO, - "freeing incomplete packet size %d, new %d\n", - asf_st->pkt.size, asf->packet_obj_size); - asf_st->frag_offset = 0; - av_free_packet(&asf_st->pkt); - } - /* new packet */ - av_new_packet(&asf_st->pkt, asf->packet_obj_size); - asf_st->seq = asf->packet_seq; - asf_st->pkt.dts = asf->packet_frag_timestamp - asf->hdr.preroll; - asf_st->pkt.stream_index = asf->stream_index; - asf_st->pkt.pos = asf_st->packet_pos = asf->packet_pos; - - if (asf_st->pkt.data && asf_st->palette_changed) { - uint8_t *pal; - pal = av_packet_new_side_data(&asf_st->pkt, AV_PKT_DATA_PALETTE, - AVPALETTE_SIZE); - if (!pal) { - av_log(s, AV_LOG_ERROR, "Cannot append palette to packet\n"); - } else { - memcpy(pal, asf_st->palette, AVPALETTE_SIZE); - asf_st->palette_changed = 0; - } - } - av_dlog(asf, "new packet: stream:%d key:%d packet_key:%d audio:%d size:%d\n", - asf->stream_index, asf->packet_key_frame, - asf_st->pkt.flags & AV_PKT_FLAG_KEY, - s->streams[asf->stream_index]->codec->codec_type == AVMEDIA_TYPE_AUDIO, - asf->packet_obj_size); - if (s->streams[asf->stream_index]->codec->codec_type == AVMEDIA_TYPE_AUDIO) - asf->packet_key_frame = 1; - if (asf->packet_key_frame) - asf_st->pkt.flags |= AV_PKT_FLAG_KEY; - } - - /* read data */ - av_dlog(asf, "READ PACKET s:%d os:%d o:%d,%d l:%d DATA:%p\n", - s->packet_size, asf_st->pkt.size, asf->packet_frag_offset, - asf_st->frag_offset, asf->packet_frag_size, asf_st->pkt.data); - asf->packet_size_left -= asf->packet_frag_size; - if (asf->packet_size_left < 0) - continue; - - if (asf->packet_frag_offset >= asf_st->pkt.size || - asf->packet_frag_size > asf_st->pkt.size - asf->packet_frag_offset) { - av_log(s, AV_LOG_ERROR, - "packet fragment position invalid %u,%u not in %u\n", - asf->packet_frag_offset, asf->packet_frag_size, - asf_st->pkt.size); - continue; - } - - ret = avio_read(pb, asf_st->pkt.data + asf->packet_frag_offset, - asf->packet_frag_size); - if (ret != asf->packet_frag_size) { - if (ret < 0 || asf->packet_frag_offset + ret == 0) - return ret < 0 ? ret : AVERROR_EOF; - - if (asf_st->ds_span > 1) { - // scrambling, we can either drop it completely or fill the remainder - // TODO: should we fill the whole packet instead of just the current - // fragment? - memset(asf_st->pkt.data + asf->packet_frag_offset + ret, 0, - asf->packet_frag_size - ret); - ret = asf->packet_frag_size; - } else { - // no scrambling, so we can return partial packets - av_shrink_packet(&asf_st->pkt, asf->packet_frag_offset + ret); - } - } - if (s->key && s->keylen == 20) - ff_asfcrypt_dec(s->key, asf_st->pkt.data + asf->packet_frag_offset, - ret); - asf_st->frag_offset += ret; - /* test if whole packet is read */ - if (asf_st->frag_offset == asf_st->pkt.size) { - // workaround for macroshit radio DVR-MS files - if (s->streams[asf->stream_index]->codec->codec_id == AV_CODEC_ID_MPEG2VIDEO && - asf_st->pkt.size > 100) { - int i; - for (i = 0; i < asf_st->pkt.size && !asf_st->pkt.data[i]; i++) - ; - if (i == asf_st->pkt.size) { - av_log(s, AV_LOG_DEBUG, "discarding ms fart\n"); - asf_st->frag_offset = 0; - av_free_packet(&asf_st->pkt); - continue; - } - } - - /* return packet */ - if (asf_st->ds_span > 1) { - if (asf_st->pkt.size != asf_st->ds_packet_size * asf_st->ds_span) { - av_log(s, AV_LOG_ERROR, - "pkt.size != ds_packet_size * ds_span (%d %d %d)\n", - asf_st->pkt.size, asf_st->ds_packet_size, - asf_st->ds_span); - } else { - /* packet descrambling */ - AVBufferRef *buf = av_buffer_alloc(asf_st->pkt.size + - FF_INPUT_BUFFER_PADDING_SIZE); - if (buf) { - uint8_t *newdata = buf->data; - int offset = 0; - memset(newdata + asf_st->pkt.size, 0, - FF_INPUT_BUFFER_PADDING_SIZE); - while (offset < asf_st->pkt.size) { - int off = offset / asf_st->ds_chunk_size; - int row = off / asf_st->ds_span; - int col = off % asf_st->ds_span; - int idx = row + col * asf_st->ds_packet_size / asf_st->ds_chunk_size; - assert(offset + asf_st->ds_chunk_size <= asf_st->pkt.size); - assert(idx + 1 <= asf_st->pkt.size / asf_st->ds_chunk_size); - memcpy(newdata + offset, - asf_st->pkt.data + idx * asf_st->ds_chunk_size, - asf_st->ds_chunk_size); - offset += asf_st->ds_chunk_size; - } - av_buffer_unref(&asf_st->pkt.buf); - asf_st->pkt.buf = buf; - asf_st->pkt.data = buf->data; - } - } - } - asf_st->frag_offset = 0; - *pkt = asf_st->pkt; -#if FF_API_DESTRUCT_PACKET - asf_st->pkt.destruct = NULL; -#endif - asf_st->pkt.buf = 0; - asf_st->pkt.size = 0; - asf_st->pkt.data = 0; - asf_st->pkt.side_data_elems = 0; - asf_st->pkt.side_data = NULL; - break; // packet completed - } - } - return 0; -} - -static int asf_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - ASFContext *asf = s->priv_data; - - for (;;) { - int ret; - - /* parse cached packets, if any */ - if ((ret = ff_asf_parse_packet(s, s->pb, pkt)) <= 0) - return ret; - if ((ret = ff_asf_get_packet(s, s->pb)) < 0) - assert(asf->packet_size_left < FRAME_HEADER_SIZE || - asf->packet_segments < 1); - asf->packet_time_start = 0; - } -} - -// Added to support seeking after packets have been read -// If information is not reset, read_packet fails due to -// leftover information from previous reads -static void asf_reset_header(AVFormatContext *s) -{ - ASFContext *asf = s->priv_data; - ASFStream *asf_st; - int i; - - asf->packet_size_left = 0; - asf->packet_segments = 0; - asf->packet_flags = 0; - asf->packet_property = 0; - asf->packet_timestamp = 0; - asf->packet_segsizetype = 0; - asf->packet_segments = 0; - asf->packet_seq = 0; - asf->packet_replic_size = 0; - asf->packet_key_frame = 0; - asf->packet_padsize = 0; - asf->packet_frag_offset = 0; - asf->packet_frag_size = 0; - asf->packet_frag_timestamp = 0; - asf->packet_multi_size = 0; - asf->packet_obj_size = 0; - asf->packet_time_delta = 0; - asf->packet_time_start = 0; - - for (i = 0; i < s->nb_streams; i++) { - asf_st = s->streams[i]->priv_data; - if (!asf_st) - continue; - av_free_packet(&asf_st->pkt); - asf_st->frag_offset = 0; - asf_st->seq = 0; - } - asf->asf_st = NULL; -} - -static int asf_read_close(AVFormatContext *s) -{ - asf_reset_header(s); - - return 0; -} - -static int64_t asf_read_pts(AVFormatContext *s, int stream_index, - int64_t *ppos, int64_t pos_limit) -{ - AVPacket pkt1, *pkt = &pkt1; - ASFStream *asf_st; - int64_t pts; - int64_t pos = *ppos; - int i; - int64_t start_pos[ASF_MAX_STREAMS]; - - for (i = 0; i < s->nb_streams; i++) - start_pos[i] = pos; - - if (s->packet_size > 0) - pos = (pos + s->packet_size - 1 - s->data_offset) / - s->packet_size * s->packet_size + - s->data_offset; - *ppos = pos; - if (avio_seek(s->pb, pos, SEEK_SET) < 0) - return AV_NOPTS_VALUE; - - asf_reset_header(s); - for (;;) { - if (av_read_frame(s, pkt) < 0) { - av_log(s, AV_LOG_INFO, "asf_read_pts failed\n"); - return AV_NOPTS_VALUE; - } - - pts = pkt->dts; - - av_free_packet(pkt); - if (pkt->flags & AV_PKT_FLAG_KEY) { - i = pkt->stream_index; - - asf_st = s->streams[i]->priv_data; - av_assert0(asf_st); - -// assert((asf_st->packet_pos - s->data_offset) % s->packet_size == 0); - pos = asf_st->packet_pos; - - av_add_index_entry(s->streams[i], pos, pts, pkt->size, - pos - start_pos[i] + 1, AVINDEX_KEYFRAME); - start_pos[i] = asf_st->packet_pos + 1; - - if (pkt->stream_index == stream_index) - break; - } - } - - *ppos = pos; - return pts; -} - -static void asf_build_simple_index(AVFormatContext *s, int stream_index) -{ - ff_asf_guid g; - ASFContext *asf = s->priv_data; - int64_t current_pos = avio_tell(s->pb); - - if(avio_seek(s->pb, asf->data_object_offset + asf->data_object_size, SEEK_SET) < 0) { - asf->index_read= -1; - return; - } - - ff_get_guid(s->pb, &g); - - /* the data object can be followed by other top-level objects, - * skip them until the simple index object is reached */ - while (ff_guidcmp(&g, &ff_asf_simple_index_header)) { - int64_t gsize = avio_rl64(s->pb); - if (gsize < 24 || url_feof(s->pb)) { - avio_seek(s->pb, current_pos, SEEK_SET); - asf->index_read= -1; - return; - } - avio_skip(s->pb, gsize - 24); - ff_get_guid(s->pb, &g); - } - - { - int64_t itime, last_pos = -1; - int pct, ict; - int i; - int64_t av_unused gsize = avio_rl64(s->pb); - ff_get_guid(s->pb, &g); - itime = avio_rl64(s->pb); - pct = avio_rl32(s->pb); - ict = avio_rl32(s->pb); - av_log(s, AV_LOG_DEBUG, - "itime:0x%"PRIx64", pct:%d, ict:%d\n", itime, pct, ict); - - for (i = 0; i < ict; i++) { - int pktnum = avio_rl32(s->pb); - int pktct = avio_rl16(s->pb); - int64_t pos = s->data_offset + s->packet_size * (int64_t)pktnum; - int64_t index_pts = FFMAX(av_rescale(itime, i, 10000) - asf->hdr.preroll, 0); - - if (pos != last_pos) { - av_log(s, AV_LOG_DEBUG, "pktnum:%d, pktct:%d pts: %"PRId64"\n", - pktnum, pktct, index_pts); - av_add_index_entry(s->streams[stream_index], pos, index_pts, - s->packet_size, 0, AVINDEX_KEYFRAME); - last_pos = pos; - } - } - asf->index_read = ict > 1; - } - avio_seek(s->pb, current_pos, SEEK_SET); -} - -static int asf_read_seek(AVFormatContext *s, int stream_index, - int64_t pts, int flags) -{ - ASFContext *asf = s->priv_data; - AVStream *st = s->streams[stream_index]; - - if (s->packet_size <= 0) - return -1; - - /* Try using the protocol's read_seek if available */ - if (s->pb) { - int ret = avio_seek_time(s->pb, stream_index, pts, flags); - if (ret >= 0) - asf_reset_header(s); - if (ret != AVERROR(ENOSYS)) - return ret; - } - - if (!asf->index_read) - asf_build_simple_index(s, stream_index); - - if ((asf->index_read > 0 && st->index_entries)) { - int index = av_index_search_timestamp(st, pts, flags); - if (index >= 0) { - /* find the position */ - uint64_t pos = st->index_entries[index].pos; - - /* do the seek */ - av_log(s, AV_LOG_DEBUG, "SEEKTO: %"PRId64"\n", pos); - if(avio_seek(s->pb, pos, SEEK_SET) < 0) - return -1; - asf_reset_header(s); - return 0; - } - } - /* no index or seeking by index failed */ - if (ff_seek_frame_binary(s, stream_index, pts, flags) < 0) - return -1; - asf_reset_header(s); - return 0; -} - -AVInputFormat ff_asf_demuxer = { - .name = "asf", - .long_name = NULL_IF_CONFIG_SMALL("ASF (Advanced / Active Streaming Format)"), - .priv_data_size = sizeof(ASFContext), - .read_probe = asf_probe, - .read_header = asf_read_header, - .read_packet = asf_read_packet, - .read_close = asf_read_close, - .read_seek = asf_read_seek, - .read_timestamp = asf_read_pts, - .flags = AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH, - .priv_class = &asf_class, -}; diff --git a/ffmpeg1/libavformat/asfenc.c b/ffmpeg1/libavformat/asfenc.c deleted file mode 100644 index f3aec9c..0000000 --- a/ffmpeg1/libavformat/asfenc.c +++ /dev/null @@ -1,914 +0,0 @@ -/* - * ASF muxer - * Copyright (c) 2000, 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 - */ - -#include "libavutil/dict.h" -#include "avformat.h" -#include "avio_internal.h" -#include "internal.h" -#include "riff.h" -#include "asf.h" - -#undef NDEBUG -#include - - -#define ASF_INDEXED_INTERVAL 10000000 -#define ASF_INDEX_BLOCK (1<<9) - -#define ASF_PACKET_ERROR_CORRECTION_DATA_SIZE 0x2 -#define ASF_PACKET_ERROR_CORRECTION_FLAGS \ - (ASF_PACKET_FLAG_ERROR_CORRECTION_PRESENT | \ - ASF_PACKET_ERROR_CORRECTION_DATA_SIZE) - -#if (ASF_PACKET_ERROR_CORRECTION_FLAGS != 0) -# define ASF_PACKET_ERROR_CORRECTION_FLAGS_FIELD_SIZE 1 -#else -# define ASF_PACKET_ERROR_CORRECTION_FLAGS_FIELD_SIZE 0 -#endif - -#define ASF_PPI_PROPERTY_FLAGS \ - (ASF_PL_FLAG_REPLICATED_DATA_LENGTH_FIELD_IS_BYTE | \ - ASF_PL_FLAG_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_IS_DWORD | \ - ASF_PL_FLAG_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_IS_BYTE | \ - ASF_PL_FLAG_STREAM_NUMBER_LENGTH_FIELD_IS_BYTE) - -#define ASF_PPI_LENGTH_TYPE_FLAGS 0 - -#define ASF_PAYLOAD_FLAGS ASF_PL_FLAG_PAYLOAD_LENGTH_FIELD_IS_WORD - -#if (ASF_PPI_FLAG_SEQUENCE_FIELD_IS_BYTE == (ASF_PPI_LENGTH_TYPE_FLAGS & ASF_PPI_MASK_SEQUENCE_FIELD_SIZE)) -# define ASF_PPI_SEQUENCE_FIELD_SIZE 1 -#endif -#if (ASF_PPI_FLAG_SEQUENCE_FIELD_IS_WORD == (ASF_PPI_LENGTH_TYPE_FLAGS & ASF_PPI_MASK_SEQUENCE_FIELD_SIZE)) -# define ASF_PPI_SEQUENCE_FIELD_SIZE 2 -#endif -#if (ASF_PPI_FLAG_SEQUENCE_FIELD_IS_DWORD == (ASF_PPI_LENGTH_TYPE_FLAGS & ASF_PPI_MASK_SEQUENCE_FIELD_SIZE)) -# define ASF_PPI_SEQUENCE_FIELD_SIZE 4 -#endif -#ifndef ASF_PPI_SEQUENCE_FIELD_SIZE -# define ASF_PPI_SEQUENCE_FIELD_SIZE 0 -#endif - -#if (ASF_PPI_FLAG_PACKET_LENGTH_FIELD_IS_BYTE == (ASF_PPI_LENGTH_TYPE_FLAGS & ASF_PPI_MASK_PACKET_LENGTH_FIELD_SIZE)) -# define ASF_PPI_PACKET_LENGTH_FIELD_SIZE 1 -#endif -#if (ASF_PPI_FLAG_PACKET_LENGTH_FIELD_IS_WORD == (ASF_PPI_LENGTH_TYPE_FLAGS & ASF_PPI_MASK_PACKET_LENGTH_FIELD_SIZE)) -# define ASF_PPI_PACKET_LENGTH_FIELD_SIZE 2 -#endif -#if (ASF_PPI_FLAG_PACKET_LENGTH_FIELD_IS_DWORD == (ASF_PPI_LENGTH_TYPE_FLAGS & ASF_PPI_MASK_PACKET_LENGTH_FIELD_SIZE)) -# define ASF_PPI_PACKET_LENGTH_FIELD_SIZE 4 -#endif -#ifndef ASF_PPI_PACKET_LENGTH_FIELD_SIZE -# define ASF_PPI_PACKET_LENGTH_FIELD_SIZE 0 -#endif - -#if (ASF_PPI_FLAG_PADDING_LENGTH_FIELD_IS_BYTE == (ASF_PPI_LENGTH_TYPE_FLAGS & ASF_PPI_MASK_PADDING_LENGTH_FIELD_SIZE)) -# define ASF_PPI_PADDING_LENGTH_FIELD_SIZE 1 -#endif -#if (ASF_PPI_FLAG_PADDING_LENGTH_FIELD_IS_WORD == (ASF_PPI_LENGTH_TYPE_FLAGS & ASF_PPI_MASK_PADDING_LENGTH_FIELD_SIZE)) -# define ASF_PPI_PADDING_LENGTH_FIELD_SIZE 2 -#endif -#if (ASF_PPI_FLAG_PADDING_LENGTH_FIELD_IS_DWORD == (ASF_PPI_LENGTH_TYPE_FLAGS & ASF_PPI_MASK_PADDING_LENGTH_FIELD_SIZE)) -# define ASF_PPI_PADDING_LENGTH_FIELD_SIZE 4 -#endif -#ifndef ASF_PPI_PADDING_LENGTH_FIELD_SIZE -# define ASF_PPI_PADDING_LENGTH_FIELD_SIZE 0 -#endif - -#if (ASF_PL_FLAG_REPLICATED_DATA_LENGTH_FIELD_IS_BYTE == (ASF_PPI_PROPERTY_FLAGS & ASF_PL_MASK_REPLICATED_DATA_LENGTH_FIELD_SIZE)) -# define ASF_PAYLOAD_REPLICATED_DATA_LENGTH_FIELD_SIZE 1 -#endif -#if (ASF_PL_FLAG_REPLICATED_DATA_LENGTH_FIELD_IS_WORD == (ASF_PPI_PROPERTY_FLAGS & ASF_PL_MASK_REPLICATED_DATA_LENGTH_FIELD_SIZE)) -# define ASF_PAYLOAD_REPLICATED_DATA_LENGTH_FIELD_SIZE 2 -#endif -#if (ASF_PL_FLAG_REPLICATED_DATA_LENGTH_FIELD_IS_DWORD == (ASF_PPI_PROPERTY_FLAGS & ASF_PL_MASK_REPLICATED_DATA_LENGTH_FIELD_SIZE)) -# define ASF_PAYLOAD_REPLICATED_DATA_LENGTH_FIELD_SIZE 4 -#endif -#ifndef ASF_PAYLOAD_REPLICATED_DATA_LENGTH_FIELD_SIZE -# define ASF_PAYLOAD_REPLICATED_DATA_LENGTH_FIELD_SIZE 0 -#endif - -#if (ASF_PL_FLAG_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_IS_BYTE == (ASF_PPI_PROPERTY_FLAGS & ASF_PL_MASK_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_SIZE)) -# define ASF_PAYLOAD_OFFSET_INTO_MEDIA_OBJECT_FIELD_SIZE 1 -#endif -#if (ASF_PL_FLAG_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_IS_WORD == (ASF_PPI_PROPERTY_FLAGS & ASF_PL_MASK_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_SIZE)) -# define ASF_PAYLOAD_OFFSET_INTO_MEDIA_OBJECT_FIELD_SIZE 2 -#endif -#if (ASF_PL_FLAG_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_IS_DWORD == (ASF_PPI_PROPERTY_FLAGS & ASF_PL_MASK_OFFSET_INTO_MEDIA_OBJECT_LENGTH_FIELD_SIZE)) -# define ASF_PAYLOAD_OFFSET_INTO_MEDIA_OBJECT_FIELD_SIZE 4 -#endif -#ifndef ASF_PAYLOAD_OFFSET_INTO_MEDIA_OBJECT_FIELD_SIZE -# define ASF_PAYLOAD_OFFSET_INTO_MEDIA_OBJECT_FIELD_SIZE 0 -#endif - -#if (ASF_PL_FLAG_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_IS_BYTE == (ASF_PPI_PROPERTY_FLAGS & ASF_PL_MASK_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_SIZE)) -# define ASF_PAYLOAD_MEDIA_OBJECT_NUMBER_FIELD_SIZE 1 -#endif -#if (ASF_PL_FLAG_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_IS_WORD == (ASF_PPI_PROPERTY_FLAGS & ASF_PL_MASK_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_SIZE)) -# define ASF_PAYLOAD_MEDIA_OBJECT_NUMBER_FIELD_SIZE 2 -#endif -#if (ASF_PL_FLAG_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_IS_DWORD == (ASF_PPI_PROPERTY_FLAGS & ASF_PL_MASK_MEDIA_OBJECT_NUMBER_LENGTH_FIELD_SIZE)) -# define ASF_PAYLOAD_MEDIA_OBJECT_NUMBER_FIELD_SIZE 4 -#endif -#ifndef ASF_PAYLOAD_MEDIA_OBJECT_NUMBER_FIELD_SIZE -# define ASF_PAYLOAD_MEDIA_OBJECT_NUMBER_FIELD_SIZE 0 -#endif - -#if (ASF_PL_FLAG_PAYLOAD_LENGTH_FIELD_IS_BYTE == (ASF_PAYLOAD_FLAGS & ASF_PL_MASK_PAYLOAD_LENGTH_FIELD_SIZE)) -# define ASF_PAYLOAD_LENGTH_FIELD_SIZE 1 -#endif -#if (ASF_PL_FLAG_PAYLOAD_LENGTH_FIELD_IS_WORD == (ASF_PAYLOAD_FLAGS & ASF_PL_MASK_PAYLOAD_LENGTH_FIELD_SIZE)) -# define ASF_PAYLOAD_LENGTH_FIELD_SIZE 2 -#endif -#ifndef ASF_PAYLOAD_LENGTH_FIELD_SIZE -# define ASF_PAYLOAD_LENGTH_FIELD_SIZE 0 -#endif - -#define PACKET_HEADER_MIN_SIZE \ - (ASF_PACKET_ERROR_CORRECTION_FLAGS_FIELD_SIZE + \ - ASF_PACKET_ERROR_CORRECTION_DATA_SIZE + \ - 1 + /* Length Type Flags */ \ - 1 + /* Property Flags */ \ - ASF_PPI_PACKET_LENGTH_FIELD_SIZE + \ - ASF_PPI_SEQUENCE_FIELD_SIZE + \ - ASF_PPI_PADDING_LENGTH_FIELD_SIZE + \ - 4 + /* Send Time Field */ \ - 2) /* Duration Field */ - -// Replicated Data shall be at least 8 bytes long. -#define ASF_PAYLOAD_REPLICATED_DATA_LENGTH 0x08 - -#define PAYLOAD_HEADER_SIZE_SINGLE_PAYLOAD \ - (1 + /* Stream Number */ \ - ASF_PAYLOAD_MEDIA_OBJECT_NUMBER_FIELD_SIZE + \ - ASF_PAYLOAD_OFFSET_INTO_MEDIA_OBJECT_FIELD_SIZE + \ - ASF_PAYLOAD_REPLICATED_DATA_LENGTH_FIELD_SIZE + \ - ASF_PAYLOAD_REPLICATED_DATA_LENGTH) - -#define PAYLOAD_HEADER_SIZE_MULTIPLE_PAYLOADS \ - (1 + /* Stream Number */ \ - ASF_PAYLOAD_MEDIA_OBJECT_NUMBER_FIELD_SIZE + \ - ASF_PAYLOAD_OFFSET_INTO_MEDIA_OBJECT_FIELD_SIZE + \ - ASF_PAYLOAD_REPLICATED_DATA_LENGTH_FIELD_SIZE + \ - ASF_PAYLOAD_REPLICATED_DATA_LENGTH + \ - ASF_PAYLOAD_LENGTH_FIELD_SIZE) - -#define SINGLE_PAYLOAD_DATA_LENGTH \ - (PACKET_SIZE - \ - PACKET_HEADER_MIN_SIZE - \ - PAYLOAD_HEADER_SIZE_SINGLE_PAYLOAD) - -#define MULTI_PAYLOAD_CONSTANT \ - (PACKET_SIZE - \ - PACKET_HEADER_MIN_SIZE - \ - 1 - /* Payload Flags */ \ - 2 * PAYLOAD_HEADER_SIZE_MULTIPLE_PAYLOADS) - -typedef struct { - uint32_t seqno; - int is_streamed; - ASFStream streams[128]; ///< it's max number and it's not that big - /* non streamed additonnal info */ - uint64_t nb_packets; ///< how many packets are there in the file, invalid if broadcasting - int64_t duration; ///< in 100ns units - /* packet filling */ - unsigned char multi_payloads_present; - int packet_size_left; - int64_t packet_timestamp_start; - int64_t packet_timestamp_end; - unsigned int packet_nb_payloads; - uint8_t packet_buf[PACKET_SIZE]; - AVIOContext pb; - /* only for reading */ - uint64_t data_offset; ///< beginning of the first data packet - - ASFIndex *index_ptr; - uint32_t nb_index_memory_alloc; - uint16_t maximum_packet; - uint32_t next_packet_number; - uint16_t next_packet_count; - int next_start_sec; - int end_sec; -} ASFContext; - -static const AVCodecTag codec_asf_bmp_tags[] = { - { AV_CODEC_ID_MPEG4, MKTAG('M', '4', 'S', '2') }, - { AV_CODEC_ID_MPEG4, MKTAG('M', 'P', '4', 'S') }, - { AV_CODEC_ID_MSMPEG4V3, MKTAG('M', 'P', '4', '3') }, - { AV_CODEC_ID_NONE, 0 }, -}; - -#define PREROLL_TIME 3100 - -void ff_put_guid(AVIOContext *s, const ff_asf_guid *g) -{ - assert(sizeof(*g) == 16); - avio_write(s, *g, sizeof(*g)); -} - -static void put_str16(AVIOContext *s, const char *tag) -{ - int len; - uint8_t *pb; - AVIOContext *dyn_buf; - if (avio_open_dyn_buf(&dyn_buf) < 0) - return; - - avio_put_str16le(dyn_buf, tag); - len = avio_close_dyn_buf(dyn_buf, &pb); - avio_wl16(s, len); - avio_write(s, pb, len); - av_freep(&pb); -} - -static int64_t put_header(AVIOContext *pb, const ff_asf_guid *g) -{ - int64_t pos; - - pos = avio_tell(pb); - ff_put_guid(pb, g); - avio_wl64(pb, 24); - return pos; -} - -/* update header size */ -static void end_header(AVIOContext *pb, int64_t pos) -{ - int64_t pos1; - - pos1 = avio_tell(pb); - avio_seek(pb, pos + 16, SEEK_SET); - avio_wl64(pb, pos1 - pos); - avio_seek(pb, pos1, SEEK_SET); -} - -/* write an asf chunk (only used in streaming case) */ -static void put_chunk(AVFormatContext *s, int type, - int payload_length, int flags) -{ - ASFContext *asf = s->priv_data; - AVIOContext *pb = s->pb; - int length; - - length = payload_length + 8; - avio_wl16(pb, type); - avio_wl16(pb, length); // size - avio_wl32(pb, asf->seqno); // sequence number - avio_wl16(pb, flags); // unknown bytes - avio_wl16(pb, length); // size_confirm - asf->seqno++; -} - -/* convert from unix to windows time */ -static int64_t unix_to_file_time(int ti) -{ - int64_t t; - - t = ti * INT64_C(10000000); - t += INT64_C(116444736000000000); - return t; -} - -/* write the header (used two times if non streamed) */ -static int asf_write_header1(AVFormatContext *s, int64_t file_size, - int64_t data_chunk_size) -{ - ASFContext *asf = s->priv_data; - AVIOContext *pb = s->pb; - AVDictionaryEntry *tags[5]; - int header_size, n, extra_size, extra_size2, wav_extra_size, file_time; - int has_title; - int metadata_count; - AVCodecContext *enc; - int64_t header_offset, cur_pos, hpos; - int bit_rate; - int64_t duration; - - ff_metadata_conv(&s->metadata, ff_asf_metadata_conv, NULL); - - tags[0] = av_dict_get(s->metadata, "title", NULL, 0); - tags[1] = av_dict_get(s->metadata, "author", NULL, 0); - tags[2] = av_dict_get(s->metadata, "copyright", NULL, 0); - tags[3] = av_dict_get(s->metadata, "comment", NULL, 0); - tags[4] = av_dict_get(s->metadata, "rating", NULL, 0); - - duration = asf->duration + PREROLL_TIME * 10000; - has_title = tags[0] || tags[1] || tags[2] || tags[3] || tags[4]; - metadata_count = av_dict_count(s->metadata); - - bit_rate = 0; - for (n = 0; n < s->nb_streams; n++) { - enc = s->streams[n]->codec; - - avpriv_set_pts_info(s->streams[n], 32, 1, 1000); /* 32 bit pts in ms */ - - bit_rate += enc->bit_rate; - } - - if (asf->is_streamed) { - put_chunk(s, 0x4824, 0, 0xc00); /* start of stream (length will be patched later) */ - } - - ff_put_guid(pb, &ff_asf_header); - avio_wl64(pb, -1); /* header length, will be patched after */ - avio_wl32(pb, 3 + has_title + !!metadata_count + s->nb_streams); /* number of chunks in header */ - avio_w8(pb, 1); /* ??? */ - avio_w8(pb, 2); /* ??? */ - - /* file header */ - header_offset = avio_tell(pb); - hpos = put_header(pb, &ff_asf_file_header); - ff_put_guid(pb, &ff_asf_my_guid); - avio_wl64(pb, file_size); - file_time = 0; - avio_wl64(pb, unix_to_file_time(file_time)); - avio_wl64(pb, asf->nb_packets); /* number of packets */ - avio_wl64(pb, duration); /* end time stamp (in 100ns units) */ - avio_wl64(pb, asf->duration); /* duration (in 100ns units) */ - avio_wl64(pb, PREROLL_TIME); /* start time stamp */ - avio_wl32(pb, (asf->is_streamed || !pb->seekable) ? 3 : 2); /* ??? */ - avio_wl32(pb, s->packet_size); /* packet size */ - avio_wl32(pb, s->packet_size); /* packet size */ - avio_wl32(pb, bit_rate); /* Nominal data rate in bps */ - end_header(pb, hpos); - - /* unknown headers */ - hpos = put_header(pb, &ff_asf_head1_guid); - ff_put_guid(pb, &ff_asf_head2_guid); - avio_wl32(pb, 6); - avio_wl16(pb, 0); - end_header(pb, hpos); - - /* title and other infos */ - if (has_title) { - int len; - uint8_t *buf; - AVIOContext *dyn_buf; - - if (avio_open_dyn_buf(&dyn_buf) < 0) - return AVERROR(ENOMEM); - - hpos = put_header(pb, &ff_asf_comment_header); - - for (n = 0; n < FF_ARRAY_ELEMS(tags); n++) { - len = tags[n] ? avio_put_str16le(dyn_buf, tags[n]->value) : 0; - avio_wl16(pb, len); - } - len = avio_close_dyn_buf(dyn_buf, &buf); - avio_write(pb, buf, len); - av_freep(&buf); - end_header(pb, hpos); - } - if (metadata_count) { - AVDictionaryEntry *tag = NULL; - hpos = put_header(pb, &ff_asf_extended_content_header); - avio_wl16(pb, metadata_count); - while ((tag = av_dict_get(s->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) { - put_str16(pb, tag->key); - avio_wl16(pb, 0); - put_str16(pb, tag->value); - } - end_header(pb, hpos); - } - - /* stream headers */ - for (n = 0; n < s->nb_streams; n++) { - int64_t es_pos; - // ASFStream *stream = &asf->streams[n]; - - enc = s->streams[n]->codec; - asf->streams[n].num = n + 1; - asf->streams[n].seq = 1; - - switch (enc->codec_type) { - case AVMEDIA_TYPE_AUDIO: - wav_extra_size = 0; - extra_size = 18 + wav_extra_size; - extra_size2 = 8; - break; - default: - case AVMEDIA_TYPE_VIDEO: - wav_extra_size = enc->extradata_size; - extra_size = 0x33 + wav_extra_size; - extra_size2 = 0; - break; - } - - hpos = put_header(pb, &ff_asf_stream_header); - if (enc->codec_type == AVMEDIA_TYPE_AUDIO) { - ff_put_guid(pb, &ff_asf_audio_stream); - ff_put_guid(pb, &ff_asf_audio_conceal_spread); - } else { - ff_put_guid(pb, &ff_asf_video_stream); - ff_put_guid(pb, &ff_asf_video_conceal_none); - } - avio_wl64(pb, 0); /* ??? */ - es_pos = avio_tell(pb); - avio_wl32(pb, extra_size); /* wav header len */ - avio_wl32(pb, extra_size2); /* additional data len */ - avio_wl16(pb, n + 1); /* stream number */ - avio_wl32(pb, 0); /* ??? */ - - if (enc->codec_type == AVMEDIA_TYPE_AUDIO) { - /* WAVEFORMATEX header */ - int wavsize = ff_put_wav_header(pb, enc); - - if (wavsize < 0) - return -1; - if (wavsize != extra_size) { - cur_pos = avio_tell(pb); - avio_seek(pb, es_pos, SEEK_SET); - avio_wl32(pb, wavsize); /* wav header len */ - avio_seek(pb, cur_pos, SEEK_SET); - } - /* ERROR Correction */ - avio_w8(pb, 0x01); - if (enc->codec_id == AV_CODEC_ID_ADPCM_G726 || !enc->block_align) { - avio_wl16(pb, 0x0190); - avio_wl16(pb, 0x0190); - } else { - avio_wl16(pb, enc->block_align); - avio_wl16(pb, enc->block_align); - } - avio_wl16(pb, 0x01); - avio_w8(pb, 0x00); - } else { - avio_wl32(pb, enc->width); - avio_wl32(pb, enc->height); - avio_w8(pb, 2); /* ??? */ - avio_wl16(pb, 40 + enc->extradata_size); /* size */ - - /* BITMAPINFOHEADER header */ - ff_put_bmp_header(pb, enc, ff_codec_bmp_tags, 1); - } - end_header(pb, hpos); - } - - /* media comments */ - - hpos = put_header(pb, &ff_asf_codec_comment_header); - ff_put_guid(pb, &ff_asf_codec_comment1_header); - avio_wl32(pb, s->nb_streams); - for (n = 0; n < s->nb_streams; n++) { - AVCodec *p; - const char *desc; - int len; - uint8_t *buf; - AVIOContext *dyn_buf; - - enc = s->streams[n]->codec; - p = avcodec_find_encoder(enc->codec_id); - - if (enc->codec_type == AVMEDIA_TYPE_AUDIO) - avio_wl16(pb, 2); - else if (enc->codec_type == AVMEDIA_TYPE_VIDEO) - avio_wl16(pb, 1); - else - avio_wl16(pb, -1); - - if (enc->codec_id == AV_CODEC_ID_WMAV2) - desc = "Windows Media Audio V8"; - else - desc = p ? p->name : enc->codec_name; - - if (avio_open_dyn_buf(&dyn_buf) < 0) - return AVERROR(ENOMEM); - - avio_put_str16le(dyn_buf, desc); - len = avio_close_dyn_buf(dyn_buf, &buf); - avio_wl16(pb, len / 2); // "number of characters" = length in bytes / 2 - - avio_write(pb, buf, len); - av_freep(&buf); - - avio_wl16(pb, 0); /* no parameters */ - - /* id */ - if (enc->codec_type == AVMEDIA_TYPE_AUDIO) { - avio_wl16(pb, 2); - avio_wl16(pb, enc->codec_tag); - } else { - avio_wl16(pb, 4); - avio_wl32(pb, enc->codec_tag); - } - if (!enc->codec_tag) - return -1; - } - end_header(pb, hpos); - - /* patch the header size fields */ - - cur_pos = avio_tell(pb); - header_size = cur_pos - header_offset; - if (asf->is_streamed) { - header_size += 8 + 30 + 50; - - avio_seek(pb, header_offset - 10 - 30, SEEK_SET); - avio_wl16(pb, header_size); - avio_seek(pb, header_offset - 2 - 30, SEEK_SET); - avio_wl16(pb, header_size); - - header_size -= 8 + 30 + 50; - } - header_size += 24 + 6; - avio_seek(pb, header_offset - 14, SEEK_SET); - avio_wl64(pb, header_size); - avio_seek(pb, cur_pos, SEEK_SET); - - /* movie chunk, followed by packets of packet_size */ - asf->data_offset = cur_pos; - ff_put_guid(pb, &ff_asf_data_header); - avio_wl64(pb, data_chunk_size); - ff_put_guid(pb, &ff_asf_my_guid); - avio_wl64(pb, asf->nb_packets); /* nb packets */ - avio_w8(pb, 1); /* ??? */ - avio_w8(pb, 1); /* ??? */ - return 0; -} - -static int asf_write_header(AVFormatContext *s) -{ - ASFContext *asf = s->priv_data; - - s->packet_size = PACKET_SIZE; - asf->nb_packets = 0; - - asf->index_ptr = av_malloc(sizeof(ASFIndex) * ASF_INDEX_BLOCK); - asf->nb_index_memory_alloc = ASF_INDEX_BLOCK; - asf->maximum_packet = 0; - - /* the data-chunk-size has to be 50, which is data_size - asf->data_offset - * at the moment this function is done. It is needed to use asf as - * streamable format. */ - if (asf_write_header1(s, 0, 50) < 0) { - //av_free(asf); - return -1; - } - - avio_flush(s->pb); - - asf->packet_nb_payloads = 0; - asf->packet_timestamp_start = -1; - asf->packet_timestamp_end = -1; - ffio_init_context(&asf->pb, asf->packet_buf, s->packet_size, 1, - NULL, NULL, NULL, NULL); - - if (s->avoid_negative_ts < 0) - s->avoid_negative_ts = 1; - - return 0; -} - -static int asf_write_stream_header(AVFormatContext *s) -{ - ASFContext *asf = s->priv_data; - - asf->is_streamed = 1; - - return asf_write_header(s); -} - -static int put_payload_parsing_info(AVFormatContext *s, - unsigned sendtime, unsigned duration, - int nb_payloads, int padsize) -{ - ASFContext *asf = s->priv_data; - AVIOContext *pb = s->pb; - int ppi_size, i; - int64_t start = avio_tell(pb); - - int iLengthTypeFlags = ASF_PPI_LENGTH_TYPE_FLAGS; - - padsize -= PACKET_HEADER_MIN_SIZE; - if (asf->multi_payloads_present) - padsize--; - assert(padsize >= 0); - - avio_w8(pb, ASF_PACKET_ERROR_CORRECTION_FLAGS); - for (i = 0; i < ASF_PACKET_ERROR_CORRECTION_DATA_SIZE; i++) - avio_w8(pb, 0x0); - - if (asf->multi_payloads_present) - iLengthTypeFlags |= ASF_PPI_FLAG_MULTIPLE_PAYLOADS_PRESENT; - - if (padsize > 0) { - if (padsize < 256) - iLengthTypeFlags |= ASF_PPI_FLAG_PADDING_LENGTH_FIELD_IS_BYTE; - else - iLengthTypeFlags |= ASF_PPI_FLAG_PADDING_LENGTH_FIELD_IS_WORD; - } - avio_w8(pb, iLengthTypeFlags); - - avio_w8(pb, ASF_PPI_PROPERTY_FLAGS); - - if (iLengthTypeFlags & ASF_PPI_FLAG_PADDING_LENGTH_FIELD_IS_WORD) - avio_wl16(pb, padsize - 2); - if (iLengthTypeFlags & ASF_PPI_FLAG_PADDING_LENGTH_FIELD_IS_BYTE) - avio_w8(pb, padsize - 1); - - avio_wl32(pb, sendtime); - avio_wl16(pb, duration); - if (asf->multi_payloads_present) - avio_w8(pb, nb_payloads | ASF_PAYLOAD_FLAGS); - - ppi_size = avio_tell(pb) - start; - - return ppi_size; -} - -static void flush_packet(AVFormatContext *s) -{ - ASFContext *asf = s->priv_data; - int packet_hdr_size, packet_filled_size; - - assert(asf->packet_timestamp_end >= asf->packet_timestamp_start); - - if (asf->is_streamed) - put_chunk(s, 0x4424, s->packet_size, 0); - - packet_hdr_size = put_payload_parsing_info(s, - asf->packet_timestamp_start, - asf->packet_timestamp_end - asf->packet_timestamp_start, - asf->packet_nb_payloads, - asf->packet_size_left); - - packet_filled_size = PACKET_SIZE - asf->packet_size_left; - assert(packet_hdr_size <= asf->packet_size_left); - memset(asf->packet_buf + packet_filled_size, 0, asf->packet_size_left); - - avio_write(s->pb, asf->packet_buf, s->packet_size - packet_hdr_size); - - avio_flush(s->pb); - asf->nb_packets++; - asf->packet_nb_payloads = 0; - asf->packet_timestamp_start = -1; - asf->packet_timestamp_end = -1; - ffio_init_context(&asf->pb, asf->packet_buf, s->packet_size, 1, - NULL, NULL, NULL, NULL); -} - -static void put_payload_header(AVFormatContext *s, ASFStream *stream, - int64_t presentation_time, int m_obj_size, - int m_obj_offset, int payload_len, int flags) -{ - ASFContext *asf = s->priv_data; - AVIOContext *pb = &asf->pb; - int val; - - val = stream->num; - if (flags & AV_PKT_FLAG_KEY) - val |= ASF_PL_FLAG_KEY_FRAME; - avio_w8(pb, val); - - avio_w8(pb, stream->seq); // Media object number - avio_wl32(pb, m_obj_offset); // Offset Into Media Object - - // Replicated Data shall be at least 8 bytes long. - // The first 4 bytes of data shall contain the - // Size of the Media Object that the payload belongs to. - // The next 4 bytes of data shall contain the - // Presentation Time for the media object that the payload belongs to. - avio_w8(pb, ASF_PAYLOAD_REPLICATED_DATA_LENGTH); - - avio_wl32(pb, m_obj_size); // Replicated Data - Media Object Size - avio_wl32(pb, (uint32_t) presentation_time); // Replicated Data - Presentation Time - - if (asf->multi_payloads_present) { - avio_wl16(pb, payload_len); // payload length - } -} - -static void put_frame(AVFormatContext *s, ASFStream *stream, AVStream *avst, - int64_t timestamp, const uint8_t *buf, - int m_obj_size, int flags) -{ - ASFContext *asf = s->priv_data; - int m_obj_offset, payload_len, frag_len1; - - m_obj_offset = 0; - while (m_obj_offset < m_obj_size) { - payload_len = m_obj_size - m_obj_offset; - if (asf->packet_timestamp_start == -1) { - asf->multi_payloads_present = (payload_len < MULTI_PAYLOAD_CONSTANT); - - asf->packet_size_left = PACKET_SIZE; - if (asf->multi_payloads_present) { - frag_len1 = MULTI_PAYLOAD_CONSTANT - 1; - } else { - frag_len1 = SINGLE_PAYLOAD_DATA_LENGTH; - } - asf->packet_timestamp_start = timestamp; - } else { - // multi payloads - frag_len1 = asf->packet_size_left - - PAYLOAD_HEADER_SIZE_MULTIPLE_PAYLOADS - - PACKET_HEADER_MIN_SIZE - 1; - - if (frag_len1 < payload_len && - avst->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - flush_packet(s); - continue; - } - } - if (frag_len1 > 0) { - if (payload_len > frag_len1) - payload_len = frag_len1; - else if (payload_len == (frag_len1 - 1)) - payload_len = frag_len1 - 2; // additional byte need to put padding length - - put_payload_header(s, stream, timestamp + PREROLL_TIME, - m_obj_size, m_obj_offset, payload_len, flags); - avio_write(&asf->pb, buf, payload_len); - - if (asf->multi_payloads_present) - asf->packet_size_left -= (payload_len + PAYLOAD_HEADER_SIZE_MULTIPLE_PAYLOADS); - else - asf->packet_size_left -= (payload_len + PAYLOAD_HEADER_SIZE_SINGLE_PAYLOAD); - asf->packet_timestamp_end = timestamp; - - asf->packet_nb_payloads++; - } else { - payload_len = 0; - } - m_obj_offset += payload_len; - buf += payload_len; - - if (!asf->multi_payloads_present) - flush_packet(s); - else if (asf->packet_size_left <= (PAYLOAD_HEADER_SIZE_MULTIPLE_PAYLOADS + PACKET_HEADER_MIN_SIZE + 1)) - flush_packet(s); - } - stream->seq++; -} - -static void update_index(AVFormatContext *s, int start_sec, - uint32_t packet_number, uint16_t packet_count) -{ - ASFContext *asf = s->priv_data; - - if (start_sec > asf->next_start_sec) { - int i; - - if (!asf->next_start_sec) { - asf->next_packet_number = packet_number; - asf->next_packet_count = packet_count; - } - - if (start_sec > asf->nb_index_memory_alloc) { - asf->nb_index_memory_alloc = (start_sec + ASF_INDEX_BLOCK) & ~(ASF_INDEX_BLOCK - 1); - asf->index_ptr = av_realloc( asf->index_ptr, sizeof(ASFIndex) * asf->nb_index_memory_alloc ); - } - for (i = asf->next_start_sec; i < start_sec; i++) { - asf->index_ptr[i].packet_number = asf->next_packet_number; - asf->index_ptr[i].packet_count = asf->next_packet_count; - } - } - asf->maximum_packet = FFMAX(asf->maximum_packet, packet_count); - asf->next_packet_number = packet_number; - asf->next_packet_count = packet_count; - asf->next_start_sec = start_sec; -} - -static int asf_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - ASFContext *asf = s->priv_data; - ASFStream *stream; - AVCodecContext *codec; - uint32_t packet_number; - int64_t pts; - int start_sec; - int flags = pkt->flags; - - codec = s->streams[pkt->stream_index]->codec; - stream = &asf->streams[pkt->stream_index]; - - if (codec->codec_type == AVMEDIA_TYPE_AUDIO) - flags &= ~AV_PKT_FLAG_KEY; - - pts = (pkt->pts != AV_NOPTS_VALUE) ? pkt->pts : pkt->dts; - assert(pts != AV_NOPTS_VALUE); - pts *= 10000; - asf->duration = FFMAX(asf->duration, pts + pkt->duration * 10000); - - packet_number = asf->nb_packets; - put_frame(s, stream, s->streams[pkt->stream_index], - pkt->dts, pkt->data, pkt->size, flags); - - start_sec = (int)((PREROLL_TIME * 10000 + pts + ASF_INDEXED_INTERVAL - 1) - / ASF_INDEXED_INTERVAL); - - /* check index */ - if ((!asf->is_streamed) && (flags & AV_PKT_FLAG_KEY)) { - uint16_t packet_count = asf->nb_packets - packet_number; - update_index(s, start_sec, packet_number, packet_count); - } - asf->end_sec = start_sec; - - return 0; -} - -static int asf_write_index(AVFormatContext *s, ASFIndex *index, - uint16_t max, uint32_t count) -{ - AVIOContext *pb = s->pb; - int i; - - ff_put_guid(pb, &ff_asf_simple_index_header); - avio_wl64(pb, 24 + 16 + 8 + 4 + 4 + (4 + 2) * count); - ff_put_guid(pb, &ff_asf_my_guid); - avio_wl64(pb, ASF_INDEXED_INTERVAL); - avio_wl32(pb, max); - avio_wl32(pb, count); - for (i = 0; i < count; i++) { - avio_wl32(pb, index[i].packet_number); - avio_wl16(pb, index[i].packet_count); - } - - return 0; -} - -static int asf_write_trailer(AVFormatContext *s) -{ - ASFContext *asf = s->priv_data; - int64_t file_size, data_size; - - /* flush the current packet */ - if (asf->pb.buf_ptr > asf->pb.buffer) - flush_packet(s); - - /* write index */ - data_size = avio_tell(s->pb); - if (!asf->is_streamed && asf->next_start_sec) { - update_index(s, asf->end_sec + 1, 0, 0); - asf_write_index(s, asf->index_ptr, asf->maximum_packet, asf->next_start_sec); - } - avio_flush(s->pb); - - if (asf->is_streamed || !s->pb->seekable) { - put_chunk(s, 0x4524, 0, 0); /* end of stream */ - } else { - /* rewrite an updated header */ - file_size = avio_tell(s->pb); - avio_seek(s->pb, 0, SEEK_SET); - asf_write_header1(s, file_size, data_size - asf->data_offset); - } - - av_free(asf->index_ptr); - return 0; -} - -#if CONFIG_ASF_MUXER -AVOutputFormat ff_asf_muxer = { - .name = "asf", - .long_name = NULL_IF_CONFIG_SMALL("ASF (Advanced / Active Streaming Format)"), - .mime_type = "video/x-ms-asf", - .extensions = "asf,wmv,wma", - .priv_data_size = sizeof(ASFContext), - .audio_codec = AV_CODEC_ID_WMAV2, - .video_codec = AV_CODEC_ID_MSMPEG4V3, - .write_header = asf_write_header, - .write_packet = asf_write_packet, - .write_trailer = asf_write_trailer, - .flags = AVFMT_GLOBALHEADER, - .codec_tag = (const AVCodecTag * const []) { - codec_asf_bmp_tags, ff_codec_bmp_tags, ff_codec_wav_tags, 0 - }, -}; -#endif /* CONFIG_ASF_MUXER */ - -#if CONFIG_ASF_STREAM_MUXER -AVOutputFormat ff_asf_stream_muxer = { - .name = "asf_stream", - .long_name = NULL_IF_CONFIG_SMALL("ASF (Advanced / Active Streaming Format)"), - .mime_type = "video/x-ms-asf", - .extensions = "asf,wmv,wma", - .priv_data_size = sizeof(ASFContext), - .audio_codec = AV_CODEC_ID_WMAV2, - .video_codec = AV_CODEC_ID_MSMPEG4V3, - .write_header = asf_write_stream_header, - .write_packet = asf_write_packet, - .write_trailer = asf_write_trailer, - .flags = AVFMT_GLOBALHEADER, - .codec_tag = (const AVCodecTag * const []) { - codec_asf_bmp_tags, ff_codec_bmp_tags, ff_codec_wav_tags, 0 - }, -}; -#endif /* CONFIG_ASF_STREAM_MUXER */ diff --git a/ffmpeg1/libavformat/assdec.c b/ffmpeg1/libavformat/assdec.c deleted file mode 100644 index 35fcb51..0000000 --- a/ffmpeg1/libavformat/assdec.c +++ /dev/null @@ -1,169 +0,0 @@ -/* - * SSA/ASS demuxer - * Copyright (c) 2008 Michael Niedermayer - * - * 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 "internal.h" -#include "subtitles.h" -#include "libavcodec/internal.h" -#include "libavutil/bprint.h" - -typedef struct ASSContext{ - FFDemuxSubtitlesQueue q; -}ASSContext; - -static int ass_probe(AVProbeData *p) -{ - const char *header= "[Script Info]"; - - if( !memcmp(p->buf , header, strlen(header)) - || !memcmp(p->buf+3, header, strlen(header))) - return AVPROBE_SCORE_MAX; - - return 0; -} - -static int ass_read_close(AVFormatContext *s) -{ - ASSContext *ass = s->priv_data; - ff_subtitles_queue_clean(&ass->q); - return 0; -} - -static int read_ts(const uint8_t *p, int64_t *start, int *duration) -{ - int64_t end; - int hh1, mm1, ss1, ms1; - int hh2, mm2, ss2, ms2; - - if (sscanf(p, "%*[^,],%d:%d:%d%*c%d,%d:%d:%d%*c%d", - &hh1, &mm1, &ss1, &ms1, - &hh2, &mm2, &ss2, &ms2) == 8) { - end = (hh2*3600LL + mm2*60LL + ss2) * 100LL + ms2; - *start = (hh1*3600LL + mm1*60LL + ss1) * 100LL + ms1; - *duration = end - *start; - return 0; - } - return -1; -} - -static int64_t get_line(AVBPrint *buf, AVIOContext *pb) -{ - int64_t pos = avio_tell(pb); - - av_bprint_clear(buf); - for (;;) { - char c = avio_r8(pb); - if (!c) - break; - av_bprint_chars(buf, c, 1); - if (c == '\n') - break; - } - return pos; -} - -static int ass_read_header(AVFormatContext *s) -{ - ASSContext *ass = s->priv_data; - AVBPrint header, line; - int header_remaining, res = 0; - AVStream *st; - - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - avpriv_set_pts_info(st, 64, 1, 100); - st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE; - st->codec->codec_id= AV_CODEC_ID_SSA; - - header_remaining= INT_MAX; - - av_bprint_init(&header, 0, AV_BPRINT_SIZE_UNLIMITED); - av_bprint_init(&line, 0, AV_BPRINT_SIZE_UNLIMITED); - - for (;;) { - int64_t pos = get_line(&line, s->pb); - - if (!line.str[0]) // EOF - break; - - if (!memcmp(line.str, "[Events]", 8)) - header_remaining= 2; - else if (line.str[0]=='[') - header_remaining= INT_MAX; - - if (header_remaining) { - av_bprintf(&header, "%s", line.str); - header_remaining--; - } else { - int64_t ts_start = AV_NOPTS_VALUE; - int duration = -1; - AVPacket *sub; - - if (read_ts(line.str, &ts_start, &duration) < 0) - continue; - sub = ff_subtitles_queue_insert(&ass->q, line.str, line.len, 0); - if (!sub) { - res = AVERROR(ENOMEM); - goto end; - } - sub->pos = pos; - sub->pts = ts_start; - sub->duration = duration; - } - } - - av_bprint_finalize(&line, NULL); - - res = avpriv_bprint_to_extradata(st->codec, &header); - if (res < 0) - goto end; - - ff_subtitles_queue_finalize(&ass->q); - -end: - return res; -} - -static int ass_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - ASSContext *ass = s->priv_data; - return ff_subtitles_queue_read_packet(&ass->q, pkt); -} - -static int ass_read_seek(AVFormatContext *s, int stream_index, - int64_t min_ts, int64_t ts, int64_t max_ts, int flags) -{ - ASSContext *ass = s->priv_data; - return ff_subtitles_queue_seek(&ass->q, s, stream_index, - min_ts, ts, max_ts, flags); -} - -AVInputFormat ff_ass_demuxer = { - .name = "ass", - .long_name = NULL_IF_CONFIG_SMALL("SSA (SubStation Alpha) subtitle"), - .priv_data_size = sizeof(ASSContext), - .read_probe = ass_probe, - .read_header = ass_read_header, - .read_packet = ass_read_packet, - .read_close = ass_read_close, - .read_seek2 = ass_read_seek, -}; diff --git a/ffmpeg1/libavformat/assenc.c b/ffmpeg1/libavformat/assenc.c deleted file mode 100644 index bda507d..0000000 --- a/ffmpeg1/libavformat/assenc.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * SSA/ASS muxer - * Copyright (c) 2008 Michael Niedermayer - * - * 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" - -typedef struct ASSContext{ - unsigned int extra_index; -}ASSContext; - -static int write_header(AVFormatContext *s) -{ - ASSContext *ass = s->priv_data; - AVCodecContext *avctx= s->streams[0]->codec; - uint8_t *last= NULL; - - if(s->nb_streams != 1 || avctx->codec_id != AV_CODEC_ID_SSA){ - av_log(s, AV_LOG_ERROR, "Exactly one ASS/SSA stream is needed.\n"); - return -1; - } - - while(ass->extra_index < avctx->extradata_size){ - uint8_t *p = avctx->extradata + ass->extra_index; - uint8_t *end= strchr(p, '\n'); - if(!end) end= avctx->extradata + avctx->extradata_size; - else end++; - - avio_write(s->pb, p, end-p); - ass->extra_index += end-p; - - if(last && !memcmp(last, "[Events]", 8)) - break; - last=p; - } - - avio_flush(s->pb); - - return 0; -} - -static int write_packet(AVFormatContext *s, AVPacket *pkt) -{ - avio_write(s->pb, pkt->data, pkt->size); - - avio_flush(s->pb); - - return 0; -} - -static int write_trailer(AVFormatContext *s) -{ - ASSContext *ass = s->priv_data; - AVCodecContext *avctx= s->streams[0]->codec; - - avio_write(s->pb, avctx->extradata + ass->extra_index, - avctx->extradata_size - ass->extra_index); - - return 0; -} - -AVOutputFormat ff_ass_muxer = { - .name = "ass", - .long_name = NULL_IF_CONFIG_SMALL("SSA (SubStation Alpha) subtitle"), - .mime_type = "text/x-ssa", - .extensions = "ass,ssa", - .priv_data_size = sizeof(ASSContext), - .subtitle_codec = AV_CODEC_ID_SSA, - .write_header = write_header, - .write_packet = write_packet, - .write_trailer = write_trailer, - .flags = AVFMT_GLOBALHEADER | AVFMT_NOTIMESTAMPS | AVFMT_TS_NONSTRICT, -}; diff --git a/ffmpeg1/libavformat/ast.c b/ffmpeg1/libavformat/ast.c deleted file mode 100644 index 9de74aa..0000000 --- a/ffmpeg1/libavformat/ast.c +++ /dev/null @@ -1,29 +0,0 @@ -/* - * AST common code - * Copyright (c) 2012 James Almer - * - * 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 "internal.h" - -const AVCodecTag ff_codec_ast_tags[] = { - { AV_CODEC_ID_ADPCM_AFC, 0 }, - { AV_CODEC_ID_PCM_S16BE_PLANAR, 1 }, - { AV_CODEC_ID_NONE, 0 }, -}; diff --git a/ffmpeg1/libavformat/ast.h b/ffmpeg1/libavformat/ast.h deleted file mode 100644 index 4a399ea..0000000 --- a/ffmpeg1/libavformat/ast.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * AST common code - * Copyright (c) 2012 James Almer - * - * 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 AVFORMAT_AST_H -#define AVFORMAT_AST_H - -#include "avformat.h" -#include "internal.h" - -extern const AVCodecTag ff_codec_ast_tags[]; - -#endif /* AVFORMAT_AST_H */ diff --git a/ffmpeg1/libavformat/astdec.c b/ffmpeg1/libavformat/astdec.c deleted file mode 100644 index 8862744..0000000 --- a/ffmpeg1/libavformat/astdec.c +++ /dev/null @@ -1,119 +0,0 @@ -/* - * AST demuxer - * Copyright (c) 2012 Paul B Mahol - * - * 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 "libavutil/channel_layout.h" -#include "libavutil/intreadwrite.h" -#include "avformat.h" -#include "internal.h" -#include "ast.h" - -static int ast_probe(AVProbeData *p) -{ - if (AV_RL32(p->buf) == MKTAG('S','T','R','M') && - AV_RB16(p->buf + 10) && - AV_RB16(p->buf + 12) && - AV_RB32(p->buf + 16)) - return AVPROBE_SCORE_MAX / 3 * 2; - return 0; -} - -static int ast_read_header(AVFormatContext *s) -{ - int depth; - AVStream *st; - - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - - avio_skip(s->pb, 8); - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = ff_codec_get_id(ff_codec_ast_tags, avio_rb16(s->pb)); - - depth = avio_rb16(s->pb); - if (depth != 16) { - avpriv_request_sample(s, "depth %d", depth); - return AVERROR_INVALIDDATA; - } - - st->codec->channels = avio_rb16(s->pb); - if (!st->codec->channels) - return AVERROR_INVALIDDATA; - - if (st->codec->channels == 2) - st->codec->channel_layout = AV_CH_LAYOUT_STEREO; - else if (st->codec->channels == 4) - st->codec->channel_layout = AV_CH_LAYOUT_4POINT0; - - avio_skip(s->pb, 2); - st->codec->sample_rate = avio_rb32(s->pb); - if (st->codec->sample_rate <= 0) - return AVERROR_INVALIDDATA; - st->start_time = 0; - st->duration = avio_rb32(s->pb); - avio_skip(s->pb, 40); - avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); - - return 0; -} - -static int ast_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - uint32_t type, size; - int64_t pos; - int ret; - - if (url_feof(s->pb)) - return AVERROR_EOF; - - pos = avio_tell(s->pb); - type = avio_rl32(s->pb); - size = avio_rb32(s->pb); - if (size > INT_MAX / s->streams[0]->codec->channels) - return AVERROR_INVALIDDATA; - - size *= s->streams[0]->codec->channels; - if ((ret = avio_skip(s->pb, 24)) < 0) // padding - return ret; - - if (type == MKTAG('B','L','C','K')) { - ret = av_get_packet(s->pb, pkt, size); - pkt->stream_index = 0; - pkt->pos = pos; - } else { - av_log(s, AV_LOG_ERROR, "unknown chunk %x\n", type); - avio_skip(s->pb, size); - ret = AVERROR_INVALIDDATA; - } - - return ret; -} - -AVInputFormat ff_ast_demuxer = { - .name = "ast", - .long_name = NULL_IF_CONFIG_SMALL("AST (Audio Stream)"), - .read_probe = ast_probe, - .read_header = ast_read_header, - .read_packet = ast_read_packet, - .extensions = "ast", - .flags = AVFMT_GENERIC_INDEX, - .codec_tag = (const AVCodecTag* const []){ff_codec_ast_tags, 0}, -}; diff --git a/ffmpeg1/libavformat/astenc.c b/ffmpeg1/libavformat/astenc.c deleted file mode 100644 index edd802c..0000000 --- a/ffmpeg1/libavformat/astenc.c +++ /dev/null @@ -1,214 +0,0 @@ -/* - * AST muxer - * Copyright (c) 2012 James Almer - * - * 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 "avio_internal.h" -#include "internal.h" -#include "ast.h" -#include "libavutil/mathematics.h" -#include "libavutil/opt.h" - -typedef struct ASTMuxContext { - AVClass *class; - int64_t size; - int64_t samples; - int64_t loopstart; - int64_t loopend; - int fbs; -} ASTMuxContext; - -#define CHECK_LOOP(type) \ - if (ast->loop ## type > 0) { \ - ast->loop ## type = av_rescale_rnd(ast->loop ## type, enc->sample_rate, 1000, AV_ROUND_DOWN); \ - if (ast->loop ## type < 0 || ast->loop ## type > UINT_MAX) { \ - av_log(s, AV_LOG_ERROR, "Invalid loop" #type " value\n"); \ - return AVERROR(EINVAL); \ - } \ - } - -static int ast_write_header(AVFormatContext *s) -{ - ASTMuxContext *ast = s->priv_data; - AVIOContext *pb = s->pb; - AVCodecContext *enc; - unsigned int codec_tag; - - if (s->nb_streams == 1) { - enc = s->streams[0]->codec; - } else { - av_log(s, AV_LOG_ERROR, "only one stream is supported\n"); - return AVERROR(EINVAL); - } - - if (enc->codec_id == AV_CODEC_ID_ADPCM_AFC) { - av_log(s, AV_LOG_ERROR, "muxing ADPCM AFC is not implemented\n"); - return AVERROR_PATCHWELCOME; - } - - codec_tag = ff_codec_get_tag(ff_codec_ast_tags, enc->codec_id); - if (!codec_tag) { - av_log(s, AV_LOG_ERROR, "unsupported codec\n"); - return AVERROR(EINVAL); - } - - if (ast->loopend > 0 && ast->loopstart >= ast->loopend) { - av_log(s, AV_LOG_ERROR, "loopend can't be less or equal to loopstart\n"); - return AVERROR(EINVAL); - } - - /* Convert milliseconds to samples */ - CHECK_LOOP(start) - CHECK_LOOP(end) - - ffio_wfourcc(pb, "STRM"); - - ast->size = avio_tell(pb); - avio_wb32(pb, 0); /* File size minus header */ - avio_wb16(pb, codec_tag); - avio_wb16(pb, 16); /* Bit depth */ - avio_wb16(pb, enc->channels); - avio_wb16(pb, 0); /* Loop flag */ - avio_wb32(pb, enc->sample_rate); - - ast->samples = avio_tell(pb); - avio_wb32(pb, 0); /* Number of samples */ - avio_wb32(pb, 0); /* Loopstart */ - avio_wb32(pb, 0); /* Loopend */ - avio_wb32(pb, 0); /* Size of first block */ - - /* Unknown */ - avio_wb32(pb, 0); - avio_wl32(pb, 0x7F); - avio_wb64(pb, 0); - avio_wb64(pb, 0); - avio_wb32(pb, 0); - - avio_flush(pb); - - return 0; -} - -static int ast_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - AVIOContext *pb = s->pb; - ASTMuxContext *ast = s->priv_data; - AVCodecContext *enc = s->streams[0]->codec; - int size = pkt->size / enc->channels; - - if (enc->frame_number == 1) - ast->fbs = size; - - ffio_wfourcc(pb, "BLCK"); - avio_wb32(pb, size); /* Block size */ - - /* padding */ - avio_wb64(pb, 0); - avio_wb64(pb, 0); - avio_wb64(pb, 0); - - avio_write(pb, pkt->data, pkt->size); - - return 0; -} - -static int ast_write_trailer(AVFormatContext *s) -{ - AVIOContext *pb = s->pb; - ASTMuxContext *ast = s->priv_data; - AVCodecContext *enc = s->streams[0]->codec; - int64_t file_size = avio_tell(pb); - int64_t samples = (file_size - 64 - (32 * enc->frame_number)) / enc->block_align; /* PCM_S16BE_PLANAR */ - - av_log(s, AV_LOG_DEBUG, "total samples: %"PRId64"\n", samples); - - if (s->pb->seekable) { - /* Number of samples */ - avio_seek(pb, ast->samples, SEEK_SET); - avio_wb32(pb, samples); - - /* Loopstart if provided */ - if (ast->loopstart > 0) { - if (ast->loopstart >= samples) { - av_log(s, AV_LOG_WARNING, "Loopstart value is out of range and will be ignored\n"); - ast->loopstart = -1; - avio_skip(pb, 4); - } else - avio_wb32(pb, ast->loopstart); - } else - avio_skip(pb, 4); - - /* Loopend if provided. Otherwise number of samples again */ - if (ast->loopend && ast->loopstart >= 0) { - if (ast->loopend > samples) { - av_log(s, AV_LOG_WARNING, "Loopend value is out of range and will be ignored\n"); - ast->loopend = samples; - } - avio_wb32(pb, ast->loopend); - } else { - avio_wb32(pb, samples); - } - - /* Size of first block */ - avio_wb32(pb, ast->fbs); - - /* File size minus header */ - avio_seek(pb, ast->size, SEEK_SET); - avio_wb32(pb, file_size - 64); - - /* Loop flag */ - if (ast->loopstart >= 0) { - avio_skip(pb, 6); - avio_wb16(pb, 0xFFFF); - } - - avio_seek(pb, file_size, SEEK_SET); - avio_flush(pb); - } - return 0; -} - -#define OFFSET(obj) offsetof(ASTMuxContext, obj) -static const AVOption options[] = { - { "loopstart", "Loopstart position in milliseconds.", OFFSET(loopstart), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM }, - { "loopend", "Loopend position in milliseconds.", OFFSET(loopend), AV_OPT_TYPE_INT64, { .i64 = 0 }, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM }, - { NULL }, -}; - -static const AVClass ast_muxer_class = { - .class_name = "AST muxer", - .item_name = av_default_item_name, - .option = options, - .version = LIBAVUTIL_VERSION_INT, -}; - -AVOutputFormat ff_ast_muxer = { - .name = "ast", - .long_name = NULL_IF_CONFIG_SMALL("AST (Audio Stream)"), - .extensions = "ast", - .priv_data_size = sizeof(ASTMuxContext), - .audio_codec = AV_CODEC_ID_PCM_S16BE_PLANAR, - .video_codec = AV_CODEC_ID_NONE, - .write_header = ast_write_header, - .write_packet = ast_write_packet, - .write_trailer = ast_write_trailer, - .priv_class = &ast_muxer_class, - .codec_tag = (const AVCodecTag* const []){ff_codec_ast_tags, 0}, -}; diff --git a/ffmpeg1/libavformat/au.c b/ffmpeg1/libavformat/au.c deleted file mode 100644 index a29e802..0000000 --- a/ffmpeg1/libavformat/au.c +++ /dev/null @@ -1,211 +0,0 @@ -/* - * AU muxer and demuxer - * 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 - */ - -/* - * First version by Francois Revol revol@free.fr - * - * Reference documents: - * http://www.opengroup.org/public/pubs/external/auformat.html - * http://www.goice.co.jp/member/mo/formats/au.html - */ - -#include "avformat.h" -#include "internal.h" -#include "avio_internal.h" -#include "pcm.h" - -/* if we don't know the size in advance */ -#define AU_UNKNOWN_SIZE ((uint32_t)(~0)) -/* the specification requires an annotation field of at least eight bytes */ -#define AU_HEADER_SIZE (24+8) - -static const AVCodecTag codec_au_tags[] = { - { AV_CODEC_ID_PCM_MULAW, 1 }, - { AV_CODEC_ID_PCM_S8, 2 }, - { AV_CODEC_ID_PCM_S16BE, 3 }, - { AV_CODEC_ID_PCM_S24BE, 4 }, - { AV_CODEC_ID_PCM_S32BE, 5 }, - { AV_CODEC_ID_PCM_F32BE, 6 }, - { AV_CODEC_ID_PCM_F64BE, 7 }, - { AV_CODEC_ID_ADPCM_G722,24 }, - { AV_CODEC_ID_PCM_ALAW, 27 }, - { AV_CODEC_ID_NONE, 0 }, -}; - -#if CONFIG_AU_DEMUXER - -static int au_probe(AVProbeData *p) -{ - if (p->buf[0] == '.' && p->buf[1] == 's' && - p->buf[2] == 'n' && p->buf[3] == 'd') - return AVPROBE_SCORE_MAX; - else - return 0; -} - -#define BLOCK_SIZE 1024 - -static int au_read_header(AVFormatContext *s) -{ - int size, data_size = 0; - unsigned int tag; - AVIOContext *pb = s->pb; - unsigned int id, channels, rate; - int bps; - enum AVCodecID codec; - AVStream *st; - - tag = avio_rl32(pb); - if (tag != MKTAG('.', 's', 'n', 'd')) - return AVERROR_INVALIDDATA; - size = avio_rb32(pb); /* header size */ - data_size = avio_rb32(pb); /* data size in bytes */ - - if (data_size < 0 && data_size != AU_UNKNOWN_SIZE) { - av_log(s, AV_LOG_ERROR, "Invalid negative data size '%d' found\n", data_size); - return AVERROR_INVALIDDATA; - } - - id = avio_rb32(pb); - rate = avio_rb32(pb); - channels = avio_rb32(pb); - - if (size > 24) { - /* skip unused data */ - avio_skip(pb, size - 24); - } - - codec = ff_codec_get_id(codec_au_tags, id); - - if (codec == AV_CODEC_ID_NONE) { - avpriv_request_sample(s, "unknown or unsupported codec tag: %u", id); - return AVERROR_PATCHWELCOME; - } - - bps = av_get_bits_per_sample(codec); - if (!bps) { - avpriv_request_sample(s, "Unknown bits per sample"); - return AVERROR_PATCHWELCOME; - } - - if (channels == 0 || channels >= INT_MAX / (BLOCK_SIZE * bps >> 3)) { - av_log(s, AV_LOG_ERROR, "Invalid number of channels %u\n", channels); - return AVERROR_INVALIDDATA; - } - - if (rate == 0 || rate > INT_MAX) { - av_log(s, AV_LOG_ERROR, "Invalid sample rate: %u\n", rate); - return AVERROR_INVALIDDATA; - } - - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_tag = id; - st->codec->codec_id = codec; - st->codec->channels = channels; - st->codec->sample_rate = rate; - st->codec->bit_rate = channels * rate * bps; - st->codec->block_align = FFMAX(bps * st->codec->channels / 8, 1); - if (data_size != AU_UNKNOWN_SIZE) - st->duration = (((int64_t)data_size)<<3) / (st->codec->channels * (int64_t)bps); - - st->start_time = 0; - avpriv_set_pts_info(st, 64, 1, rate); - - return 0; -} - -AVInputFormat ff_au_demuxer = { - .name = "au", - .long_name = NULL_IF_CONFIG_SMALL("Sun AU"), - .read_probe = au_probe, - .read_header = au_read_header, - .read_packet = ff_pcm_read_packet, - .read_seek = ff_pcm_read_seek, - .codec_tag = (const AVCodecTag* const []) { codec_au_tags, 0 }, -}; - -#endif /* CONFIG_AU_DEMUXER */ - -#if CONFIG_AU_MUXER - -#include "rawenc.h" - -static int au_write_header(AVFormatContext *s) -{ - AVIOContext *pb = s->pb; - AVCodecContext *enc = s->streams[0]->codec; - - if (s->nb_streams != 1) { - av_log(s, AV_LOG_ERROR, "only one stream is supported\n"); - return AVERROR(EINVAL); - } - - enc->codec_tag = ff_codec_get_tag(codec_au_tags, enc->codec_id); - if (!enc->codec_tag) { - av_log(s, AV_LOG_ERROR, "unsupported codec\n"); - return AVERROR(EINVAL); - } - - ffio_wfourcc(pb, ".snd"); /* magic number */ - avio_wb32(pb, AU_HEADER_SIZE); /* header size */ - avio_wb32(pb, AU_UNKNOWN_SIZE); /* data size */ - avio_wb32(pb, enc->codec_tag); /* codec ID */ - avio_wb32(pb, enc->sample_rate); - avio_wb32(pb, enc->channels); - avio_wb64(pb, 0); /* annotation field */ - avio_flush(pb); - - return 0; -} - -static int au_write_trailer(AVFormatContext *s) -{ - AVIOContext *pb = s->pb; - int64_t file_size = avio_tell(pb); - - if (s->pb->seekable && file_size < INT32_MAX) { - /* update file size */ - avio_seek(pb, 8, SEEK_SET); - avio_wb32(pb, (uint32_t)(file_size - AU_HEADER_SIZE)); - avio_seek(pb, file_size, SEEK_SET); - avio_flush(pb); - } - - return 0; -} - -AVOutputFormat ff_au_muxer = { - .name = "au", - .long_name = NULL_IF_CONFIG_SMALL("Sun AU"), - .mime_type = "audio/basic", - .extensions = "au", - .audio_codec = AV_CODEC_ID_PCM_S16BE, - .video_codec = AV_CODEC_ID_NONE, - .write_header = au_write_header, - .write_packet = ff_raw_write_packet, - .write_trailer = au_write_trailer, - .codec_tag = (const AVCodecTag* const []) { codec_au_tags, 0 }, -}; - -#endif /* CONFIG_AU_MUXER */ diff --git a/ffmpeg1/libavformat/audiointerleave.c b/ffmpeg1/libavformat/audiointerleave.c deleted file mode 100644 index 35dd8d5..0000000 --- a/ffmpeg1/libavformat/audiointerleave.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Audio Interleaving functions - * - * Copyright (c) 2009 Baptiste Coudurier - * - * 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 "libavutil/fifo.h" -#include "libavutil/mathematics.h" -#include "avformat.h" -#include "audiointerleave.h" -#include "internal.h" - -void ff_audio_interleave_close(AVFormatContext *s) -{ - int i; - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - AudioInterleaveContext *aic = st->priv_data; - - if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) - av_fifo_free(aic->fifo); - } -} - -int ff_audio_interleave_init(AVFormatContext *s, - const int *samples_per_frame, - AVRational time_base) -{ - int i; - - if (!samples_per_frame) - return -1; - - if (!time_base.num) { - av_log(s, AV_LOG_ERROR, "timebase not set for audio interleave\n"); - return -1; - } - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - AudioInterleaveContext *aic = st->priv_data; - - if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - aic->sample_size = (st->codec->channels * - av_get_bits_per_sample(st->codec->codec_id)) / 8; - if (!aic->sample_size) { - av_log(s, AV_LOG_ERROR, "could not compute sample size\n"); - return -1; - } - aic->samples_per_frame = samples_per_frame; - aic->samples = aic->samples_per_frame; - aic->time_base = time_base; - - aic->fifo_size = 100* *aic->samples; - aic->fifo= av_fifo_alloc(100 * *aic->samples); - } - } - - return 0; -} - -static int ff_interleave_new_audio_packet(AVFormatContext *s, AVPacket *pkt, - int stream_index, int flush) -{ - AVStream *st = s->streams[stream_index]; - AudioInterleaveContext *aic = st->priv_data; - - int size = FFMIN(av_fifo_size(aic->fifo), *aic->samples * aic->sample_size); - if (!size || (!flush && size == av_fifo_size(aic->fifo))) - return 0; - - if (av_new_packet(pkt, size) < 0) - return AVERROR(ENOMEM); - av_fifo_generic_read(aic->fifo, pkt->data, size, NULL); - - pkt->dts = pkt->pts = aic->dts; - pkt->duration = av_rescale_q(*aic->samples, st->time_base, aic->time_base); - pkt->stream_index = stream_index; - aic->dts += pkt->duration; - - aic->samples++; - if (!*aic->samples) - aic->samples = aic->samples_per_frame; - - return size; -} - -int ff_audio_rechunk_interleave(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush, - int (*get_packet)(AVFormatContext *, AVPacket *, AVPacket *, int), - int (*compare_ts)(AVFormatContext *, AVPacket *, AVPacket *)) -{ - int i; - - if (pkt) { - AVStream *st = s->streams[pkt->stream_index]; - AudioInterleaveContext *aic = st->priv_data; - if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - unsigned new_size = av_fifo_size(aic->fifo) + pkt->size; - if (new_size > aic->fifo_size) { - if (av_fifo_realloc2(aic->fifo, new_size) < 0) - return -1; - aic->fifo_size = new_size; - } - av_fifo_generic_write(aic->fifo, pkt->data, pkt->size, NULL); - } else { - int ret; - // rewrite pts and dts to be decoded time line position - pkt->pts = pkt->dts = aic->dts; - aic->dts += pkt->duration; - ret = ff_interleave_add_packet(s, pkt, compare_ts); - if (ret < 0) - return ret; - } - pkt = NULL; - } - - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - AVPacket new_pkt; - int ret; - while ((ret = ff_interleave_new_audio_packet(s, &new_pkt, i, flush)) > 0) { - ret = ff_interleave_add_packet(s, &new_pkt, compare_ts); - if (ret < 0) - return ret; - } - if (ret < 0) - return ret; - } - } - - return get_packet(s, out, NULL, flush); -} diff --git a/ffmpeg1/libavformat/audiointerleave.h b/ffmpeg1/libavformat/audiointerleave.h deleted file mode 100644 index 4d77832..0000000 --- a/ffmpeg1/libavformat/audiointerleave.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * audio interleaving prototypes and declarations - * - * Copyright (c) 2009 Baptiste Coudurier - * - * 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 AVFORMAT_AUDIOINTERLEAVE_H -#define AVFORMAT_AUDIOINTERLEAVE_H - -#include "libavutil/fifo.h" -#include "avformat.h" - -typedef struct AudioInterleaveContext { - AVFifoBuffer *fifo; - unsigned fifo_size; ///< size of currently allocated FIFO - uint64_t dts; ///< current dts - int sample_size; ///< size of one sample all channels included - const int *samples_per_frame; ///< must be 0-terminated - const int *samples; ///< current samples per frame, pointer to samples_per_frame - AVRational time_base; ///< time base of output audio packets -} AudioInterleaveContext; - -int ff_audio_interleave_init(AVFormatContext *s, const int *samples_per_frame, AVRational time_base); -void ff_audio_interleave_close(AVFormatContext *s); - -/** - * Rechunk audio PCM packets per AudioInterleaveContext->samples_per_frame - * and interleave them correctly. - * The first element of AVStream->priv_data must be AudioInterleaveContext - * when using this function. - * - * @param get_packet function will output a packet when streams are correctly interleaved. - * @param compare_ts function will compare AVPackets and decide interleaving order. - */ -int ff_audio_rechunk_interleave(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush, - int (*get_packet)(AVFormatContext *, AVPacket *, AVPacket *, int), - int (*compare_ts)(AVFormatContext *, AVPacket *, AVPacket *)); - -#endif /* AVFORMAT_AUDIOINTERLEAVE_H */ diff --git a/ffmpeg1/libavformat/avc.c b/ffmpeg1/libavformat/avc.c deleted file mode 100644 index f5c513b..0000000 --- a/ffmpeg1/libavformat/avc.c +++ /dev/null @@ -1,193 +0,0 @@ -/* - * AVC helper functions for muxers - * Copyright (c) 2006 Baptiste Coudurier - * - * 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 "libavutil/intreadwrite.h" -#include "avformat.h" -#include "avio.h" -#include "avc.h" - -static const uint8_t *ff_avc_find_startcode_internal(const uint8_t *p, const uint8_t *end) -{ - const uint8_t *a = p + 4 - ((intptr_t)p & 3); - - for (end -= 3; p < a && p < end; p++) { - if (p[0] == 0 && p[1] == 0 && p[2] == 1) - return p; - } - - for (end -= 3; p < end; p += 4) { - uint32_t x = *(const uint32_t*)p; -// if ((x - 0x01000100) & (~x) & 0x80008000) // little endian -// if ((x - 0x00010001) & (~x) & 0x00800080) // big endian - if ((x - 0x01010101) & (~x) & 0x80808080) { // generic - if (p[1] == 0) { - if (p[0] == 0 && p[2] == 1) - return p; - if (p[2] == 0 && p[3] == 1) - return p+1; - } - if (p[3] == 0) { - if (p[2] == 0 && p[4] == 1) - return p+2; - if (p[4] == 0 && p[5] == 1) - return p+3; - } - } - } - - for (end += 3; p < end; p++) { - if (p[0] == 0 && p[1] == 0 && p[2] == 1) - return p; - } - - return end + 3; -} - -const uint8_t *ff_avc_find_startcode(const uint8_t *p, const uint8_t *end){ - const uint8_t *out= ff_avc_find_startcode_internal(p, end); - if(p 6) { - /* check for h264 start code */ - if (AV_RB32(data) == 0x00000001 || - AV_RB24(data) == 0x000001) { - uint8_t *buf=NULL, *end, *start; - uint32_t sps_size=0, pps_size=0; - uint8_t *sps=0, *pps=0; - - int ret = ff_avc_parse_nal_units_buf(data, &buf, &len); - if (ret < 0) - return ret; - start = buf; - end = buf + len; - - /* look for sps and pps */ - while (end - buf > 4) { - uint32_t size; - uint8_t nal_type; - size = FFMIN(AV_RB32(buf), end - buf - 4); - buf += 4; - nal_type = buf[0] & 0x1f; - - if (nal_type == 7) { /* SPS */ - sps = buf; - sps_size = size; - } else if (nal_type == 8) { /* PPS */ - pps = buf; - pps_size = size; - } - - buf += size; - } - - if (!sps || !pps || sps_size < 4 || sps_size > UINT16_MAX || pps_size > UINT16_MAX) - return AVERROR_INVALIDDATA; - - avio_w8(pb, 1); /* version */ - avio_w8(pb, sps[1]); /* profile */ - avio_w8(pb, sps[2]); /* profile compat */ - avio_w8(pb, sps[3]); /* level */ - avio_w8(pb, 0xff); /* 6 bits reserved (111111) + 2 bits nal size length - 1 (11) */ - avio_w8(pb, 0xe1); /* 3 bits reserved (111) + 5 bits number of sps (00001) */ - - avio_wb16(pb, sps_size); - avio_write(pb, sps, sps_size); - avio_w8(pb, 1); /* number of pps */ - avio_wb16(pb, pps_size); - avio_write(pb, pps, pps_size); - av_free(start); - } else { - avio_write(pb, data, len); - } - } - return 0; -} - -int ff_avc_write_annexb_extradata(const uint8_t *in, uint8_t **buf, int *size) -{ - uint16_t sps_size, pps_size; - uint8_t *out; - int out_size; - - *buf = NULL; - if (*size >= 4 && (AV_RB32(in) == 0x00000001 || AV_RB24(in) == 0x000001)) - return 0; - if (*size < 11 || in[0] != 1) - return AVERROR_INVALIDDATA; - - sps_size = AV_RB16(&in[6]); - if (11 + sps_size > *size) - return AVERROR_INVALIDDATA; - pps_size = AV_RB16(&in[9 + sps_size]); - if (11 + sps_size + pps_size > *size) - return AVERROR_INVALIDDATA; - out_size = 8 + sps_size + pps_size; - out = av_mallocz(out_size); - if (!out) - return AVERROR(ENOMEM); - AV_WB32(&out[0], 0x00000001); - memcpy(out + 4, &in[8], sps_size); - AV_WB32(&out[4 + sps_size], 0x00000001); - memcpy(out + 8 + sps_size, &in[11 + sps_size], pps_size); - *buf = out; - *size = out_size; - return 0; -} diff --git a/ffmpeg1/libavformat/avc.h b/ffmpeg1/libavformat/avc.h deleted file mode 100644 index 972e19b..0000000 --- a/ffmpeg1/libavformat/avc.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * AVC helper functions for muxers - * Copyright (c) 2008 Aurelien Jacobs - * - * 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 AVFORMAT_AVC_H -#define AVFORMAT_AVC_H - -#include -#include "avio.h" - -int ff_avc_parse_nal_units(AVIOContext *s, const uint8_t *buf, int size); -int ff_avc_parse_nal_units_buf(const uint8_t *buf_in, uint8_t **buf, int *size); -int ff_isom_write_avcc(AVIOContext *pb, const uint8_t *data, int len); -const uint8_t *ff_avc_find_startcode(const uint8_t *p, const uint8_t *end); -int ff_avc_write_annexb_extradata(const uint8_t *in, uint8_t **buf, int *size); - -#endif /* AVFORMAT_AVC_H */ diff --git a/ffmpeg1/libavformat/avformat.h b/ffmpeg1/libavformat/avformat.h deleted file mode 100644 index 4b8731c..0000000 --- a/ffmpeg1/libavformat/avformat.h +++ /dev/null @@ -1,2126 +0,0 @@ -/* - * 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 AVFORMAT_AVFORMAT_H -#define AVFORMAT_AVFORMAT_H - -/** - * @file - * @ingroup libavf - * Main libavformat public API header - */ - -/** - * @defgroup libavf I/O and Muxing/Demuxing Library - * @{ - * - * Libavformat (lavf) is a library for dealing with various media container - * formats. Its main two purposes are demuxing - i.e. splitting a media file - * into component streams, and the reverse process of muxing - writing supplied - * data in a specified container format. It also has an @ref lavf_io - * "I/O module" which supports a number of protocols for accessing the data (e.g. - * file, tcp, http and others). Before using lavf, you need to call - * av_register_all() to register all compiled muxers, demuxers and protocols. - * Unless you are absolutely sure you won't use libavformat's network - * capabilities, you should also call avformat_network_init(). - * - * A supported input format is described by an AVInputFormat struct, conversely - * an output format is described by AVOutputFormat. You can iterate over all - * registered input/output formats using the av_iformat_next() / - * av_oformat_next() functions. The protocols layer is not part of the public - * API, so you can only get the names of supported protocols with the - * avio_enum_protocols() function. - * - * Main lavf structure used for both muxing and demuxing is AVFormatContext, - * which exports all information about the file being read or written. As with - * most Libavformat structures, its size is not part of public ABI, so it cannot be - * allocated on stack or directly with av_malloc(). To create an - * AVFormatContext, use avformat_alloc_context() (some functions, like - * avformat_open_input() might do that for you). - * - * Most importantly an AVFormatContext contains: - * @li the @ref AVFormatContext.iformat "input" or @ref AVFormatContext.oformat - * "output" format. It is either autodetected or set by user for input; - * always set by user for output. - * @li an @ref AVFormatContext.streams "array" of AVStreams, which describe all - * elementary streams stored in the file. AVStreams are typically referred to - * using their index in this array. - * @li an @ref AVFormatContext.pb "I/O context". It is either opened by lavf or - * set by user for input, always set by user for output (unless you are dealing - * with an AVFMT_NOFILE format). - * - * @section lavf_options Passing options to (de)muxers - * Lavf allows to configure muxers and demuxers using the @ref avoptions - * mechanism. Generic (format-independent) libavformat options are provided by - * AVFormatContext, they can be examined from a user program by calling - * av_opt_next() / av_opt_find() on an allocated AVFormatContext (or its AVClass - * from avformat_get_class()). Private (format-specific) options are provided by - * AVFormatContext.priv_data if and only if AVInputFormat.priv_class / - * AVOutputFormat.priv_class of the corresponding format struct is non-NULL. - * Further options may be provided by the @ref AVFormatContext.pb "I/O context", - * if its AVClass is non-NULL, and the protocols layer. See the discussion on - * nesting in @ref avoptions documentation to learn how to access those. - * - * @defgroup lavf_decoding Demuxing - * @{ - * Demuxers read a media file and split it into chunks of data (@em packets). A - * @ref AVPacket "packet" contains one or more encoded frames which belongs to a - * single elementary stream. In the lavf API this process is represented by the - * avformat_open_input() function for opening a file, av_read_frame() for - * reading a single packet and finally avformat_close_input(), which does the - * cleanup. - * - * @section lavf_decoding_open Opening a media file - * The minimum information required to open a file is its URL or filename, which - * is passed to avformat_open_input(), as in the following code: - * @code - * const char *url = "in.mp3"; - * AVFormatContext *s = NULL; - * int ret = avformat_open_input(&s, url, NULL, NULL); - * if (ret < 0) - * abort(); - * @endcode - * The above code attempts to allocate an AVFormatContext, open the - * specified file (autodetecting the format) and read the header, exporting the - * information stored there into s. Some formats do not have a header or do not - * store enough information there, so it is recommended that you call the - * avformat_find_stream_info() function which tries to read and decode a few - * frames to find missing information. - * - * In some cases you might want to preallocate an AVFormatContext yourself with - * avformat_alloc_context() and do some tweaking on it before passing it to - * avformat_open_input(). One such case is when you want to use custom functions - * for reading input data instead of lavf internal I/O layer. - * To do that, create your own AVIOContext with avio_alloc_context(), passing - * your reading callbacks to it. Then set the @em pb field of your - * AVFormatContext to newly created AVIOContext. - * - * Since the format of the opened file is in general not known until after - * avformat_open_input() has returned, it is not possible to set demuxer private - * options on a preallocated context. Instead, the options should be passed to - * avformat_open_input() wrapped in an AVDictionary: - * @code - * AVDictionary *options = NULL; - * av_dict_set(&options, "video_size", "640x480", 0); - * av_dict_set(&options, "pixel_format", "rgb24", 0); - * - * if (avformat_open_input(&s, url, NULL, &options) < 0) - * abort(); - * av_dict_free(&options); - * @endcode - * This code passes the private options 'video_size' and 'pixel_format' to the - * demuxer. They would be necessary for e.g. the rawvideo demuxer, since it - * cannot know how to interpret raw video data otherwise. If the format turns - * out to be something different than raw video, those options will not be - * recognized by the demuxer and therefore will not be applied. Such unrecognized - * options are then returned in the options dictionary (recognized options are - * consumed). The calling program can handle such unrecognized options as it - * wishes, e.g. - * @code - * AVDictionaryEntry *e; - * if (e = av_dict_get(options, "", NULL, AV_DICT_IGNORE_SUFFIX)) { - * fprintf(stderr, "Option %s not recognized by the demuxer.\n", e->key); - * abort(); - * } - * @endcode - * - * After you have finished reading the file, you must close it with - * avformat_close_input(). It will free everything associated with the file. - * - * @section lavf_decoding_read Reading from an opened file - * Reading data from an opened AVFormatContext is done by repeatedly calling - * av_read_frame() on it. Each call, if successful, will return an AVPacket - * containing encoded data for one AVStream, identified by - * AVPacket.stream_index. This packet may be passed straight into the libavcodec - * decoding functions avcodec_decode_video2(), avcodec_decode_audio4() or - * avcodec_decode_subtitle2() if the caller wishes to decode the data. - * - * AVPacket.pts, AVPacket.dts and AVPacket.duration timing information will be - * set if known. They may also be unset (i.e. AV_NOPTS_VALUE for - * pts/dts, 0 for duration) if the stream does not provide them. The timing - * information will be in AVStream.time_base units, i.e. it has to be - * multiplied by the timebase to convert them to seconds. - * - * If AVPacket.buf is set on the returned packet, then the packet is - * allocated dynamically and the user may keep it indefinitely. - * Otherwise, if AVPacket.buf is NULL, the packet data is backed by a - * static storage somewhere inside the demuxer and the packet is only valid - * until the next av_read_frame() call or closing the file. If the caller - * requires a longer lifetime, av_dup_packet() will make an av_malloc()ed copy - * of it. - * In both cases, the packet must be freed with av_free_packet() when it is no - * longer needed. - * - * @section lavf_decoding_seek Seeking - * @} - * - * @defgroup lavf_encoding Muxing - * @{ - * @} - * - * @defgroup lavf_io I/O Read/Write - * @{ - * @} - * - * @defgroup lavf_codec Demuxers - * @{ - * @defgroup lavf_codec_native Native Demuxers - * @{ - * @} - * @defgroup lavf_codec_wrappers External library wrappers - * @{ - * @} - * @} - * @defgroup lavf_protos I/O Protocols - * @{ - * @} - * @defgroup lavf_internal Internal - * @{ - * @} - * @} - * - */ - -#include -#include /* FILE */ -#include "libavcodec/avcodec.h" -#include "libavutil/dict.h" -#include "libavutil/log.h" - -#include "avio.h" -#include "libavformat/version.h" - -struct AVFormatContext; - - -/** - * @defgroup metadata_api Public Metadata API - * @{ - * @ingroup libavf - * The metadata API allows libavformat to export metadata tags to a client - * application when demuxing. Conversely it allows a client application to - * set metadata when muxing. - * - * Metadata is exported or set as pairs of key/value strings in the 'metadata' - * fields of the AVFormatContext, AVStream, AVChapter and AVProgram structs - * using the @ref lavu_dict "AVDictionary" API. Like all strings in FFmpeg, - * metadata is assumed to be UTF-8 encoded Unicode. Note that metadata - * exported by demuxers isn't checked to be valid UTF-8 in most cases. - * - * Important concepts to keep in mind: - * - Keys are unique; there can never be 2 tags with the same key. This is - * also meant semantically, i.e., a demuxer should not knowingly produce - * several keys that are literally different but semantically identical. - * E.g., key=Author5, key=Author6. In this example, all authors must be - * placed in the same tag. - * - Metadata is flat, not hierarchical; there are no subtags. If you - * want to store, e.g., the email address of the child of producer Alice - * and actor Bob, that could have key=alice_and_bobs_childs_email_address. - * - Several modifiers can be applied to the tag name. This is done by - * appending a dash character ('-') and the modifier name in the order - * they appear in the list below -- e.g. foo-eng-sort, not foo-sort-eng. - * - language -- a tag whose value is localized for a particular language - * is appended with the ISO 639-2/B 3-letter language code. - * For example: Author-ger=Michael, Author-eng=Mike - * The original/default language is in the unqualified "Author" tag. - * A demuxer should set a default if it sets any translated tag. - * - sorting -- a modified version of a tag that should be used for - * sorting will have '-sort' appended. E.g. artist="The Beatles", - * artist-sort="Beatles, The". - * - * - Demuxers attempt to export metadata in a generic format, however tags - * with no generic equivalents are left as they are stored in the container. - * Follows a list of generic tag names: - * - @verbatim - album -- name of the set this work belongs to - album_artist -- main creator of the set/album, if different from artist. - e.g. "Various Artists" for compilation albums. - artist -- main creator of the work - comment -- any additional description of the file. - composer -- who composed the work, if different from artist. - copyright -- name of copyright holder. - creation_time-- date when the file was created, preferably in ISO 8601. - date -- date when the work was created, preferably in ISO 8601. - disc -- number of a subset, e.g. disc in a multi-disc collection. - encoder -- name/settings of the software/hardware that produced the file. - encoded_by -- person/group who created the file. - filename -- original name of the file. - genre -- . - language -- main language in which the work is performed, preferably - in ISO 639-2 format. Multiple languages can be specified by - separating them with commas. - performer -- artist who performed the work, if different from artist. - E.g for "Also sprach Zarathustra", artist would be "Richard - Strauss" and performer "London Philharmonic Orchestra". - publisher -- name of the label/publisher. - service_name -- name of the service in broadcasting (channel name). - service_provider -- name of the service provider in broadcasting. - title -- name of the work. - track -- number of this work in the set, can be in form current/total. - variant_bitrate -- the total bitrate of the bitrate variant that the current stream is part of - @endverbatim - * - * Look in the examples section for an application example how to use the Metadata API. - * - * @} - */ - -/* packet functions */ - - -/** - * Allocate and read the payload of a packet and initialize its - * fields with default values. - * - * @param pkt packet - * @param size desired payload size - * @return >0 (read size) if OK, AVERROR_xxx otherwise - */ -int av_get_packet(AVIOContext *s, AVPacket *pkt, int size); - - -/** - * Read data and append it to the current content of the AVPacket. - * If pkt->size is 0 this is identical to av_get_packet. - * Note that this uses av_grow_packet and thus involves a realloc - * which is inefficient. Thus this function should only be used - * when there is no reasonable way to know (an upper bound of) - * the final size. - * - * @param pkt packet - * @param size amount of data to read - * @return >0 (read size) if OK, AVERROR_xxx otherwise, previous data - * will not be lost even if an error occurs. - */ -int av_append_packet(AVIOContext *s, AVPacket *pkt, int size); - -/*************************************************/ -/* fractional numbers for exact pts handling */ - -/** - * The exact value of the fractional number is: 'val + num / den'. - * num is assumed to be 0 <= num < den. - */ -typedef struct AVFrac { - int64_t val, num, den; -} AVFrac; - -/*************************************************/ -/* input/output formats */ - -struct AVCodecTag; - -/** - * This structure contains the data a format has to probe a file. - */ -typedef struct AVProbeData { - const char *filename; - unsigned char *buf; /**< Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero. */ - int buf_size; /**< Size of buf except extra allocated bytes */ -} AVProbeData; - -#define AVPROBE_SCORE_MAX 100 ///< maximum score, half of that is used for file-extension-based detection -#define AVPROBE_SCORE_RETRY (AVPROBE_SCORE_MAX/4) -#define AVPROBE_PADDING_SIZE 32 ///< extra allocated bytes at the end of the probe buffer - -/// Demuxer will use avio_open, no opened file should be provided by the caller. -#define AVFMT_NOFILE 0x0001 -#define AVFMT_NEEDNUMBER 0x0002 /**< Needs '%d' in filename. */ -#define AVFMT_SHOW_IDS 0x0008 /**< Show format stream IDs numbers. */ -#define AVFMT_RAWPICTURE 0x0020 /**< Format wants AVPicture structure for - raw picture data. */ -#define AVFMT_GLOBALHEADER 0x0040 /**< Format wants global header. */ -#define AVFMT_NOTIMESTAMPS 0x0080 /**< Format does not need / have any timestamps. */ -#define AVFMT_GENERIC_INDEX 0x0100 /**< Use generic index building code. */ -#define AVFMT_TS_DISCONT 0x0200 /**< Format allows timestamp discontinuities. Note, muxers always require valid (monotone) timestamps */ -#define AVFMT_VARIABLE_FPS 0x0400 /**< Format allows variable fps. */ -#define AVFMT_NODIMENSIONS 0x0800 /**< Format does not need width/height */ -#define AVFMT_NOSTREAMS 0x1000 /**< Format does not require any streams */ -#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. */ -#if LIBAVFORMAT_VERSION_MAJOR <= 54 -#define AVFMT_TS_NONSTRICT 0x8020000 //we try to be compatible to the ABIs of ffmpeg and major forks -#else -#define AVFMT_TS_NONSTRICT 0x20000 -#endif - /**< Format does not require strictly - increasing timestamps, but they must - still be monotonic */ - -#define AVFMT_SEEK_TO_PTS 0x4000000 /**< Seeking is based on PTS */ - -/** - * @addtogroup lavf_encoding - * @{ - */ -typedef struct AVOutputFormat { - const char *name; - /** - * Descriptive name for the format, meant to be more human-readable - * than name. You should use the NULL_IF_CONFIG_SMALL() macro - * to define it. - */ - const char *long_name; - const char *mime_type; - const char *extensions; /**< comma-separated filename extensions */ - /* output support */ - enum AVCodecID audio_codec; /**< default audio codec */ - enum AVCodecID video_codec; /**< default video codec */ - enum AVCodecID subtitle_codec; /**< default subtitle codec */ - /** - * can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER, AVFMT_RAWPICTURE, - * AVFMT_GLOBALHEADER, AVFMT_NOTIMESTAMPS, AVFMT_VARIABLE_FPS, - * AVFMT_NODIMENSIONS, AVFMT_NOSTREAMS, AVFMT_ALLOW_FLUSH, - * AVFMT_TS_NONSTRICT - */ - int flags; - - /** - * List of supported codec_id-codec_tag pairs, ordered by "better - * choice first". The arrays are all terminated by AV_CODEC_ID_NONE. - */ - const struct AVCodecTag * const *codec_tag; - - - const AVClass *priv_class; ///< AVClass for the private context - - /***************************************************************** - * No fields below this line are part of the public API. They - * may not be used outside of libavformat and can be changed and - * removed at will. - * New public fields should be added right above. - ***************************************************************** - */ - struct AVOutputFormat *next; - /** - * size of private data so that it can be allocated in the wrapper - */ - int priv_data_size; - - 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 *); - /** - * Currently only used to set pixel format if not YUV420P. - */ - int (*interleave_packet)(struct AVFormatContext *, AVPacket *out, - AVPacket *in, int flush); - /** - * Test if the given codec can be stored in this container. - * - * @return 1 if the codec is supported, 0 if it is not. - * A negative number if unknown. - * MKTAG('A', 'P', 'I', 'C') if the codec is only supported as AV_DISPOSITION_ATTACHED_PIC - */ - int (*query_codec)(enum AVCodecID id, int std_compliance); - - void (*get_output_timestamp)(struct AVFormatContext *s, int stream, - int64_t *dts, int64_t *wall); -} AVOutputFormat; -/** - * @} - */ - -/** - * @addtogroup lavf_decoding - * @{ - */ -typedef struct AVInputFormat { - /** - * A comma separated list of short names for the format. New names - * may be appended with a minor bump. - */ - const char *name; - - /** - * Descriptive name for the format, meant to be more human-readable - * than name. You should use the NULL_IF_CONFIG_SMALL() macro - * to define it. - */ - const char *long_name; - - /** - * Can use flags: AVFMT_NOFILE, AVFMT_NEEDNUMBER, AVFMT_SHOW_IDS, - * AVFMT_GENERIC_INDEX, AVFMT_TS_DISCONT, AVFMT_NOBINSEARCH, - * AVFMT_NOGENSEARCH, AVFMT_NO_BYTE_SEEK, AVFMT_SEEK_TO_PTS. - */ - int flags; - - /** - * If extensions are defined, then no probe is done. You should - * usually not use extension format guessing because it is not - * reliable enough - */ - const char *extensions; - - const struct AVCodecTag * const *codec_tag; - - const AVClass *priv_class; ///< AVClass for the private context - - /***************************************************************** - * No fields below this line are part of the public API. They - * may not be used outside of libavformat and can be changed and - * removed at will. - * New public fields should be added right above. - ***************************************************************** - */ - struct AVInputFormat *next; - - /** - * Raw demuxers store their codec ID here. - */ - int raw_codec_id; - - /** - * Size of private data so that it can be allocated in the wrapper. - */ - int priv_data_size; - - /** - * Tell if a given file has a chance of being parsed as this format. - * The buffer provided is guaranteed to be AVPROBE_PADDING_SIZE bytes - * big so you do not have to check for that unless you need more. - */ - int (*read_probe)(AVProbeData *); - - /** - * Read the format header and initialize the AVFormatContext - * structure. Return 0 if OK. Only used in raw format right - * now. 'avformat_new_stream' should be called to create new streams. - */ - int (*read_header)(struct AVFormatContext *); - - /** - * Read one packet and put it in 'pkt'. pts and flags are also - * set. 'avformat_new_stream' can be called only if the flag - * AVFMTCTX_NOHEADER is used and only in the calling thread (not in a - * background thread). - * @return 0 on success, < 0 on error. - * When returning an error, pkt must not have been allocated - * or must be freed before returning - */ - int (*read_packet)(struct AVFormatContext *, AVPacket *pkt); - - /** - * Close the stream. The AVFormatContext and AVStreams are not - * freed by this function - */ - int (*read_close)(struct AVFormatContext *); - - /** - * Seek to a given timestamp relative to the frames in - * stream component stream_index. - * @param stream_index Must not be -1. - * @param flags Selects which direction should be preferred if no exact - * match is available. - * @return >= 0 on success (but not necessarily the new offset) - */ - int (*read_seek)(struct AVFormatContext *, - int stream_index, int64_t timestamp, int flags); - - /** - * Get the next timestamp in stream[stream_index].time_base units. - * @return the timestamp or AV_NOPTS_VALUE if an error occurred - */ - int64_t (*read_timestamp)(struct AVFormatContext *s, int stream_index, - int64_t *pos, int64_t pos_limit); - - /** - * Start/resume playing - only meaningful if using a network-based format - * (RTSP). - */ - int (*read_play)(struct AVFormatContext *); - - /** - * Pause playing - only meaningful if using a network-based format - * (RTSP). - */ - int (*read_pause)(struct AVFormatContext *); - - /** - * Seek to timestamp ts. - * Seeking will be done so that the point from which all active streams - * can be presented successfully will be closest to ts and within min/max_ts. - * Active streams are all streams that have AVStream.discard < AVDISCARD_ALL. - */ - int (*read_seek2)(struct AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags); -} AVInputFormat; -/** - * @} - */ - -enum AVStreamParseType { - AVSTREAM_PARSE_NONE, - AVSTREAM_PARSE_FULL, /**< full parsing and repack */ - AVSTREAM_PARSE_HEADERS, /**< Only parse headers, do not repack. */ - AVSTREAM_PARSE_TIMESTAMPS, /**< full parsing and interpolation of timestamps for frames not starting on a packet boundary */ - AVSTREAM_PARSE_FULL_ONCE, /**< full parsing and repack of the first frame only, only implemented for H.264 currently */ - AVSTREAM_PARSE_FULL_RAW=MKTAG(0,'R','A','W'), /**< full parsing and repack with timestamp and position generation by parser for raw - this assumes that each packet in the file contains no demuxer level headers and - just codec level data, otherwise position generation would fail */ -}; - -typedef struct AVIndexEntry { - int64_t pos; - int64_t timestamp; /**< - * Timestamp in AVStream.time_base units, preferably the time from which on correctly decoded frames are available - * when seeking to this entry. That means preferable PTS on keyframe based formats. - * But demuxers can choose to store a different timestamp, if it is more convenient for the implementation or nothing better - * is known - */ -#define AVINDEX_KEYFRAME 0x0001 - int flags:2; - int size:30; //Yeah, trying to keep the size of this small to reduce memory requirements (it is 24 vs. 32 bytes due to possible 8-byte alignment). - int min_distance; /**< Minimum distance between this and the previous keyframe, used to avoid unneeded searching. */ -} AVIndexEntry; - -#define AV_DISPOSITION_DEFAULT 0x0001 -#define AV_DISPOSITION_DUB 0x0002 -#define AV_DISPOSITION_ORIGINAL 0x0004 -#define AV_DISPOSITION_COMMENT 0x0008 -#define AV_DISPOSITION_LYRICS 0x0010 -#define AV_DISPOSITION_KARAOKE 0x0020 - -/** - * Track should be used during playback by default. - * Useful for subtitle track that should be displayed - * even when user did not explicitly ask for subtitles. - */ -#define AV_DISPOSITION_FORCED 0x0040 -#define AV_DISPOSITION_HEARING_IMPAIRED 0x0080 /**< stream for hearing impaired audiences */ -#define AV_DISPOSITION_VISUAL_IMPAIRED 0x0100 /**< stream for visual impaired audiences */ -#define AV_DISPOSITION_CLEAN_EFFECTS 0x0200 /**< stream without voice */ -/** - * The stream is stored in the file as an attached picture/"cover art" (e.g. - * APIC frame in ID3v2). The single packet associated with it will be returned - * among the first few packets read from the file unless seeking takes place. - * It can also be accessed at any time in AVStream.attached_pic. - */ -#define AV_DISPOSITION_ATTACHED_PIC 0x0400 - -/** - * Options for behavior on timestamp wrap detection. - */ -#define AV_PTS_WRAP_IGNORE 0 ///< ignore the wrap -#define AV_PTS_WRAP_ADD_OFFSET 1 ///< add the format specific offset on wrap detection -#define AV_PTS_WRAP_SUB_OFFSET -1 ///< subtract the format specific offset on wrap detection - -/** - * Stream structure. - * New fields can be added to the end with minor version bumps. - * Removal, reordering and changes to existing fields require a major - * version bump. - * sizeof(AVStream) must not be used outside libav*. - */ -typedef struct AVStream { - int index; /**< stream index in AVFormatContext */ - /** - * Format-specific stream ID. - * decoding: set by libavformat - * encoding: set by the user, replaced by libavformat if left unset - */ - int id; - /** - * Codec context associated with this stream. Allocated and freed by - * libavformat. - * - * - decoding: The demuxer exports codec information stored in the headers - * here. - * - encoding: The user sets codec information, the muxer writes it to the - * output. Mandatory fields as specified in AVCodecContext - * documentation must be set even if this AVCodecContext is - * not actually used for encoding. - */ - AVCodecContext *codec; - void *priv_data; - - /** - * encoding: pts generation when outputting stream - */ - struct AVFrac pts; - - /** - * This is the fundamental unit of time (in seconds) in terms - * of which frame timestamps are represented. - * - * decoding: set by libavformat - * encoding: set by libavformat in avformat_write_header. The muxer may use the - * user-provided value of @ref AVCodecContext.time_base "codec->time_base" - * as a hint. - */ - AVRational time_base; - - /** - * Decoding: pts of the first frame of the stream in presentation order, in stream time base. - * Only set this if you are absolutely 100% sure that the value you set - * it to really is the pts of the first frame. - * This may be undefined (AV_NOPTS_VALUE). - * @note The ASF header does NOT contain a correct start_time the ASF - * demuxer must NOT set this. - */ - int64_t start_time; - - /** - * Decoding: duration of the stream, in stream time base. - * If a source file does not specify a duration, but does specify - * a bitrate, this value will be estimated from bitrate and file size. - */ - int64_t duration; - - int64_t nb_frames; ///< number of frames in this stream if known or 0 - - int disposition; /**< AV_DISPOSITION_* bit field */ - - enum AVDiscard discard; ///< Selects which packets can be discarded at will and do not need to be demuxed. - - /** - * sample aspect ratio (0 if unknown) - * - encoding: Set by user. - * - decoding: Set by libavformat. - */ - AVRational sample_aspect_ratio; - - AVDictionary *metadata; - - /** - * Average framerate - */ - AVRational avg_frame_rate; - - /** - * For streams with AV_DISPOSITION_ATTACHED_PIC disposition, this packet - * will contain the attached picture. - * - * decoding: set by libavformat, must not be modified by the caller. - * encoding: unused - */ - AVPacket attached_pic; - - /** - * Real base framerate of the stream. - * This is the lowest framerate with which all timestamps can be - * represented accurately (it is the least common multiple of all - * framerates in the stream). Note, this value is just a guess! - * For example, if the time base is 1/90000 and all frames have either - * approximately 3600 or 1800 timer ticks, then r_frame_rate will be 50/1. - * - * Code outside avformat should access this field using: - * av_stream_get/set_r_frame_rate(stream) - */ - AVRational r_frame_rate; - - /***************************************************************** - * All fields below this line are not part of the public API. They - * may not be used outside of libavformat and can be changed and - * removed at will. - * New public fields should be added right above. - ***************************************************************** - */ - - /** - * Stream information used internally by av_find_stream_info() - */ -#define MAX_STD_TIMEBASES (60*12+6) - struct { - int64_t last_dts; - int64_t duration_gcd; - int duration_count; - double (*duration_error)[2][MAX_STD_TIMEBASES]; - int64_t codec_info_duration; - int64_t codec_info_duration_fields; - int found_decoder; - - int64_t last_duration; - - /** - * Those are used for average framerate estimation. - */ - int64_t fps_first_dts; - int fps_first_dts_idx; - int64_t fps_last_dts; - int fps_last_dts_idx; - - } *info; - - int pts_wrap_bits; /**< number of bits in pts (used for wrapping control) */ - - // Timestamp generation support: - /** - * Timestamp corresponding to the last dts sync point. - * - * Initialized when AVCodecParserContext.dts_sync_point >= 0 and - * a DTS is received from the underlying container. Otherwise set to - * AV_NOPTS_VALUE by default. - */ - int64_t reference_dts; - int64_t first_dts; - int64_t cur_dts; - int64_t last_IP_pts; - int last_IP_duration; - - /** - * Number of packets to buffer for codec probing - */ -#define MAX_PROBE_PACKETS 2500 - int probe_packets; - - /** - * Number of frames that have been demuxed during av_find_stream_info() - */ - int codec_info_nb_frames; - - /** - * Stream Identifier - * This is the MPEG-TS stream identifier +1 - * 0 means unknown - */ - int stream_identifier; - - int64_t interleaver_chunk_size; - int64_t interleaver_chunk_duration; - - /* av_read_frame() support */ - enum AVStreamParseType need_parsing; - struct AVCodecParserContext *parser; - - /** - * last packet in packet_buffer for this stream when muxing. - */ - struct AVPacketList *last_in_packet_buffer; - AVProbeData probe_data; -#define MAX_REORDER_DELAY 16 - int64_t pts_buffer[MAX_REORDER_DELAY+1]; - - AVIndexEntry *index_entries; /**< Only used if the format does not - support seeking natively. */ - int nb_index_entries; - unsigned int index_entries_allocated_size; - - /** - * stream probing state - * -1 -> probing finished - * 0 -> no probing requested - * rest -> perform probing with request_probe being the minimum score to accept. - * NOT PART OF PUBLIC API - */ - int request_probe; - /** - * Indicates that everything up to the next keyframe - * should be discarded. - */ - int skip_to_keyframe; - - /** - * Number of samples to skip at the start of the frame decoded from the next packet. - */ - int skip_samples; - - /** - * Number of internally decoded frames, used internally in libavformat, do not access - * its lifetime differs from info which is why it is not in that structure. - */ - int nb_decoded_frames; - - /** - * Timestamp offset added to timestamps before muxing - * NOT PART OF PUBLIC API - */ - int64_t mux_ts_offset; - - /** - * Internal data to check for wrapping of the time stamp - */ - int64_t pts_wrap_reference; - - /** - * Options for behavior, when a wrap is detected. - * - * Defined by AV_PTS_WRAP_ values. - * - * If correction is enabled, there are two possibilities: - * If the first time stamp is near the wrap point, the wrap offset - * will be subtracted, which will create negative time stamps. - * Otherwise the offset will be added. - */ - int pts_wrap_behavior; - -} AVStream; - -AVRational av_stream_get_r_frame_rate(const AVStream *s); -void av_stream_set_r_frame_rate(AVStream *s, AVRational r); - -#define AV_PROGRAM_RUNNING 1 - -/** - * New fields can be added to the end with minor version bumps. - * Removal, reordering and changes to existing fields require a major - * version bump. - * sizeof(AVProgram) must not be used outside libav*. - */ -typedef struct AVProgram { - int id; - int flags; - enum AVDiscard discard; ///< selects which program to discard and which to feed to the caller - unsigned int *stream_index; - unsigned int nb_stream_indexes; - AVDictionary *metadata; - - int program_num; - int pmt_pid; - int pcr_pid; - - /***************************************************************** - * All fields below this line are not part of the public API. They - * may not be used outside of libavformat and can be changed and - * removed at will. - * New public fields should be added right above. - ***************************************************************** - */ - int64_t start_time; - int64_t end_time; - - int64_t pts_wrap_reference; ///< reference dts for wrap detection - int pts_wrap_behavior; ///< behavior on wrap detection -} AVProgram; - -#define AVFMTCTX_NOHEADER 0x0001 /**< signal that no header is present - (streams are added dynamically) */ - -typedef struct AVChapter { - int id; ///< unique ID to identify the chapter - AVRational time_base; ///< time base in which the start/end timestamps are specified - int64_t start, end; ///< chapter start/end time in time_base units - AVDictionary *metadata; -} AVChapter; - - -/** - * The duration of a video can be estimated through various ways, and this enum can be used - * to know how the duration was estimated. - */ -enum AVDurationEstimationMethod { - AVFMT_DURATION_FROM_PTS, ///< Duration accurately estimated from PTSes - AVFMT_DURATION_FROM_STREAM, ///< Duration estimated from a stream with a known duration - AVFMT_DURATION_FROM_BITRATE ///< Duration estimated from bitrate (less accurate) -}; - -/** - * Format I/O context. - * New fields can be added to the end with minor version bumps. - * Removal, reordering and changes to existing fields require a major - * version bump. - * sizeof(AVFormatContext) must not be used outside libav*, use - * avformat_alloc_context() to create an AVFormatContext. - */ -typedef struct AVFormatContext { - /** - * A class for logging and AVOptions. Set by avformat_alloc_context(). - * Exports (de)muxer private options if they exist. - */ - const AVClass *av_class; - - /** - * Can only be iformat or oformat, not both at the same time. - * - * decoding: set by avformat_open_input(). - * encoding: set by the user. - */ - struct AVInputFormat *iformat; - struct AVOutputFormat *oformat; - - /** - * Format private data. This is an AVOptions-enabled struct - * if and only if iformat/oformat.priv_class is not NULL. - */ - void *priv_data; - - /** - * I/O context. - * - * decoding: either set by the user before avformat_open_input() (then - * the user must close it manually) or set by avformat_open_input(). - * encoding: set by the user. - * - * Do NOT set this field if AVFMT_NOFILE flag is set in - * iformat/oformat.flags. In such a case, the (de)muxer will handle - * I/O in some other way and this field will be NULL. - */ - AVIOContext *pb; - - /* stream info */ - int ctx_flags; /**< Format-specific flags, see AVFMTCTX_xx */ - - /** - * A list of all streams in the file. New streams are created with - * avformat_new_stream(). - * - * decoding: streams are created by libavformat in avformat_open_input(). - * If AVFMTCTX_NOHEADER is set in ctx_flags, then new streams may also - * appear in av_read_frame(). - * encoding: streams are created by the user before avformat_write_header(). - */ - unsigned int nb_streams; - AVStream **streams; - - char filename[1024]; /**< input or output filename */ - - /** - * Decoding: position of the first frame of the component, in - * AV_TIME_BASE fractional seconds. NEVER set this value directly: - * It is deduced from the AVStream values. - */ - int64_t start_time; - - /** - * Decoding: duration of the stream, in AV_TIME_BASE fractional - * seconds. Only set this value if you know none of the individual stream - * durations and also do not set any of them. This is deduced from the - * AVStream values if not set. - */ - int64_t duration; - - /** - * Decoding: total stream bitrate in bit/s, 0 if not - * available. Never set it directly if the file_size and the - * duration are known as FFmpeg can compute it automatically. - */ - int bit_rate; - - unsigned int packet_size; - int max_delay; - - int flags; -#define AVFMT_FLAG_GENPTS 0x0001 ///< Generate missing pts even if it requires parsing future frames. -#define AVFMT_FLAG_IGNIDX 0x0002 ///< Ignore index. -#define AVFMT_FLAG_NONBLOCK 0x0004 ///< Do not block when reading packets from input. -#define AVFMT_FLAG_IGNDTS 0x0008 ///< Ignore DTS on frames that contain both DTS & PTS -#define AVFMT_FLAG_NOFILLIN 0x0010 ///< Do not infer any values from other values, just return what is stored in the container -#define AVFMT_FLAG_NOPARSE 0x0020 ///< Do not use AVParsers, you also must set AVFMT_FLAG_NOFILLIN as the fillin code works on frames and no parsing -> no frames. Also seeking to frames can not work if parsing to find frame boundaries has been disabled -#define AVFMT_FLAG_NOBUFFER 0x0040 ///< Do not buffer frames when possible -#define AVFMT_FLAG_CUSTOM_IO 0x0080 ///< The caller has supplied a custom AVIOContext, don't avio_close() it. -#define AVFMT_FLAG_DISCARD_CORRUPT 0x0100 ///< Discard frames marked corrupted -#define AVFMT_FLAG_MP4A_LATM 0x8000 ///< Enable RTP MP4A-LATM payload -#define AVFMT_FLAG_SORT_DTS 0x10000 ///< try to interleave outputted packets by dts (using this flag can slow demuxing down) -#define AVFMT_FLAG_PRIV_OPT 0x20000 ///< Enable use of private options by delaying codec open (this could be made default once all code is converted) -#define AVFMT_FLAG_KEEP_SIDE_DATA 0x40000 ///< Don't merge side data but keep it separate. - - /** - * decoding: size of data to probe; encoding: unused. - */ - unsigned int probesize; - - /** - * decoding: maximum time (in AV_TIME_BASE units) during which the input should - * be analyzed in avformat_find_stream_info(). - */ - int max_analyze_duration; - - const uint8_t *key; - int keylen; - - unsigned int nb_programs; - AVProgram **programs; - - /** - * Forced video codec_id. - * Demuxing: Set by user. - */ - enum AVCodecID video_codec_id; - - /** - * Forced audio codec_id. - * Demuxing: Set by user. - */ - enum AVCodecID audio_codec_id; - - /** - * Forced subtitle codec_id. - * Demuxing: Set by user. - */ - enum AVCodecID subtitle_codec_id; - - /** - * Maximum amount of memory in bytes to use for the index of each stream. - * If the index exceeds this size, entries will be discarded as - * needed to maintain a smaller size. This can lead to slower or less - * accurate seeking (depends on demuxer). - * Demuxers for which a full in-memory index is mandatory will ignore - * this. - * muxing : unused - * demuxing: set by user - */ - unsigned int max_index_size; - - /** - * Maximum amount of memory in bytes to use for buffering frames - * obtained from realtime capture devices. - */ - unsigned int max_picture_buffer; - - unsigned int nb_chapters; - AVChapter **chapters; - - AVDictionary *metadata; - - /** - * Start time of the stream in real world time, in microseconds - * since the unix epoch (00:00 1st January 1970). That is, pts=0 - * in the stream was captured at this real world time. - * - encoding: Set by user. - * - decoding: Unused. - */ - int64_t start_time_realtime; - - /** - * decoding: number of frames used to probe fps - */ - int fps_probe_size; - - /** - * Error recognition; higher values will detect more errors but may - * misdetect some more or less valid parts as errors. - * - encoding: unused - * - decoding: Set by user. - */ - int error_recognition; - - /** - * Custom interrupt callbacks for the I/O layer. - * - * decoding: set by the user before avformat_open_input(). - * encoding: set by the user before avformat_write_header() - * (mainly useful for AVFMT_NOFILE formats). The callback - * should also be passed to avio_open2() if it's used to - * open the file. - */ - AVIOInterruptCB interrupt_callback; - - /** - * Flags to enable debugging. - */ - int debug; -#define FF_FDEBUG_TS 0x0001 - - /** - * Transport stream id. - * This will be moved into demuxer private options. Thus no API/ABI compatibility - */ - int ts_id; - - /** - * Audio preload in microseconds. - * Note, not all formats support this and unpredictable things may happen if it is used when not supported. - * - encoding: Set by user via AVOptions (NO direct access) - * - decoding: unused - */ - int audio_preload; - - /** - * Max chunk time in microseconds. - * Note, not all formats support this and unpredictable things may happen if it is used when not supported. - * - encoding: Set by user via AVOptions (NO direct access) - * - decoding: unused - */ - int max_chunk_duration; - - /** - * Max chunk size in bytes - * Note, not all formats support this and unpredictable things may happen if it is used when not supported. - * - encoding: Set by user via AVOptions (NO direct access) - * - decoding: unused - */ - int max_chunk_size; - - /** - * forces the use of wallclock timestamps as pts/dts of packets - * This has undefined results in the presence of B frames. - * - encoding: unused - * - decoding: Set by user via AVOptions (NO direct access) - */ - int use_wallclock_as_timestamps; - - /** - * Avoid negative timestamps during muxing. - * 0 -> allow negative timestamps - * 1 -> avoid negative timestamps - * -1 -> choose automatically (default) - * Note, this only works when interleave_packet_per_dts is in use. - * - encoding: Set by user via AVOptions (NO direct access) - * - decoding: unused - */ - int avoid_negative_ts; - - /** - * avio flags, used to force AVIO_FLAG_DIRECT. - * - encoding: unused - * - decoding: Set by user via AVOptions (NO direct access) - */ - int avio_flags; - - /** - * The duration field can be estimated through various ways, and this field can be used - * to know how the duration was estimated. - * - encoding: unused - * - decoding: Read by user via AVOptions (NO direct access) - */ - enum AVDurationEstimationMethod duration_estimation_method; - - /** - * Skip initial bytes when opening stream - * - encoding: unused - * - decoding: Set by user via AVOptions (NO direct access) - */ - unsigned int skip_initial_bytes; - - /** - * Correct single timestamp overflows - * - encoding: unused - * - decoding: Set by user via AVOPtions (NO direct access) - */ - unsigned int correct_ts_overflow; - - /** - * Force seeking to any (also non key) frames. - * - encoding: unused - * - decoding: Set by user via AVOPtions (NO direct access) - */ - int seek2any; - - /***************************************************************** - * All fields below this line are not part of the public API. They - * may not be used outside of libavformat and can be changed and - * removed at will. - * New public fields should be added right above. - ***************************************************************** - */ - - /** - * This buffer is only needed when packets were already buffered but - * not decoded, for example to get the codec parameters in MPEG - * streams. - */ - struct AVPacketList *packet_buffer; - struct AVPacketList *packet_buffer_end; - - /* av_seek_frame() support */ - int64_t data_offset; /**< offset of the first packet */ - - /** - * Raw packets from the demuxer, prior to parsing and decoding. - * This buffer is used for buffering packets until the codec can - * be identified, as parsing cannot be done without knowing the - * codec. - */ - struct AVPacketList *raw_packet_buffer; - struct AVPacketList *raw_packet_buffer_end; - /** - * Packets split by the parser get queued here. - */ - struct AVPacketList *parse_queue; - struct AVPacketList *parse_queue_end; - /** - * Remaining size available for raw_packet_buffer, in bytes. - */ -#define RAW_PACKET_BUFFER_SIZE 2500000 - int raw_packet_buffer_remaining_size; -} AVFormatContext; - -/** - * Returns the method used to set ctx->duration. - * - * @return AVFMT_DURATION_FROM_PTS, AVFMT_DURATION_FROM_STREAM, or AVFMT_DURATION_FROM_BITRATE. - */ -enum AVDurationEstimationMethod av_fmt_ctx_get_duration_estimation_method(const AVFormatContext* ctx); - -typedef struct AVPacketList { - AVPacket pkt; - struct AVPacketList *next; -} AVPacketList; - - -/** - * @defgroup lavf_core Core functions - * @ingroup libavf - * - * Functions for querying libavformat capabilities, allocating core structures, - * etc. - * @{ - */ - -/** - * Return the LIBAVFORMAT_VERSION_INT constant. - */ -unsigned avformat_version(void); - -/** - * Return the libavformat build-time configuration. - */ -const char *avformat_configuration(void); - -/** - * Return the libavformat license. - */ -const char *avformat_license(void); - -/** - * Initialize libavformat and register all the muxers, demuxers and - * protocols. If you do not call this function, then you can select - * exactly which formats you want to support. - * - * @see av_register_input_format() - * @see av_register_output_format() - */ -void av_register_all(void); - -void av_register_input_format(AVInputFormat *format); -void av_register_output_format(AVOutputFormat *format); - -/** - * Do global initialization of network components. This is optional, - * but recommended, since it avoids the overhead of implicitly - * doing the setup for each session. - * - * Calling this function will become mandatory if using network - * protocols at some major version bump. - */ -int avformat_network_init(void); - -/** - * Undo the initialization done by avformat_network_init. - */ -int avformat_network_deinit(void); - -/** - * If f is NULL, returns the first registered input format, - * if f is non-NULL, returns the next registered input format after f - * or NULL if f is the last one. - */ -AVInputFormat *av_iformat_next(AVInputFormat *f); - -/** - * If f is NULL, returns the first registered output format, - * if f is non-NULL, returns the next registered output format after f - * or NULL if f is the last one. - */ -AVOutputFormat *av_oformat_next(AVOutputFormat *f); - -/** - * Allocate an AVFormatContext. - * avformat_free_context() can be used to free the context and everything - * allocated by the framework within it. - */ -AVFormatContext *avformat_alloc_context(void); - -/** - * Free an AVFormatContext and all its streams. - * @param s context to free - */ -void avformat_free_context(AVFormatContext *s); - -/** - * Get the AVClass for AVFormatContext. It can be used in combination with - * AV_OPT_SEARCH_FAKE_OBJ for examining options. - * - * @see av_opt_find(). - */ -const AVClass *avformat_get_class(void); - -/** - * Add a new stream to a media file. - * - * When demuxing, it is called by the demuxer in read_header(). If the - * flag AVFMTCTX_NOHEADER is set in s.ctx_flags, then it may also - * be called in read_packet(). - * - * When muxing, should be called by the user before avformat_write_header(). - * - * @param c If non-NULL, the AVCodecContext corresponding to the new stream - * will be initialized to use this codec. This is needed for e.g. codec-specific - * defaults to be set, so codec should be provided if it is known. - * - * @return newly created stream or NULL on error. - */ -AVStream *avformat_new_stream(AVFormatContext *s, const AVCodec *c); - -AVProgram *av_new_program(AVFormatContext *s, int id); - -/** - * @} - */ - - -#if FF_API_PKT_DUMP -attribute_deprecated void av_pkt_dump(FILE *f, AVPacket *pkt, int dump_payload); -attribute_deprecated void av_pkt_dump_log(void *avcl, int level, AVPacket *pkt, - int dump_payload); -#endif - -#if FF_API_ALLOC_OUTPUT_CONTEXT -/** - * @deprecated deprecated in favor of avformat_alloc_output_context2() - */ -attribute_deprecated -AVFormatContext *avformat_alloc_output_context(const char *format, - AVOutputFormat *oformat, - const char *filename); -#endif - -/** - * Allocate an AVFormatContext for an output format. - * avformat_free_context() can be used to free the context and - * everything allocated by the framework within it. - * - * @param *ctx is set to the created format context, or to NULL in - * case of failure - * @param oformat format to use for allocating the context, if NULL - * format_name and filename are used instead - * @param format_name the name of output format to use for allocating the - * context, if NULL filename is used instead - * @param filename the name of the filename to use for allocating the - * context, may be NULL - * @return >= 0 in case of success, a negative AVERROR code in case of - * failure - */ -int avformat_alloc_output_context2(AVFormatContext **ctx, AVOutputFormat *oformat, - const char *format_name, const char *filename); - -/** - * @addtogroup lavf_decoding - * @{ - */ - -/** - * Find AVInputFormat based on the short name of the input format. - */ -AVInputFormat *av_find_input_format(const char *short_name); - -/** - * Guess the file format. - * - * @param is_opened Whether the file is already opened; determines whether - * demuxers with or without AVFMT_NOFILE are probed. - */ -AVInputFormat *av_probe_input_format(AVProbeData *pd, int is_opened); - -/** - * Guess the file format. - * - * @param is_opened Whether the file is already opened; determines whether - * demuxers with or without AVFMT_NOFILE are probed. - * @param score_max A probe score larger that this is required to accept a - * detection, the variable is set to the actual detection - * score afterwards. - * If the score is <= AVPROBE_SCORE_MAX / 4 it is recommended - * to retry with a larger probe buffer. - */ -AVInputFormat *av_probe_input_format2(AVProbeData *pd, int is_opened, int *score_max); - -/** - * Guess the file format. - * - * @param is_opened Whether the file is already opened; determines whether - * demuxers with or without AVFMT_NOFILE are probed. - * @param score_ret The score of the best detection. - */ -AVInputFormat *av_probe_input_format3(AVProbeData *pd, int is_opened, int *score_ret); - -/** - * Probe a bytestream to determine the input format. Each time a probe returns - * with a score that is too low, the probe buffer size is increased and another - * attempt is made. When the maximum probe size is reached, the input format - * with the highest score is returned. - * - * @param pb the bytestream to probe - * @param fmt the input format is put here - * @param filename the filename of the stream - * @param logctx the log context - * @param offset the offset within the bytestream to probe from - * @param max_probe_size the maximum probe buffer size (zero for default) - * @return 0 in case of success, a negative value corresponding to an - * AVERROR code otherwise - */ -int av_probe_input_buffer(AVIOContext *pb, AVInputFormat **fmt, - const char *filename, void *logctx, - unsigned int offset, unsigned int max_probe_size); - -/** - * Open an input stream and read the header. The codecs are not opened. - * The stream must be closed with av_close_input_file(). - * - * @param ps Pointer to user-supplied AVFormatContext (allocated by avformat_alloc_context). - * May be a pointer to NULL, in which case an AVFormatContext is allocated by this - * function and written into ps. - * Note that a user-supplied AVFormatContext will be freed on failure. - * @param filename Name of the stream to open. - * @param fmt If non-NULL, this parameter forces a specific input format. - * Otherwise the format is autodetected. - * @param options A dictionary filled with AVFormatContext and demuxer-private options. - * On return this parameter will be destroyed and replaced with a dict containing - * options that were not found. May be NULL. - * - * @return 0 on success, a negative AVERROR on failure. - * - * @note If you want to use custom IO, preallocate the format context and set its pb field. - */ -int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputFormat *fmt, AVDictionary **options); - -attribute_deprecated -int av_demuxer_open(AVFormatContext *ic); - -#if FF_API_FORMAT_PARAMETERS -/** - * Read packets of a media file to get stream information. This - * is useful for file formats with no headers such as MPEG. This - * function also computes the real framerate in case of MPEG-2 repeat - * frame mode. - * The logical file position is not changed by this function; - * examined packets may be buffered for later processing. - * - * @param ic media file handle - * @return >=0 if OK, AVERROR_xxx on error - * @todo Let the user decide somehow what information is needed so that - * we do not waste time getting stuff the user does not need. - * - * @deprecated use avformat_find_stream_info. - */ -attribute_deprecated -int av_find_stream_info(AVFormatContext *ic); -#endif - -/** - * Read packets of a media file to get stream information. This - * is useful for file formats with no headers such as MPEG. This - * function also computes the real framerate in case of MPEG-2 repeat - * frame mode. - * The logical file position is not changed by this function; - * examined packets may be buffered for later processing. - * - * @param ic media file handle - * @param options If non-NULL, an ic.nb_streams long array of pointers to - * dictionaries, where i-th member contains options for - * codec corresponding to i-th stream. - * On return each dictionary will be filled with options that were not found. - * @return >=0 if OK, AVERROR_xxx on error - * - * @note this function isn't guaranteed to open all the codecs, so - * options being non-empty at return is a perfectly normal behavior. - * - * @todo Let the user decide somehow what information is needed so that - * we do not waste time getting stuff the user does not need. - */ -int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options); - -/** - * Find the programs which belong to a given stream. - * - * @param ic media file handle - * @param last the last found program, the search will start after this - * program, or from the beginning if it is NULL - * @param s stream index - * @return the next program which belongs to s, NULL if no program is found or - * the last program is not among the programs of ic. - */ -AVProgram *av_find_program_from_stream(AVFormatContext *ic, AVProgram *last, int s); - -/** - * Find the "best" stream in the file. - * The best stream is determined according to various heuristics as the most - * likely to be what the user expects. - * If the decoder parameter is non-NULL, av_find_best_stream will find the - * default decoder for the stream's codec; streams for which no decoder can - * be found are ignored. - * - * @param ic media file handle - * @param type stream type: video, audio, subtitles, etc. - * @param wanted_stream_nb user-requested stream number, - * or -1 for automatic selection - * @param related_stream try to find a stream related (eg. in the same - * program) to this one, or -1 if none - * @param decoder_ret if non-NULL, returns the decoder for the - * selected stream - * @param flags flags; none are currently defined - * @return the non-negative stream number in case of success, - * AVERROR_STREAM_NOT_FOUND if no stream with the requested type - * could be found, - * AVERROR_DECODER_NOT_FOUND if streams were found but no decoder - * @note If av_find_best_stream returns successfully and decoder_ret is not - * NULL, then *decoder_ret is guaranteed to be set to a valid AVCodec. - */ -int av_find_best_stream(AVFormatContext *ic, - enum AVMediaType type, - int wanted_stream_nb, - int related_stream, - AVCodec **decoder_ret, - int flags); - -#if FF_API_READ_PACKET -/** - * @deprecated use AVFMT_FLAG_NOFILLIN | AVFMT_FLAG_NOPARSE to read raw - * unprocessed packets - * - * Read a transport packet from a media file. - * - * This function is obsolete and should never be used. - * Use av_read_frame() instead. - * - * @param s media file handle - * @param pkt is filled - * @return 0 if OK, AVERROR_xxx on error - */ -attribute_deprecated -int av_read_packet(AVFormatContext *s, AVPacket *pkt); -#endif - -/** - * Return the next frame of a stream. - * This function returns what is stored in the file, and does not validate - * that what is there are valid frames for the decoder. It will split what is - * stored in the file into frames and return one for each call. It will not - * omit invalid data between valid frames so as to give the decoder the maximum - * information possible for decoding. - * - * If pkt->buf is NULL, then the packet is valid until the next - * av_read_frame() or until av_close_input_file(). Otherwise the packet is valid - * indefinitely. In both cases the packet must be freed with - * av_free_packet when it is no longer needed. For video, the packet contains - * exactly one frame. For audio, it contains an integer number of frames if each - * frame has a known fixed size (e.g. PCM or ADPCM data). If the audio frames - * have a variable size (e.g. MPEG audio), then it contains one frame. - * - * pkt->pts, pkt->dts and pkt->duration are always set to correct - * values in AVStream.time_base units (and guessed if the format cannot - * provide them). pkt->pts can be AV_NOPTS_VALUE if the video format - * has B-frames, so it is better to rely on pkt->dts if you do not - * decompress the payload. - * - * @return 0 if OK, < 0 on error or end of file - */ -int av_read_frame(AVFormatContext *s, AVPacket *pkt); - -/** - * Seek to the keyframe at timestamp. - * 'timestamp' in 'stream_index'. - * @param stream_index If stream_index is (-1), a default - * stream is selected, and timestamp is automatically converted - * from AV_TIME_BASE units to the stream specific time_base. - * @param timestamp Timestamp in AVStream.time_base units - * or, if no stream is specified, in AV_TIME_BASE units. - * @param flags flags which select direction and seeking mode - * @return >= 0 on success - */ -int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp, - int flags); - -/** - * Seek to timestamp ts. - * Seeking will be done so that the point from which all active streams - * can be presented successfully will be closest to ts and within min/max_ts. - * Active streams are all streams that have AVStream.discard < AVDISCARD_ALL. - * - * If flags contain AVSEEK_FLAG_BYTE, then all timestamps are in bytes and - * are the file position (this may not be supported by all demuxers). - * If flags contain AVSEEK_FLAG_FRAME, then all timestamps are in frames - * in the stream with stream_index (this may not be supported by all demuxers). - * Otherwise all timestamps are in units of the stream selected by stream_index - * or if stream_index is -1, in AV_TIME_BASE units. - * If flags contain AVSEEK_FLAG_ANY, then non-keyframes are treated as - * keyframes (this may not be supported by all demuxers). - * - * @param stream_index index of the stream which is used as time base reference - * @param min_ts smallest acceptable timestamp - * @param ts target timestamp - * @param max_ts largest acceptable timestamp - * @param flags flags - * @return >=0 on success, error code otherwise - * - * @note This is part of the new seek API which is still under construction. - * Thus do not use this yet. It may change at any time, do not expect - * ABI compatibility yet! - */ -int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags); - -/** - * Start playing a network-based stream (e.g. RTSP stream) at the - * current position. - */ -int av_read_play(AVFormatContext *s); - -/** - * Pause a network-based stream (e.g. RTSP stream). - * - * Use av_read_play() to resume it. - */ -int av_read_pause(AVFormatContext *s); - -#if FF_API_CLOSE_INPUT_FILE -/** - * @deprecated use avformat_close_input() - * Close a media file (but not its codecs). - * - * @param s media file handle - */ -attribute_deprecated -void av_close_input_file(AVFormatContext *s); -#endif - -/** - * Close an opened input AVFormatContext. Free it and all its contents - * and set *s to NULL. - */ -void avformat_close_input(AVFormatContext **s); -/** - * @} - */ - -#if FF_API_NEW_STREAM -/** - * Add a new stream to a media file. - * - * Can only be called in the read_header() function. If the flag - * AVFMTCTX_NOHEADER is in the format context, then new streams - * can be added in read_packet too. - * - * @param s media file handle - * @param id file-format-dependent stream ID - */ -attribute_deprecated -AVStream *av_new_stream(AVFormatContext *s, int id); -#endif - -#if FF_API_SET_PTS_INFO -/** - * @deprecated this function is not supposed to be called outside of lavf - */ -attribute_deprecated -void av_set_pts_info(AVStream *s, int pts_wrap_bits, - unsigned int pts_num, unsigned int pts_den); -#endif - -#define AVSEEK_FLAG_BACKWARD 1 ///< seek backward -#define AVSEEK_FLAG_BYTE 2 ///< seeking based on position in bytes -#define AVSEEK_FLAG_ANY 4 ///< seek to any frame, even non-keyframes -#define AVSEEK_FLAG_FRAME 8 ///< seeking based on frame number - -/** - * @addtogroup lavf_encoding - * @{ - */ -/** - * Allocate the stream private data and write the stream header to - * an output media file. - * - * @param s Media file handle, must be allocated with avformat_alloc_context(). - * Its oformat field must be set to the desired output format; - * Its pb field must be set to an already openened AVIOContext. - * @param options An AVDictionary filled with AVFormatContext and muxer-private options. - * On return this parameter will be destroyed and replaced with a dict containing - * options that were not found. May be NULL. - * - * @return 0 on success, negative AVERROR on failure. - * - * @see av_opt_find, av_dict_set, avio_open, av_oformat_next. - */ -int avformat_write_header(AVFormatContext *s, AVDictionary **options); - -/** - * Write a packet to an output media file. - * - * The packet shall contain one audio or video frame. - * The packet must be correctly interleaved according to the container - * specification, if not then av_interleaved_write_frame must be used. - * - * @param s media file handle - * @param pkt The packet, which contains the stream_index, buf/buf_size, - * 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); - -/** - * Write a packet to an output media file ensuring correct interleaving. - * - * The packet must contain one audio or video frame. - * If the packets are already correctly interleaved, the application should - * call av_write_frame() instead as it is slightly faster. It is also important - * to keep in mind that completely non-interleaved input will need huge amounts - * of memory to interleave with this, so it is preferable to interleave at the - * demuxer level. - * - * @param s media file handle - * @param pkt The packet containing the data to be written. pkt->buf must be set - * to a valid AVBufferRef describing the packet data. Libavformat takes - * ownership of this reference and will unref it when it sees fit. The caller - * must not access the data through this reference after this function returns. - * This can be NULL (at any time, not just at the end), to flush the - * interleaving queues. - * Packet's @ref AVPacket.stream_index "stream_index" field must be set to the - * index of the corresponding stream in @ref AVFormatContext.streams - * "s.streams". - * It is very strongly recommended that timing information (@ref AVPacket.pts - * "pts", @ref AVPacket.dts "dts" @ref AVPacket.duration "duration") is set to - * correct values. - * - * @return 0 on success, a negative AVERROR on error. - */ -int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt); - -/** - * Write the stream trailer to an output media file and free the - * file private data. - * - * May only be called after a successful call to avformat_write_header. - * - * @param s media file handle - * @return 0 if OK, AVERROR_xxx on error - */ -int av_write_trailer(AVFormatContext *s); - -/** - * Return the output format in the list of registered output formats - * which best matches the provided parameters, or return NULL if - * there is no match. - * - * @param short_name if non-NULL checks if short_name matches with the - * names of the registered formats - * @param filename if non-NULL checks if filename terminates with the - * extensions of the registered formats - * @param mime_type if non-NULL checks if mime_type matches with the - * MIME type of the registered formats - */ -AVOutputFormat *av_guess_format(const char *short_name, - const char *filename, - const char *mime_type); - -/** - * Guess the codec ID based upon muxer and filename. - */ -enum AVCodecID av_guess_codec(AVOutputFormat *fmt, const char *short_name, - const char *filename, const char *mime_type, - enum AVMediaType type); - -/** - * Get timing information for the data currently output. - * The exact meaning of "currently output" depends on the format. - * It is mostly relevant for devices that have an internal buffer and/or - * work in real time. - * @param s media file handle - * @param stream stream in the media file - * @param[out] dts DTS of the last packet output for the stream, in stream - * time_base units - * @param[out] wall absolute time when that packet whas output, - * in microsecond - * @return 0 if OK, AVERROR(ENOSYS) if the format does not support it - * Note: some formats or devices may not allow to measure dts and wall - * atomically. - */ -int av_get_output_timestamp(struct AVFormatContext *s, int stream, - int64_t *dts, int64_t *wall); - - -/** - * @} - */ - - -/** - * @defgroup lavf_misc Utility functions - * @ingroup libavf - * @{ - * - * Miscellaneous utility functions related to both muxing and demuxing - * (or neither). - */ - -/** - * Send a nice hexadecimal dump of a buffer to the specified file stream. - * - * @param f The file stream pointer where the dump should be sent to. - * @param buf buffer - * @param size buffer size - * - * @see av_hex_dump_log, av_pkt_dump2, av_pkt_dump_log2 - */ -void av_hex_dump(FILE *f, const uint8_t *buf, int size); - -/** - * Send a nice hexadecimal dump of a buffer to the log. - * - * @param avcl A pointer to an arbitrary struct of which the first field is a - * pointer to an AVClass struct. - * @param level The importance level of the message, lower values signifying - * higher importance. - * @param buf buffer - * @param size buffer size - * - * @see av_hex_dump, av_pkt_dump2, av_pkt_dump_log2 - */ -void av_hex_dump_log(void *avcl, int level, const uint8_t *buf, int size); - -/** - * Send a nice dump of a packet to the specified file stream. - * - * @param f The file stream pointer where the dump should be sent to. - * @param pkt packet to dump - * @param dump_payload True if the payload must be displayed, too. - * @param st AVStream that the packet belongs to - */ -void av_pkt_dump2(FILE *f, AVPacket *pkt, int dump_payload, AVStream *st); - - -/** - * Send a nice dump of a packet to the log. - * - * @param avcl A pointer to an arbitrary struct of which the first field is a - * pointer to an AVClass struct. - * @param level The importance level of the message, lower values signifying - * higher importance. - * @param pkt packet to dump - * @param dump_payload True if the payload must be displayed, too. - * @param st AVStream that the packet belongs to - */ -void av_pkt_dump_log2(void *avcl, int level, AVPacket *pkt, int dump_payload, - AVStream *st); - -/** - * Get the AVCodecID for the given codec tag tag. - * If no codec id is found returns AV_CODEC_ID_NONE. - * - * @param tags list of supported codec_id-codec_tag pairs, as stored - * in AVInputFormat.codec_tag and AVOutputFormat.codec_tag - */ -enum AVCodecID av_codec_get_id(const struct AVCodecTag * const *tags, unsigned int tag); - -/** - * Get the codec tag for the given codec id id. - * If no codec tag is found returns 0. - * - * @param tags list of supported codec_id-codec_tag pairs, as stored - * in AVInputFormat.codec_tag and AVOutputFormat.codec_tag - */ -unsigned int av_codec_get_tag(const struct AVCodecTag * const *tags, enum AVCodecID id); - -/** - * Get the codec tag for the given codec id. - * - * @param tags list of supported codec_id - codec_tag pairs, as stored - * in AVInputFormat.codec_tag and AVOutputFormat.codec_tag - * @param id codec id that should be searched for in the list - * @param tag A pointer to the found tag - * @return 0 if id was not found in tags, > 0 if it was found - */ -int av_codec_get_tag2(const struct AVCodecTag * const *tags, enum AVCodecID id, - unsigned int *tag); - -int av_find_default_stream_index(AVFormatContext *s); - -/** - * Get the index for a specific timestamp. - * @param flags if AVSEEK_FLAG_BACKWARD then the returned index will correspond - * to the timestamp which is <= the requested one, if backward - * is 0, then it will be >= - * if AVSEEK_FLAG_ANY seek to any frame, only keyframes otherwise - * @return < 0 if no such timestamp could be found - */ -int av_index_search_timestamp(AVStream *st, int64_t timestamp, int flags); - -/** - * Add an index entry into a sorted list. Update the entry if the list - * already contains it. - * - * @param timestamp timestamp in the time base of the given stream - */ -int av_add_index_entry(AVStream *st, int64_t pos, int64_t timestamp, - int size, int distance, int flags); - - -/** - * Split a URL string into components. - * - * The pointers to buffers for storing individual components may be null, - * in order to ignore that component. Buffers for components not found are - * set to empty strings. If the port is not found, it is set to a negative - * value. - * - * @param proto the buffer for the protocol - * @param proto_size the size of the proto buffer - * @param authorization the buffer for the authorization - * @param authorization_size the size of the authorization buffer - * @param hostname the buffer for the host name - * @param hostname_size the size of the hostname buffer - * @param port_ptr a pointer to store the port number in - * @param path the buffer for the path - * @param path_size the size of the path buffer - * @param url the URL to split - */ -void av_url_split(char *proto, int proto_size, - char *authorization, int authorization_size, - char *hostname, int hostname_size, - int *port_ptr, - char *path, int path_size, - const char *url); - - -void av_dump_format(AVFormatContext *ic, - int index, - const char *url, - int is_output); - -/** - * Return in 'buf' the path with '%d' replaced by a number. - * - * Also handles the '%0nd' format where 'n' is the total number - * of digits and '%%'. - * - * @param buf destination buffer - * @param buf_size destination buffer size - * @param path numbered sequence string - * @param number frame number - * @return 0 if OK, -1 on format error - */ -int av_get_frame_filename(char *buf, int buf_size, - const char *path, int number); - -/** - * Check whether filename actually is a numbered sequence generator. - * - * @param filename possible numbered sequence string - * @return 1 if a valid numbered sequence string, 0 otherwise - */ -int av_filename_number_test(const char *filename); - -/** - * Generate an SDP for an RTP session. - * - * Note, this overwrites the id values of AVStreams in the muxer contexts - * for getting unique dynamic payload types. - * - * @param ac array of AVFormatContexts describing the RTP streams. If the - * array is composed by only one context, such context can contain - * multiple AVStreams (one AVStream per RTP stream). Otherwise, - * all the contexts in the array (an AVCodecContext per RTP stream) - * must contain only one AVStream. - * @param n_files number of AVCodecContexts contained in ac - * @param buf buffer where the SDP will be stored (must be allocated by - * the caller) - * @param size the size of the buffer - * @return 0 if OK, AVERROR_xxx on error - */ -int av_sdp_create(AVFormatContext *ac[], int n_files, char *buf, int size); - -/** - * Return a positive value if the given filename has one of the given - * extensions, 0 otherwise. - * - * @param extensions a comma-separated list of filename extensions - */ -int av_match_ext(const char *filename, const char *extensions); - -/** - * Test if the given container can store a codec. - * - * @param std_compliance standards compliance level, one of FF_COMPLIANCE_* - * - * @return 1 if codec with ID codec_id can be stored in ofmt, 0 if it cannot. - * A negative number if this information is not available. - */ -int avformat_query_codec(AVOutputFormat *ofmt, enum AVCodecID codec_id, int std_compliance); - -/** - * @defgroup riff_fourcc RIFF FourCCs - * @{ - * Get the tables mapping RIFF FourCCs to libavcodec AVCodecIDs. The tables are - * meant to be passed to av_codec_get_id()/av_codec_get_tag() as in the - * following code: - * @code - * uint32_t tag = MKTAG('H', '2', '6', '4'); - * const struct AVCodecTag *table[] = { avformat_get_riff_video_tags(), 0 }; - * enum AVCodecID id = av_codec_get_id(table, tag); - * @endcode - */ -/** - * @return the table mapping RIFF FourCCs for video to libavcodec AVCodecID. - */ -const struct AVCodecTag *avformat_get_riff_video_tags(void); -/** - * @return the table mapping RIFF FourCCs for audio to AVCodecID. - */ -const struct AVCodecTag *avformat_get_riff_audio_tags(void); - -/** - * @} - */ - -/** - * Guess the sample aspect ratio of a frame, based on both the stream and the - * frame aspect ratio. - * - * Since the frame aspect ratio is set by the codec but the stream aspect ratio - * is set by the demuxer, these two may not be equal. This function tries to - * return the value that you should use if you would like to display the frame. - * - * Basic logic is to use the stream aspect ratio if it is set to something sane - * otherwise use the frame aspect ratio. This way a container setting, which is - * usually easy to modify can override the coded value in the frames. - * - * @param format the format context which the stream is part of - * @param stream the stream which the frame is part of - * @param frame the frame with the aspect ratio to be determined - * @return the guessed (valid) sample_aspect_ratio, 0/1 if no idea - */ -AVRational av_guess_sample_aspect_ratio(AVFormatContext *format, AVStream *stream, AVFrame *frame); - -/** - * Check if the stream st contained in s is matched by the stream specifier - * spec. - * - * See the "stream specifiers" chapter in the documentation for the syntax - * of spec. - * - * @return >0 if st is matched by spec; - * 0 if st is not matched by spec; - * AVERROR code if spec is invalid - * - * @note A stream specifier can match several streams in the format. - */ -int avformat_match_stream_specifier(AVFormatContext *s, AVStream *st, - const char *spec); - -int avformat_queue_attached_pictures(AVFormatContext *s); - - -/** - * @} - */ - -#endif /* AVFORMAT_AVFORMAT_H */ diff --git a/ffmpeg1/libavformat/avi.h b/ffmpeg1/libavformat/avi.h deleted file mode 100644 index 34da76f..0000000 --- a/ffmpeg1/libavformat/avi.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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 AVFORMAT_AVI_H -#define AVFORMAT_AVI_H - -#define AVIF_HASINDEX 0x00000010 // Index at end of file? -#define AVIF_MUSTUSEINDEX 0x00000020 -#define AVIF_ISINTERLEAVED 0x00000100 -#define AVIF_TRUSTCKTYPE 0x00000800 // Use CKType to find key frames? -#define AVIF_WASCAPTUREFILE 0x00010000 -#define AVIF_COPYRIGHTED 0x00020000 - -#define AVI_MAX_RIFF_SIZE 0x40000000LL -#define AVI_MASTER_INDEX_SIZE 256 -#define AVI_MAX_STREAM_COUNT 100 - -/* index flags */ -#define AVIIF_INDEX 0x10 - -#endif /* AVFORMAT_AVI_H */ diff --git a/ffmpeg1/libavformat/avidec.c b/ffmpeg1/libavformat/avidec.c deleted file mode 100644 index f6eb71e..0000000 --- a/ffmpeg1/libavformat/avidec.c +++ /dev/null @@ -1,1614 +0,0 @@ -/* - * AVI demuxer - * 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 - */ - -#include "libavutil/intreadwrite.h" -#include "libavutil/mathematics.h" -#include "libavutil/bswap.h" -#include "libavutil/opt.h" -#include "libavutil/dict.h" -#include "libavutil/avstring.h" -#include "libavutil/avassert.h" -#include "avformat.h" -#include "internal.h" -#include "avi.h" -#include "dv.h" -#include "riff.h" - -typedef struct AVIStream { - int64_t frame_offset; /* current frame (video) or byte (audio) counter - (used to compute the pts) */ - int remaining; - int packet_size; - - uint32_t scale; - uint32_t rate; - int sample_size; /* size of one sample (or packet) (in the rate/scale sense) in bytes */ - - int64_t cum_len; /* temporary storage (used during seek) */ - - int prefix; ///< normally 'd'<<8 + 'c' or 'w'<<8 + 'b' - int prefix_count; - uint32_t pal[256]; - int has_pal; - int dshow_block_align; ///< block align variable used to emulate bugs in the MS dshow demuxer - - AVFormatContext *sub_ctx; - AVPacket sub_pkt; - uint8_t *sub_buffer; - - int64_t seek_pos; -} AVIStream; - -typedef struct { - const AVClass *class; - int64_t riff_end; - int64_t movi_end; - int64_t fsize; - int64_t io_fsize; - int64_t movi_list; - int64_t last_pkt_pos; - int index_loaded; - int is_odml; - int non_interleaved; - int stream_index; - DVDemuxContext* dv_demux; - int odml_depth; - int use_odml; -#define MAX_ODML_DEPTH 1000 - int64_t dts_max; -} AVIContext; - - -static const AVOption options[] = { - { "use_odml", "use odml index", offsetof(AVIContext, use_odml), AV_OPT_TYPE_INT, {.i64 = 1}, -1, 1, AV_OPT_FLAG_DECODING_PARAM}, - { NULL }, -}; - -static const AVClass demuxer_class = { - .class_name = "avi", - .item_name = av_default_item_name, - .option = options, - .version = LIBAVUTIL_VERSION_INT, - .category = AV_CLASS_CATEGORY_DEMUXER, -}; - - -static const char avi_headers[][8] = { - { 'R', 'I', 'F', 'F', 'A', 'V', 'I', ' ' }, - { 'R', 'I', 'F', 'F', 'A', 'V', 'I', 'X' }, - { 'R', 'I', 'F', 'F', 'A', 'V', 'I', 0x19}, - { 'O', 'N', '2', ' ', 'O', 'N', '2', 'f' }, - { 'R', 'I', 'F', 'F', 'A', 'M', 'V', ' ' }, - { 0 } -}; - -static const AVMetadataConv avi_metadata_conv[] = { - { "strn", "title" }, - { 0 }, -}; - -static int avi_load_index(AVFormatContext *s); -static int guess_ni_flag(AVFormatContext *s); - -#define print_tag(str, tag, size) \ - av_dlog(NULL, "%s: tag=%c%c%c%c size=0x%x\n", \ - str, tag & 0xff, \ - (tag >> 8) & 0xff, \ - (tag >> 16) & 0xff, \ - (tag >> 24) & 0xff, \ - size) - -static inline int get_duration(AVIStream *ast, int len){ - if(ast->sample_size){ - return len; - }else if (ast->dshow_block_align){ - return (len + ast->dshow_block_align - 1)/ast->dshow_block_align; - }else - return 1; -} - -static int get_riff(AVFormatContext *s, AVIOContext *pb) -{ - AVIContext *avi = s->priv_data; - char header[8]; - int i; - - /* check RIFF header */ - avio_read(pb, header, 4); - avi->riff_end = avio_rl32(pb); /* RIFF chunk size */ - avi->riff_end += avio_tell(pb); /* RIFF chunk end */ - avio_read(pb, header+4, 4); - - for(i=0; avi_headers[i][0]; i++) - if(!memcmp(header, avi_headers[i], 8)) - break; - if(!avi_headers[i][0]) - return AVERROR_INVALIDDATA; - - if(header[7] == 0x19) - av_log(s, AV_LOG_INFO, "This file has been generated by a totally broken muxer.\n"); - - return 0; -} - -static int read_braindead_odml_indx(AVFormatContext *s, int frame_num){ - AVIContext *avi = s->priv_data; - AVIOContext *pb = s->pb; - int longs_pre_entry= avio_rl16(pb); - int index_sub_type = avio_r8(pb); - int index_type = avio_r8(pb); - int entries_in_use = avio_rl32(pb); - int chunk_id = avio_rl32(pb); - int64_t base = avio_rl64(pb); - int stream_id= 10*((chunk_id&0xFF) - '0') + (((chunk_id>>8)&0xFF) - '0'); - AVStream *st; - AVIStream *ast; - int i; - int64_t last_pos= -1; - int64_t filesize= avi->fsize; - - av_dlog(s, "longs_pre_entry:%d index_type:%d entries_in_use:%d chunk_id:%X base:%16"PRIX64"\n", - longs_pre_entry,index_type, entries_in_use, chunk_id, base); - - if(stream_id >= s->nb_streams || stream_id < 0) - return AVERROR_INVALIDDATA; - st= s->streams[stream_id]; - ast = st->priv_data; - - if(index_sub_type) - return AVERROR_INVALIDDATA; - - avio_rl32(pb); - - if(index_type && longs_pre_entry != 2) - return AVERROR_INVALIDDATA; - if(index_type>1) - return AVERROR_INVALIDDATA; - - if(filesize > 0 && base >= filesize){ - av_log(s, AV_LOG_ERROR, "ODML index invalid\n"); - if(base>>32 == (base & 0xFFFFFFFF) && (base & 0xFFFFFFFF) < filesize && filesize <= 0xFFFFFFFF) - base &= 0xFFFFFFFF; - else - return AVERROR_INVALIDDATA; - } - - for(i=0; i= 0; - len &= 0x7FFFFFFF; - -#ifdef DEBUG_SEEK - av_log(s, AV_LOG_ERROR, "pos:%"PRId64", len:%X\n", pos, len); -#endif - if(url_feof(pb)) - return AVERROR_INVALIDDATA; - - if(last_pos == pos || pos == base - 8) - avi->non_interleaved= 1; - if(last_pos != pos && (len || !ast->sample_size)) - av_add_index_entry(st, pos, ast->cum_len, len, 0, key ? AVINDEX_KEYFRAME : 0); - - ast->cum_len += get_duration(ast, len); - last_pos= pos; - }else{ - int64_t offset, pos; - int duration; - offset = avio_rl64(pb); - avio_rl32(pb); /* size */ - duration = avio_rl32(pb); - - if(url_feof(pb)) - return AVERROR_INVALIDDATA; - - pos = avio_tell(pb); - - if(avi->odml_depth > MAX_ODML_DEPTH){ - av_log(s, AV_LOG_ERROR, "Too deeply nested ODML indexes\n"); - return AVERROR_INVALIDDATA; - } - - if(avio_seek(pb, offset+8, SEEK_SET) < 0) - return -1; - avi->odml_depth++; - read_braindead_odml_indx(s, frame_num); - avi->odml_depth--; - frame_num += duration; - - if(avio_seek(pb, pos, SEEK_SET) < 0) { - av_log(s, AV_LOG_ERROR, "Failed to restore position after reading index\n"); - return -1; - } - - } - } - avi->index_loaded=2; - return 0; -} - -static void clean_index(AVFormatContext *s){ - int i; - int64_t j; - - for(i=0; inb_streams; i++){ - AVStream *st = s->streams[i]; - AVIStream *ast = st->priv_data; - int n= st->nb_index_entries; - int max= ast->sample_size; - int64_t pos, size, ts; - - if(n != 1 || ast->sample_size==0) - continue; - - while(max < 1024) max+=max; - - pos= st->index_entries[0].pos; - size= st->index_entries[0].size; - ts= st->index_entries[0].timestamp; - - for(j=0; jpb; - char key[5] = {0}, *value; - - size += (size & 1); - - if (size == UINT_MAX) - return AVERROR(EINVAL); - value = av_malloc(size+1); - if (!value) - return AVERROR(ENOMEM); - avio_read(pb, value, size); - value[size]=0; - - AV_WL32(key, tag); - - return av_dict_set(st ? &st->metadata : &s->metadata, key, value, - AV_DICT_DONT_STRDUP_VAL); -} - -static const char months[12][4] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", - "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; - -static void avi_metadata_creation_time(AVDictionary **metadata, char *date) -{ - char month[4], time[9], buffer[64]; - int i, day, year; - /* parse standard AVI date format (ie. "Mon Mar 10 15:04:43 2003") */ - if (sscanf(date, "%*3s%*[ ]%3s%*[ ]%2d%*[ ]%8s%*[ ]%4d", - month, &day, time, &year) == 4) { - for (i=0; i<12; i++) - if (!av_strcasecmp(month, months[i])) { - snprintf(buffer, sizeof(buffer), "%.4d-%.2d-%.2d %s", - year, i+1, day, time); - av_dict_set(metadata, "creation_time", buffer, 0); - } - } else if (date[4] == '/' && date[7] == '/') { - date[4] = date[7] = '-'; - av_dict_set(metadata, "creation_time", date, 0); - } -} - -static void avi_read_nikon(AVFormatContext *s, uint64_t end) -{ - while (avio_tell(s->pb) < end) { - uint32_t tag = avio_rl32(s->pb); - uint32_t size = avio_rl32(s->pb); - switch (tag) { - case MKTAG('n', 'c', 't', 'g'): { /* Nikon Tags */ - uint64_t tag_end = avio_tell(s->pb) + size; - while (avio_tell(s->pb) < tag_end) { - uint16_t tag = avio_rl16(s->pb); - uint16_t size = avio_rl16(s->pb); - const char *name = NULL; - char buffer[64] = {0}; - size -= avio_read(s->pb, buffer, - FFMIN(size, sizeof(buffer)-1)); - switch (tag) { - case 0x03: name = "maker"; break; - case 0x04: name = "model"; break; - case 0x13: name = "creation_time"; - if (buffer[4] == ':' && buffer[7] == ':') - buffer[4] = buffer[7] = '-'; - break; - } - if (name) - av_dict_set(&s->metadata, name, buffer, 0); - avio_skip(s->pb, size); - } - break; - } - default: - avio_skip(s->pb, size); - break; - } - } -} - -static int avi_read_header(AVFormatContext *s) -{ - AVIContext *avi = s->priv_data; - AVIOContext *pb = s->pb; - unsigned int tag, tag1, handler; - int codec_type, stream_index, frame_period; - unsigned int size; - int i; - AVStream *st; - AVIStream *ast = NULL; - int avih_width=0, avih_height=0; - int amv_file_format=0; - uint64_t list_end = 0; - int ret; - - avi->stream_index= -1; - - ret = get_riff(s, pb); - if (ret < 0) - return ret; - - av_log(avi, AV_LOG_DEBUG, "use odml:%d\n", avi->use_odml); - - avi->io_fsize = avi->fsize = avio_size(pb); - if(avi->fsize<=0 || avi->fsize < avi->riff_end) - avi->fsize= avi->riff_end == 8 ? INT64_MAX : avi->riff_end; - - /* first list tag */ - stream_index = -1; - codec_type = -1; - frame_period = 0; - for(;;) { - if (url_feof(pb)) - goto fail; - tag = avio_rl32(pb); - size = avio_rl32(pb); - - print_tag("tag", tag, size); - - switch(tag) { - case MKTAG('L', 'I', 'S', 'T'): - list_end = avio_tell(pb) + size; - /* Ignored, except at start of video packets. */ - tag1 = avio_rl32(pb); - - print_tag("list", tag1, 0); - - if (tag1 == MKTAG('m', 'o', 'v', 'i')) { - avi->movi_list = avio_tell(pb) - 4; - if(size) avi->movi_end = avi->movi_list + size + (size & 1); - else avi->movi_end = avi->fsize; - av_dlog(NULL, "movi end=%"PRIx64"\n", avi->movi_end); - goto end_of_header; - } - else if (tag1 == MKTAG('I', 'N', 'F', 'O')) - ff_read_riff_info(s, size - 4); - else if (tag1 == MKTAG('n', 'c', 'd', 't')) - avi_read_nikon(s, list_end); - - break; - case MKTAG('I', 'D', 'I', 'T'): { - unsigned char date[64] = {0}; - size += (size & 1); - size -= avio_read(pb, date, FFMIN(size, sizeof(date)-1)); - avio_skip(pb, size); - avi_metadata_creation_time(&s->metadata, date); - break; - } - case MKTAG('d', 'm', 'l', 'h'): - avi->is_odml = 1; - avio_skip(pb, size + (size & 1)); - break; - case MKTAG('a', 'm', 'v', 'h'): - amv_file_format=1; - case MKTAG('a', 'v', 'i', 'h'): - /* AVI header */ - /* using frame_period is bad idea */ - frame_period = avio_rl32(pb); - avio_rl32(pb); /* max. bytes per second */ - avio_rl32(pb); - avi->non_interleaved |= avio_rl32(pb) & AVIF_MUSTUSEINDEX; - - avio_skip(pb, 2 * 4); - avio_rl32(pb); - avio_rl32(pb); - avih_width=avio_rl32(pb); - avih_height=avio_rl32(pb); - - avio_skip(pb, size - 10 * 4); - break; - case MKTAG('s', 't', 'r', 'h'): - /* stream header */ - - tag1 = avio_rl32(pb); - handler = avio_rl32(pb); /* codec tag */ - - if(tag1 == MKTAG('p', 'a', 'd', 's')){ - avio_skip(pb, size - 8); - break; - }else{ - stream_index++; - st = avformat_new_stream(s, NULL); - if (!st) - goto fail; - - st->id = stream_index; - ast = av_mallocz(sizeof(AVIStream)); - if (!ast) - goto fail; - st->priv_data = ast; - } - if(amv_file_format) - tag1 = stream_index ? MKTAG('a','u','d','s') : MKTAG('v','i','d','s'); - - print_tag("strh", tag1, -1); - - if(tag1 == MKTAG('i', 'a', 'v', 's') || tag1 == MKTAG('i', 'v', 'a', 's')){ - int64_t dv_dur; - - /* - * After some consideration -- I don't think we - * have to support anything but DV in type1 AVIs. - */ - if (s->nb_streams != 1) - goto fail; - - if (handler != MKTAG('d', 'v', 's', 'd') && - handler != MKTAG('d', 'v', 'h', 'd') && - handler != MKTAG('d', 'v', 's', 'l')) - goto fail; - - ast = s->streams[0]->priv_data; - av_freep(&s->streams[0]->codec->extradata); - av_freep(&s->streams[0]->codec); - if (s->streams[0]->info) - av_freep(&s->streams[0]->info->duration_error); - av_freep(&s->streams[0]->info); - av_freep(&s->streams[0]); - s->nb_streams = 0; - if (CONFIG_DV_DEMUXER) { - avi->dv_demux = avpriv_dv_init_demux(s); - if (!avi->dv_demux) - goto fail; - } - s->streams[0]->priv_data = ast; - avio_skip(pb, 3 * 4); - ast->scale = avio_rl32(pb); - ast->rate = avio_rl32(pb); - avio_skip(pb, 4); /* start time */ - - dv_dur = avio_rl32(pb); - if (ast->scale > 0 && ast->rate > 0 && dv_dur > 0) { - dv_dur *= AV_TIME_BASE; - s->duration = av_rescale(dv_dur, ast->scale, ast->rate); - } - /* - * else, leave duration alone; timing estimation in utils.c - * will make a guess based on bitrate. - */ - - stream_index = s->nb_streams - 1; - avio_skip(pb, size - 9*4); - break; - } - - av_assert0(stream_index < s->nb_streams); - st->codec->stream_codec_tag= handler; - - avio_rl32(pb); /* flags */ - avio_rl16(pb); /* priority */ - avio_rl16(pb); /* language */ - avio_rl32(pb); /* initial frame */ - ast->scale = avio_rl32(pb); - ast->rate = avio_rl32(pb); - if(!(ast->scale && ast->rate)){ - av_log(s, AV_LOG_WARNING, "scale/rate is %u/%u which is invalid. (This file has been generated by broken software.)\n", ast->scale, ast->rate); - if(frame_period){ - ast->rate = 1000000; - ast->scale = frame_period; - }else{ - ast->rate = 25; - ast->scale = 1; - } - } - avpriv_set_pts_info(st, 64, ast->scale, ast->rate); - - ast->cum_len=avio_rl32(pb); /* start */ - st->nb_frames = avio_rl32(pb); - - st->start_time = 0; - avio_rl32(pb); /* buffer size */ - avio_rl32(pb); /* quality */ - if (ast->cum_len*ast->scale/ast->rate > 3600) { - av_log(s, AV_LOG_ERROR, "crazy start time, iam scared, giving up\n"); - return AVERROR_INVALIDDATA; - } - ast->sample_size = avio_rl32(pb); /* sample ssize */ - ast->cum_len *= FFMAX(1, ast->sample_size); - av_dlog(s, "%"PRIu32" %"PRIu32" %d\n", - ast->rate, ast->scale, ast->sample_size); - - switch(tag1) { - case MKTAG('v', 'i', 'd', 's'): - codec_type = AVMEDIA_TYPE_VIDEO; - - ast->sample_size = 0; - break; - case MKTAG('a', 'u', 'd', 's'): - codec_type = AVMEDIA_TYPE_AUDIO; - break; - case MKTAG('t', 'x', 't', 's'): - codec_type = AVMEDIA_TYPE_SUBTITLE; - break; - case MKTAG('d', 'a', 't', 's'): - codec_type = AVMEDIA_TYPE_DATA; - break; - default: - av_log(s, AV_LOG_INFO, "unknown stream type %X\n", tag1); - } - if(ast->sample_size == 0) { - st->duration = st->nb_frames; - if (st->duration > 0 && avi->io_fsize > 0 && avi->riff_end > avi->io_fsize) { - av_log(s, AV_LOG_DEBUG, "File is truncated adjusting duration\n"); - st->duration = av_rescale(st->duration, avi->io_fsize, avi->riff_end); - } - } - ast->frame_offset= ast->cum_len; - avio_skip(pb, size - 12 * 4); - break; - case MKTAG('s', 't', 'r', 'f'): - /* stream header */ - if (!size) - break; - if (stream_index >= (unsigned)s->nb_streams || avi->dv_demux) { - avio_skip(pb, size); - } else { - uint64_t cur_pos = avio_tell(pb); - unsigned esize; - if (cur_pos < list_end) - size = FFMIN(size, list_end - cur_pos); - st = s->streams[stream_index]; - switch(codec_type) { - case AVMEDIA_TYPE_VIDEO: - if(amv_file_format){ - st->codec->width=avih_width; - st->codec->height=avih_height; - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = AV_CODEC_ID_AMV; - avio_skip(pb, size); - break; - } - tag1 = ff_get_bmp_header(pb, st, &esize); - - if (tag1 == MKTAG('D', 'X', 'S', 'B') || tag1 == MKTAG('D','X','S','A')) { - st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE; - st->codec->codec_tag = tag1; - st->codec->codec_id = AV_CODEC_ID_XSUB; - break; - } - - if(size > 10*4 && size<(1<<30) && size < avi->fsize){ - if(esize == size-1 && (esize&1)) st->codec->extradata_size= esize - 10*4; - else st->codec->extradata_size= size - 10*4; - st->codec->extradata= av_malloc(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!st->codec->extradata) { - st->codec->extradata_size= 0; - return AVERROR(ENOMEM); - } - avio_read(pb, st->codec->extradata, st->codec->extradata_size); - } - - if(st->codec->extradata_size & 1) //FIXME check if the encoder really did this correctly - avio_r8(pb); - - /* Extract palette from extradata if bpp <= 8. */ - /* This code assumes that extradata contains only palette. */ - /* This is true for all paletted codecs implemented in FFmpeg. */ - if (st->codec->extradata_size && (st->codec->bits_per_coded_sample <= 8)) { - int pal_size = (1 << st->codec->bits_per_coded_sample) << 2; - const uint8_t *pal_src; - - pal_size = FFMIN(pal_size, st->codec->extradata_size); - pal_src = st->codec->extradata + st->codec->extradata_size - pal_size; - for (i = 0; i < pal_size/4; i++) - ast->pal[i] = 0xFFU<<24 | AV_RL32(pal_src+4*i); - ast->has_pal = 1; - } - - print_tag("video", tag1, 0); - - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_tag = tag1; - st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, tag1); - st->need_parsing = AVSTREAM_PARSE_HEADERS; // This is needed to get the pict type which is necessary for generating correct pts. - - if(st->codec->codec_tag==0 && st->codec->height > 0 && st->codec->extradata_size < 1U<<30){ - st->codec->extradata_size+= 9; - st->codec->extradata= av_realloc_f(st->codec->extradata, 1, st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); - if(st->codec->extradata) - memcpy(st->codec->extradata + st->codec->extradata_size - 9, "BottomUp", 9); - } - st->codec->height= FFABS(st->codec->height); - -// avio_skip(pb, size - 5 * 4); - break; - case AVMEDIA_TYPE_AUDIO: - ret = ff_get_wav_header(pb, st->codec, size); - if (ret < 0) - return ret; - ast->dshow_block_align= st->codec->block_align; - if(ast->sample_size && st->codec->block_align && ast->sample_size != st->codec->block_align){ - av_log(s, AV_LOG_WARNING, "sample size (%d) != block align (%d)\n", ast->sample_size, st->codec->block_align); - ast->sample_size= st->codec->block_align; - } - if (size&1) /* 2-aligned (fix for Stargate SG-1 - 3x18 - Shades of Grey.avi) */ - avio_skip(pb, 1); - /* Force parsing as several audio frames can be in - * one packet and timestamps refer to packet start. */ - st->need_parsing = AVSTREAM_PARSE_TIMESTAMPS; - /* ADTS header is in extradata, AAC without header must be - * stored as exact frames. Parser not needed and it will - * fail. */ - if (st->codec->codec_id == AV_CODEC_ID_AAC && st->codec->extradata_size) - st->need_parsing = AVSTREAM_PARSE_NONE; - /* AVI files with Xan DPCM audio (wrongly) declare PCM - * audio in the header but have Axan as stream_code_tag. */ - if (st->codec->stream_codec_tag == AV_RL32("Axan")){ - st->codec->codec_id = AV_CODEC_ID_XAN_DPCM; - st->codec->codec_tag = 0; - ast->dshow_block_align = 0; - } - if (amv_file_format){ - st->codec->codec_id = AV_CODEC_ID_ADPCM_IMA_AMV; - ast->dshow_block_align = 0; - } - if(st->codec->codec_id == AV_CODEC_ID_AAC && ast->dshow_block_align <= 4 && ast->dshow_block_align) { - av_log(s, AV_LOG_DEBUG, "overriding invalid dshow_block_align of %d\n", ast->dshow_block_align); - ast->dshow_block_align = 0; - } - if(st->codec->codec_id == AV_CODEC_ID_AAC && ast->dshow_block_align == 1024 && ast->sample_size == 1024 || - st->codec->codec_id == AV_CODEC_ID_AAC && ast->dshow_block_align == 4096 && ast->sample_size == 4096 || - st->codec->codec_id == AV_CODEC_ID_MP3 && ast->dshow_block_align == 1152 && ast->sample_size == 1152) { - av_log(s, AV_LOG_DEBUG, "overriding sample_size\n"); - ast->sample_size = 0; - } - break; - case AVMEDIA_TYPE_SUBTITLE: - st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE; - st->request_probe= 1; - avio_skip(pb, size); - break; - default: - st->codec->codec_type = AVMEDIA_TYPE_DATA; - st->codec->codec_id= AV_CODEC_ID_NONE; - st->codec->codec_tag= 0; - avio_skip(pb, size); - break; - } - } - break; - case MKTAG('s', 't', 'r', 'd'): - if (stream_index >= (unsigned)s->nb_streams || s->streams[stream_index]->codec->extradata_size) { - avio_skip(pb, size); - } else { - uint64_t cur_pos = avio_tell(pb); - if (cur_pos < list_end) - size = FFMIN(size, list_end - cur_pos); - st = s->streams[stream_index]; - - if(size<(1<<30)){ - st->codec->extradata_size= size; - st->codec->extradata= av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!st->codec->extradata) { - st->codec->extradata_size= 0; - return AVERROR(ENOMEM); - } - avio_read(pb, st->codec->extradata, st->codec->extradata_size); - } - - if(st->codec->extradata_size & 1) //FIXME check if the encoder really did this correctly - avio_r8(pb); - } - break; - case MKTAG('i', 'n', 'd', 'x'): - i= avio_tell(pb); - if(pb->seekable && !(s->flags & AVFMT_FLAG_IGNIDX) && avi->use_odml && - read_braindead_odml_indx(s, 0) < 0 && (s->error_recognition & AV_EF_EXPLODE)) - goto fail; - avio_seek(pb, i+size, SEEK_SET); - break; - case MKTAG('v', 'p', 'r', 'p'): - if(stream_index < (unsigned)s->nb_streams && size > 9*4){ - AVRational active, active_aspect; - - st = s->streams[stream_index]; - avio_rl32(pb); - avio_rl32(pb); - avio_rl32(pb); - avio_rl32(pb); - avio_rl32(pb); - - active_aspect.den= avio_rl16(pb); - active_aspect.num= avio_rl16(pb); - active.num = avio_rl32(pb); - active.den = avio_rl32(pb); - avio_rl32(pb); //nbFieldsPerFrame - - if(active_aspect.num && active_aspect.den && active.num && active.den){ - st->sample_aspect_ratio= av_div_q(active_aspect, active); - av_dlog(s, "vprp %d/%d %d/%d\n", - active_aspect.num, active_aspect.den, - active.num, active.den); - } - size -= 9*4; - } - avio_skip(pb, size); - break; - case MKTAG('s', 't', 'r', 'n'): - if(s->nb_streams){ - ret = avi_read_tag(s, s->streams[s->nb_streams-1], tag, size); - if (ret < 0) - return ret; - break; - } - default: - if(size > 1000000){ - av_log(s, AV_LOG_ERROR, "Something went wrong during header parsing, " - "I will ignore it and try to continue anyway.\n"); - if (s->error_recognition & AV_EF_EXPLODE) - goto fail; - avi->movi_list = avio_tell(pb) - 4; - avi->movi_end = avi->fsize; - goto end_of_header; - } - /* skip tag */ - size += (size & 1); - avio_skip(pb, size); - break; - } - } - end_of_header: - /* check stream number */ - if (stream_index != s->nb_streams - 1) { - fail: - return AVERROR_INVALIDDATA; - } - - if(!avi->index_loaded && pb->seekable) - avi_load_index(s); - avi->index_loaded |= 1; - avi->non_interleaved |= guess_ni_flag(s) | (s->flags & AVFMT_FLAG_SORT_DTS); - for(i=0; inb_streams; i++){ - AVStream *st = s->streams[i]; - if(st->nb_index_entries) - break; - } - // DV-in-AVI cannot be non-interleaved, if set this must be - // a mis-detection. - if(avi->dv_demux) - avi->non_interleaved=0; - if(i==s->nb_streams && avi->non_interleaved) { - av_log(s, AV_LOG_WARNING, "non-interleaved AVI without index, switching to interleaved\n"); - avi->non_interleaved=0; - } - - if(avi->non_interleaved) { - av_log(s, AV_LOG_INFO, "non-interleaved AVI\n"); - clean_index(s); - } - - ff_metadata_conv_ctx(s, NULL, avi_metadata_conv); - ff_metadata_conv_ctx(s, NULL, ff_riff_info_conv); - - return 0; -} - -static int read_gab2_sub(AVStream *st, AVPacket *pkt) { - if (pkt->data && !strcmp(pkt->data, "GAB2") && AV_RL16(pkt->data+5) == 2) { - uint8_t desc[256]; - int score = AVPROBE_SCORE_MAX / 2, ret; - AVIStream *ast = st->priv_data; - AVInputFormat *sub_demuxer; - AVRational time_base; - AVIOContext *pb = avio_alloc_context( pkt->data + 7, - pkt->size - 7, - 0, NULL, NULL, NULL, NULL); - AVProbeData pd; - unsigned int desc_len = avio_rl32(pb); - - if (desc_len > pb->buf_end - pb->buf_ptr) - goto error; - - ret = avio_get_str16le(pb, desc_len, desc, sizeof(desc)); - avio_skip(pb, desc_len - ret); - if (*desc) - av_dict_set(&st->metadata, "title", desc, 0); - - avio_rl16(pb); /* flags? */ - avio_rl32(pb); /* data size */ - - pd = (AVProbeData) { .buf = pb->buf_ptr, .buf_size = pb->buf_end - pb->buf_ptr }; - if (!(sub_demuxer = av_probe_input_format2(&pd, 1, &score))) - goto error; - - if (!(ast->sub_ctx = avformat_alloc_context())) - goto error; - - ast->sub_ctx->pb = pb; - if (!avformat_open_input(&ast->sub_ctx, "", sub_demuxer, NULL)) { - ff_read_packet(ast->sub_ctx, &ast->sub_pkt); - *st->codec = *ast->sub_ctx->streams[0]->codec; - ast->sub_ctx->streams[0]->codec->extradata = NULL; - time_base = ast->sub_ctx->streams[0]->time_base; - avpriv_set_pts_info(st, 64, time_base.num, time_base.den); - } - ast->sub_buffer = pkt->data; - memset(pkt, 0, sizeof(*pkt)); - return 1; -error: - av_freep(&pb); - } - return 0; -} - -static AVStream *get_subtitle_pkt(AVFormatContext *s, AVStream *next_st, - AVPacket *pkt) -{ - AVIStream *ast, *next_ast = next_st->priv_data; - int64_t ts, next_ts, ts_min = INT64_MAX; - AVStream *st, *sub_st = NULL; - int i; - - next_ts = av_rescale_q(next_ast->frame_offset, next_st->time_base, - AV_TIME_BASE_Q); - - for (i=0; inb_streams; i++) { - st = s->streams[i]; - ast = st->priv_data; - if (st->discard < AVDISCARD_ALL && ast && ast->sub_pkt.data) { - ts = av_rescale_q(ast->sub_pkt.dts, st->time_base, AV_TIME_BASE_Q); - if (ts <= next_ts && ts < ts_min) { - ts_min = ts; - sub_st = st; - } - } - } - - if (sub_st) { - ast = sub_st->priv_data; - *pkt = ast->sub_pkt; - pkt->stream_index = sub_st->index; - if (ff_read_packet(ast->sub_ctx, &ast->sub_pkt) < 0) - ast->sub_pkt.data = NULL; - } - return sub_st; -} - -static int get_stream_idx(int *d){ - if( d[0] >= '0' && d[0] <= '9' - && d[1] >= '0' && d[1] <= '9'){ - return (d[0] - '0') * 10 + (d[1] - '0'); - }else{ - return 100; //invalid stream ID - } -} - -/** - * - * @param exit_early set to 1 to just gather packet position without making the changes needed to actually read & return the packet - */ -static int avi_sync(AVFormatContext *s, int exit_early) -{ - AVIContext *avi = s->priv_data; - AVIOContext *pb = s->pb; - int n; - unsigned int d[8]; - unsigned int size; - int64_t i, sync; - -start_sync: - memset(d, -1, sizeof(d)); - for(i=sync=avio_tell(pb); !url_feof(pb); i++) { - int j; - - for(j=0; j<7; j++) - d[j]= d[j+1]; - d[7]= avio_r8(pb); - - size= d[4] + (d[5]<<8) + (d[6]<<16) + (d[7]<<24); - - n= get_stream_idx(d+2); - av_dlog(s, "%X %X %X %X %X %X %X %X %"PRId64" %u %d\n", - d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], i, size, n); - if(i + (uint64_t)size > avi->fsize || d[0] > 127) - continue; - - //parse ix## - if( (d[0] == 'i' && d[1] == 'x' && n < s->nb_streams) - //parse JUNK - ||(d[0] == 'J' && d[1] == 'U' && d[2] == 'N' && d[3] == 'K') - ||(d[0] == 'i' && d[1] == 'd' && d[2] == 'x' && d[3] == '1')){ - avio_skip(pb, size); - goto start_sync; - } - - //parse stray LIST - if(d[0] == 'L' && d[1] == 'I' && d[2] == 'S' && d[3] == 'T'){ - avio_skip(pb, 4); - goto start_sync; - } - - n= get_stream_idx(d); - - if(!((i-avi->last_pkt_pos)&1) && get_stream_idx(d+1) < s->nb_streams) - continue; - - //detect ##ix chunk and skip - if(d[2] == 'i' && d[3] == 'x' && n < s->nb_streams){ - avio_skip(pb, size); - goto start_sync; - } - - //parse ##dc/##wb - if(n < s->nb_streams){ - AVStream *st; - AVIStream *ast; - st = s->streams[n]; - ast = st->priv_data; - - if (!ast) { - av_log(s, AV_LOG_WARNING, "Skiping foreign stream %d packet\n", n); - continue; - } - - if(s->nb_streams>=2){ - AVStream *st1 = s->streams[1]; - AVIStream *ast1= st1->priv_data; - //workaround for broken small-file-bug402.avi - if( d[2] == 'w' && d[3] == 'b' - && n==0 - && st ->codec->codec_type == AVMEDIA_TYPE_VIDEO - && st1->codec->codec_type == AVMEDIA_TYPE_AUDIO - && ast->prefix == 'd'*256+'c' - && (d[2]*256+d[3] == ast1->prefix || !ast1->prefix_count) - ){ - n=1; - st = st1; - ast = ast1; - av_log(s, AV_LOG_WARNING, "Invalid stream + prefix combination, assuming audio.\n"); - } - } - - - if( (st->discard >= AVDISCARD_DEFAULT && size==0) - /*|| (st->discard >= AVDISCARD_NONKEY && !(pkt->flags & AV_PKT_FLAG_KEY))*/ //FIXME needs a little reordering - || st->discard >= AVDISCARD_ALL){ - if (!exit_early) { - ast->frame_offset += get_duration(ast, size); - } - avio_skip(pb, size); - goto start_sync; - } - - if (d[2] == 'p' && d[3] == 'c' && size<=4*256+4) { - int k = avio_r8(pb); - int last = (k + avio_r8(pb) - 1) & 0xFF; - - avio_rl16(pb); //flags - - for (; k <= last; k++) - ast->pal[k] = 0xFFU<<24 | avio_rb32(pb)>>8;// b + (g << 8) + (r << 16); - ast->has_pal= 1; - goto start_sync; - } else if( ((ast->prefix_count<5 || sync+9 > i) && d[2]<128 && d[3]<128) || - d[2]*256+d[3] == ast->prefix /*|| - (d[2] == 'd' && d[3] == 'c') || - (d[2] == 'w' && d[3] == 'b')*/) { - - if (exit_early) - return 0; - if(d[2]*256+d[3] == ast->prefix) - ast->prefix_count++; - else{ - ast->prefix= d[2]*256+d[3]; - ast->prefix_count= 0; - } - - avi->stream_index= n; - ast->packet_size= size + 8; - ast->remaining= size; - - if(size || !ast->sample_size){ - uint64_t pos= avio_tell(pb) - 8; - if(!st->index_entries || !st->nb_index_entries || st->index_entries[st->nb_index_entries - 1].pos < pos){ - av_add_index_entry(st, pos, ast->frame_offset, size, 0, AVINDEX_KEYFRAME); - } - } - return 0; - } - } - } - - if(pb->error) - return pb->error; - return AVERROR_EOF; -} - -static int avi_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - AVIContext *avi = s->priv_data; - AVIOContext *pb = s->pb; - int err; -#if FF_API_DESTRUCT_PACKET - void* dstr; -#endif - - if (CONFIG_DV_DEMUXER && avi->dv_demux) { - int size = avpriv_dv_get_packet(avi->dv_demux, pkt); - if (size >= 0) - return size; - } - - if(avi->non_interleaved){ - int best_stream_index = 0; - AVStream *best_st= NULL; - AVIStream *best_ast; - int64_t best_ts= INT64_MAX; - int i; - - for(i=0; inb_streams; i++){ - AVStream *st = s->streams[i]; - AVIStream *ast = st->priv_data; - int64_t ts= ast->frame_offset; - int64_t last_ts; - - if(!st->nb_index_entries) - continue; - - last_ts = st->index_entries[st->nb_index_entries - 1].timestamp; - if(!ast->remaining && ts > last_ts) - continue; - - ts = av_rescale_q(ts, st->time_base, (AVRational){FFMAX(1, ast->sample_size), AV_TIME_BASE}); - - av_dlog(s, "%"PRId64" %d/%d %"PRId64"\n", ts, - st->time_base.num, st->time_base.den, ast->frame_offset); - if(ts < best_ts){ - best_ts= ts; - best_st= st; - best_stream_index= i; - } - } - if(!best_st) - return AVERROR_EOF; - - best_ast = best_st->priv_data; - best_ts = best_ast->frame_offset; - if(best_ast->remaining) - i= av_index_search_timestamp(best_st, best_ts, AVSEEK_FLAG_ANY | AVSEEK_FLAG_BACKWARD); - else{ - i= av_index_search_timestamp(best_st, best_ts, AVSEEK_FLAG_ANY); - if(i>=0) - best_ast->frame_offset= best_st->index_entries[i].timestamp; - } - - if(i>=0){ - int64_t pos= best_st->index_entries[i].pos; - pos += best_ast->packet_size - best_ast->remaining; - if(avio_seek(s->pb, pos + 8, SEEK_SET) < 0) - return AVERROR_EOF; - - av_assert0(best_ast->remaining <= best_ast->packet_size); - - avi->stream_index= best_stream_index; - if(!best_ast->remaining) - best_ast->packet_size= - best_ast->remaining= best_st->index_entries[i].size; - } - else - return AVERROR_EOF; - } - -resync: - if(avi->stream_index >= 0){ - AVStream *st= s->streams[ avi->stream_index ]; - AVIStream *ast= st->priv_data; - int size, err; - - if(get_subtitle_pkt(s, st, pkt)) - return 0; - - if(ast->sample_size <= 1) // minorityreport.AVI block_align=1024 sample_size=1 IMA-ADPCM - size= INT_MAX; - else if(ast->sample_size < 32) - // arbitrary multiplier to avoid tiny packets for raw PCM data - size= 1024*ast->sample_size; - else - size= ast->sample_size; - - if(size > ast->remaining) - size= ast->remaining; - avi->last_pkt_pos= avio_tell(pb); - err= av_get_packet(pb, pkt, size); - if(err<0) - return err; - size = err; - - if(ast->has_pal && pkt->size<(unsigned)INT_MAX/2){ - uint8_t *pal; - pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE); - if(!pal){ - av_log(s, AV_LOG_ERROR, "Failed to allocate data for palette\n"); - }else{ - memcpy(pal, ast->pal, AVPALETTE_SIZE); - ast->has_pal = 0; - } - } - - if (CONFIG_DV_DEMUXER && avi->dv_demux) { - AVBufferRef *avbuf = pkt->buf; -#if FF_API_DESTRUCT_PACKET - dstr = pkt->destruct; -#endif - size = avpriv_dv_produce_packet(avi->dv_demux, pkt, - pkt->data, pkt->size, pkt->pos); -#if FF_API_DESTRUCT_PACKET - pkt->destruct = dstr; -#endif - pkt->buf = avbuf; - pkt->flags |= AV_PKT_FLAG_KEY; - if (size < 0) - av_free_packet(pkt); - } else if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE - && !st->codec->codec_tag && read_gab2_sub(st, pkt)) { - ast->frame_offset++; - avi->stream_index = -1; - ast->remaining = 0; - goto resync; - } else { - /* XXX: How to handle B-frames in AVI? */ - pkt->dts = ast->frame_offset; -// pkt->dts += ast->start; - if(ast->sample_size) - pkt->dts /= ast->sample_size; - av_dlog(s, "dts:%"PRId64" offset:%"PRId64" %d/%d smpl_siz:%d base:%d st:%d size:%d\n", - pkt->dts, ast->frame_offset, ast->scale, ast->rate, - ast->sample_size, AV_TIME_BASE, avi->stream_index, size); - pkt->stream_index = avi->stream_index; - - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { - AVIndexEntry *e; - int index; - av_assert0(st->index_entries); - - index= av_index_search_timestamp(st, ast->frame_offset, 0); - e= &st->index_entries[index]; - - if(index >= 0 && e->timestamp == ast->frame_offset){ - if (index == st->nb_index_entries-1){ - int key=1; - int i; - uint32_t state=-1; - for(i=0; icodec->codec_id == AV_CODEC_ID_MPEG4){ - if(state == 0x1B6){ - key= !(pkt->data[i]&0xC0); - break; - } - }else - break; - state= (state<<8) + pkt->data[i]; - } - if(!key) - e->flags &= ~AVINDEX_KEYFRAME; - } - if (e->flags & AVINDEX_KEYFRAME) - pkt->flags |= AV_PKT_FLAG_KEY; - } - } else { - pkt->flags |= AV_PKT_FLAG_KEY; - } - ast->frame_offset += get_duration(ast, pkt->size); - } - ast->remaining -= err; - if(!ast->remaining){ - avi->stream_index= -1; - ast->packet_size= 0; - } - - if(!avi->non_interleaved && pkt->pos >= 0 && ast->seek_pos > pkt->pos){ - av_free_packet(pkt); - goto resync; - } - ast->seek_pos= 0; - - if(!avi->non_interleaved && st->nb_index_entries>1 && avi->index_loaded>1){ - int64_t dts= av_rescale_q(pkt->dts, st->time_base, AV_TIME_BASE_Q); - - if(avi->dts_max - dts > 2*AV_TIME_BASE){ - avi->non_interleaved= 1; - av_log(s, AV_LOG_INFO, "Switching to NI mode, due to poor interleaving\n"); - }else if(avi->dts_max < dts) - avi->dts_max = dts; - } - - return 0; - } - - if ((err = avi_sync(s, 0)) < 0) - return err; - goto resync; -} - -/* XXX: We make the implicit supposition that the positions are sorted - for each stream. */ -static int avi_read_idx1(AVFormatContext *s, int size) -{ - AVIContext *avi = s->priv_data; - AVIOContext *pb = s->pb; - int nb_index_entries, i; - AVStream *st; - AVIStream *ast; - unsigned int index, tag, flags, pos, len, first_packet = 1; - unsigned last_pos= -1; - unsigned last_idx= -1; - int64_t idx1_pos, first_packet_pos = 0, data_offset = 0; - int anykey = 0; - - nb_index_entries = size / 16; - if (nb_index_entries <= 0) - return AVERROR_INVALIDDATA; - - idx1_pos = avio_tell(pb); - avio_seek(pb, avi->movi_list+4, SEEK_SET); - if (avi_sync(s, 1) == 0) { - first_packet_pos = avio_tell(pb) - 8; - } - avi->stream_index = -1; - avio_seek(pb, idx1_pos, SEEK_SET); - - if (s->nb_streams == 1 && s->streams[0]->codec->codec_tag == AV_RL32("MMES")){ - first_packet_pos = 0; - data_offset = avi->movi_list; - } - - /* Read the entries and sort them in each stream component. */ - for(i = 0; i < nb_index_entries; i++) { - if(url_feof(pb)) - return -1; - - tag = avio_rl32(pb); - flags = avio_rl32(pb); - pos = avio_rl32(pb); - len = avio_rl32(pb); - av_dlog(s, "%d: tag=0x%x flags=0x%x pos=0x%x len=%d/", - i, tag, flags, pos, len); - - index = ((tag & 0xff) - '0') * 10; - index += ((tag >> 8) & 0xff) - '0'; - if (index >= s->nb_streams) - continue; - st = s->streams[index]; - ast = st->priv_data; - - if(first_packet && first_packet_pos && len) { - data_offset = first_packet_pos - pos; - first_packet = 0; - } - pos += data_offset; - - av_dlog(s, "%d cum_len=%"PRId64"\n", len, ast->cum_len); - - // even if we have only a single stream, we should - // switch to non-interleaved to get correct timestamps - if(last_pos == pos) - avi->non_interleaved= 1; - if(last_idx != pos && len) { - av_add_index_entry(st, pos, ast->cum_len, len, 0, (flags&AVIIF_INDEX) ? AVINDEX_KEYFRAME : 0); - last_idx= pos; - } - ast->cum_len += get_duration(ast, len); - last_pos= pos; - anykey |= flags&AVIIF_INDEX; - } - if (!anykey) { - for (index = 0; index < s->nb_streams; index++) { - st = s->streams[index]; - if (st->nb_index_entries) - st->index_entries[0].flags |= AVINDEX_KEYFRAME; - } - } - return 0; -} - -static int guess_ni_flag(AVFormatContext *s){ - int i; - int64_t last_start=0; - int64_t first_end= INT64_MAX; - int64_t oldpos= avio_tell(s->pb); - int *idx; - int64_t min_pos, pos; - - for(i=0; inb_streams; i++){ - AVStream *st = s->streams[i]; - int n= st->nb_index_entries; - unsigned int size; - - if(n <= 0) - continue; - - if(n >= 2){ - int64_t pos= st->index_entries[0].pos; - avio_seek(s->pb, pos + 4, SEEK_SET); - size= avio_rl32(s->pb); - if(pos + size > st->index_entries[1].pos) - last_start= INT64_MAX; - } - - if(st->index_entries[0].pos > last_start) - last_start= st->index_entries[0].pos; - if(st->index_entries[n-1].pos < first_end) - first_end= st->index_entries[n-1].pos; - } - avio_seek(s->pb, oldpos, SEEK_SET); - if (last_start > first_end) - return 1; - idx= av_mallocz(sizeof(*idx) * s->nb_streams); - for (min_pos=pos=0; min_pos!=INT64_MAX; pos= min_pos+1LU) { - int64_t max_dts = INT64_MIN/2, min_dts= INT64_MAX/2; - min_pos = INT64_MAX; - - for (i=0; inb_streams; i++) { - AVStream *st = s->streams[i]; - int n= st->nb_index_entries; - while (idx[i]index_entries[idx[i]].pos < pos) - idx[i]++; - if (idx[i] < n) { - min_dts = FFMIN(min_dts, av_rescale_q(st->index_entries[idx[i]].timestamp, st->time_base, AV_TIME_BASE_Q)); - min_pos = FFMIN(min_pos, st->index_entries[idx[i]].pos); - } - if (idx[i]) - max_dts = FFMAX(max_dts, av_rescale_q(st->index_entries[idx[i]-1].timestamp, st->time_base, AV_TIME_BASE_Q)); - } - if(max_dts - min_dts > 2*AV_TIME_BASE) { - av_free(idx); - return 1; - } - } - av_free(idx); - return 0; -} - -static int avi_load_index(AVFormatContext *s) -{ - AVIContext *avi = s->priv_data; - AVIOContext *pb = s->pb; - uint32_t tag, size; - int64_t pos= avio_tell(pb); - int64_t next; - int ret = -1; - - if (avio_seek(pb, avi->movi_end, SEEK_SET) < 0) - goto the_end; // maybe truncated file - av_dlog(s, "movi_end=0x%"PRIx64"\n", avi->movi_end); - for(;;) { - tag = avio_rl32(pb); - size = avio_rl32(pb); - if (url_feof(pb)) - break; - next = avio_tell(pb) + size + (size & 1); - - av_dlog(s, "tag=%c%c%c%c size=0x%x\n", - tag & 0xff, - (tag >> 8) & 0xff, - (tag >> 16) & 0xff, - (tag >> 24) & 0xff, - size); - - if (tag == MKTAG('i', 'd', 'x', '1') && - avi_read_idx1(s, size) >= 0) { - avi->index_loaded=2; - ret = 0; - }else if(tag == MKTAG('L', 'I', 'S', 'T')) { - uint32_t tag1 = avio_rl32(pb); - - if (tag1 == MKTAG('I', 'N', 'F', 'O')) - ff_read_riff_info(s, size - 4); - }else if(!ret) - break; - - if (avio_seek(pb, next, SEEK_SET) < 0) - break; // something is wrong here - } - the_end: - avio_seek(pb, pos, SEEK_SET); - return ret; -} - -static void seek_subtitle(AVStream *st, AVStream *st2, int64_t timestamp) -{ - AVIStream *ast2 = st2->priv_data; - int64_t ts2 = av_rescale_q(timestamp, st->time_base, st2->time_base); - av_free_packet(&ast2->sub_pkt); - if (avformat_seek_file(ast2->sub_ctx, 0, INT64_MIN, ts2, ts2, 0) >= 0 || - avformat_seek_file(ast2->sub_ctx, 0, ts2, ts2, INT64_MAX, 0) >= 0) - ff_read_packet(ast2->sub_ctx, &ast2->sub_pkt); -} - -static int avi_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) -{ - AVIContext *avi = s->priv_data; - AVStream *st; - int i, index; - int64_t pos, pos_min; - AVIStream *ast; - - if (!avi->index_loaded) { - /* we only load the index on demand */ - avi_load_index(s); - avi->index_loaded |= 1; - } - av_assert0(stream_index>= 0); - - st = s->streams[stream_index]; - ast= st->priv_data; - index= av_index_search_timestamp(st, timestamp * FFMAX(ast->sample_size, 1), flags); - if (index<0) { - if (st->nb_index_entries > 0) - av_log(s, AV_LOG_DEBUG, "Failed to find timestamp %"PRId64 " in index %"PRId64 " .. %"PRId64 "\n", - timestamp * FFMAX(ast->sample_size, 1), - st->index_entries[0].timestamp, - st->index_entries[st->nb_index_entries - 1].timestamp); - return AVERROR_INVALIDDATA; - } - - /* find the position */ - pos = st->index_entries[index].pos; - timestamp = st->index_entries[index].timestamp / FFMAX(ast->sample_size, 1); - - av_dlog(s, "XX %"PRId64" %d %"PRId64"\n", - timestamp, index, st->index_entries[index].timestamp); - - if (CONFIG_DV_DEMUXER && avi->dv_demux) { - /* One and only one real stream for DV in AVI, and it has video */ - /* offsets. Calling with other stream indexes should have failed */ - /* the av_index_search_timestamp call above. */ - av_assert0(stream_index == 0); - - if(avio_seek(s->pb, pos, SEEK_SET) < 0) - return -1; - - /* Feed the DV video stream version of the timestamp to the */ - /* DV demux so it can synthesize correct timestamps. */ - ff_dv_offset_reset(avi->dv_demux, timestamp); - - avi->stream_index= -1; - return 0; - } - - pos_min= pos; - for(i = 0; i < s->nb_streams; i++) { - AVStream *st2 = s->streams[i]; - AVIStream *ast2 = st2->priv_data; - - ast2->packet_size= - ast2->remaining= 0; - - if (ast2->sub_ctx) { - seek_subtitle(st, st2, timestamp); - continue; - } - - if (st2->nb_index_entries <= 0) - continue; - -// av_assert1(st2->codec->block_align); - av_assert0((int64_t)st2->time_base.num*ast2->rate == (int64_t)st2->time_base.den*ast2->scale); - index = av_index_search_timestamp( - st2, - av_rescale_q(timestamp, st->time_base, st2->time_base) * FFMAX(ast2->sample_size, 1), - flags | AVSEEK_FLAG_BACKWARD | (st2->codec->codec_type != AVMEDIA_TYPE_VIDEO ? AVSEEK_FLAG_ANY : 0)); - if(index<0) - index=0; - ast2->seek_pos= st2->index_entries[index].pos; - pos_min= FFMIN(pos_min,ast2->seek_pos); - } - for(i = 0; i < s->nb_streams; i++) { - AVStream *st2 = s->streams[i]; - AVIStream *ast2 = st2->priv_data; - - if (ast2->sub_ctx || st2->nb_index_entries <= 0) - continue; - - index = av_index_search_timestamp( - st2, - av_rescale_q(timestamp, st->time_base, st2->time_base) * FFMAX(ast2->sample_size, 1), - flags | AVSEEK_FLAG_BACKWARD | (st2->codec->codec_type != AVMEDIA_TYPE_VIDEO ? AVSEEK_FLAG_ANY : 0)); - if(index<0) - index=0; - while(!avi->non_interleaved && index>0 && st2->index_entries[index-1].pos >= pos_min) - index--; - ast2->frame_offset = st2->index_entries[index].timestamp; - } - - /* do the seek */ - if (avio_seek(s->pb, pos_min, SEEK_SET) < 0) { - av_log(s, AV_LOG_ERROR, "Seek failed\n"); - return -1; - } - avi->stream_index= -1; - avi->dts_max= INT_MIN; - return 0; -} - -static int avi_read_close(AVFormatContext *s) -{ - int i; - AVIContext *avi = s->priv_data; - - for(i=0;inb_streams;i++) { - AVStream *st = s->streams[i]; - AVIStream *ast = st->priv_data; - if (ast) { - if (ast->sub_ctx) { - av_freep(&ast->sub_ctx->pb); - avformat_close_input(&ast->sub_ctx); - } - av_free(ast->sub_buffer); - av_free_packet(&ast->sub_pkt); - } - } - - av_free(avi->dv_demux); - - return 0; -} - -static int avi_probe(AVProbeData *p) -{ - int i; - - /* check file header */ - for(i=0; avi_headers[i][0]; i++) - if(!memcmp(p->buf , avi_headers[i] , 4) && - !memcmp(p->buf+8, avi_headers[i]+4, 4)) - return AVPROBE_SCORE_MAX; - - return 0; -} - -AVInputFormat ff_avi_demuxer = { - .name = "avi", - .long_name = NULL_IF_CONFIG_SMALL("AVI (Audio Video Interleaved)"), - .priv_data_size = sizeof(AVIContext), - .read_probe = avi_probe, - .read_header = avi_read_header, - .read_packet = avi_read_packet, - .read_close = avi_read_close, - .read_seek = avi_read_seek, - .priv_class = &demuxer_class, -}; diff --git a/ffmpeg1/libavformat/avienc.c b/ffmpeg1/libavformat/avienc.c deleted file mode 100644 index 15f0794..0000000 --- a/ffmpeg1/libavformat/avienc.c +++ /dev/null @@ -1,663 +0,0 @@ -/* - * AVI 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 - */ - -//#define DEBUG - -#include "avformat.h" -#include "internal.h" -#include "avi.h" -#include "avio_internal.h" -#include "riff.h" -#include "libavutil/intreadwrite.h" -#include "libavutil/dict.h" -#include "libavutil/avassert.h" -#include "libavutil/timestamp.h" - -/* - * TODO: - * - fill all fields if non streamed (nb_frames for example) - */ - -typedef struct AVIIentry { - unsigned int flags, pos, len; -} AVIIentry; - -#define AVI_INDEX_CLUSTER_SIZE 16384 - -typedef struct AVIIndex { - int64_t indx_start; - int entry; - int ents_allocated; - AVIIentry** cluster; -} AVIIndex; - -typedef struct { - int64_t riff_start, movi_list, odml_list; - int64_t frames_hdr_all; - int riff_id; -} AVIContext; - -typedef struct { - int64_t frames_hdr_strm; - int audio_strm_length; - int packet_count; - int entry; - - AVIIndex indexes; -} AVIStream ; - -static inline AVIIentry* avi_get_ientry(AVIIndex* idx, int ent_id) -{ - int cl = ent_id / AVI_INDEX_CLUSTER_SIZE; - int id = ent_id % AVI_INDEX_CLUSTER_SIZE; - return &idx->cluster[cl][id]; -} - -static int64_t avi_start_new_riff(AVFormatContext *s, AVIOContext *pb, - const char* riff_tag, const char* list_tag) -{ - AVIContext *avi= s->priv_data; - int64_t loff; - int i; - - avi->riff_id++; - for (i=0; inb_streams; i++){ - AVIStream *avist= s->streams[i]->priv_data; - avist->indexes.entry = 0; - } - - avi->riff_start = ff_start_tag(pb, "RIFF"); - ffio_wfourcc(pb, riff_tag); - loff = ff_start_tag(pb, "LIST"); - ffio_wfourcc(pb, list_tag); - return loff; -} - -static char* avi_stream2fourcc(char* tag, int index, enum AVMediaType type) -{ - tag[0] = '0' + index/10; - tag[1] = '0' + index%10; - if (type == AVMEDIA_TYPE_VIDEO) { - tag[2] = 'd'; - tag[3] = 'c'; - } else if (type == AVMEDIA_TYPE_SUBTITLE) { - // note: this is not an official code - tag[2] = 's'; - tag[3] = 'b'; - } else { - tag[2] = 'w'; - tag[3] = 'b'; - } - tag[4] = '\0'; - return tag; -} - -static int avi_write_counters(AVFormatContext* s, int riff_id) -{ - AVIOContext *pb = s->pb; - AVIContext *avi = s->priv_data; - int n, au_byterate, au_ssize, au_scale, nb_frames = 0; - int64_t file_size; - AVCodecContext* stream; - - file_size = avio_tell(pb); - for(n = 0; n < s->nb_streams; n++) { - AVIStream *avist= s->streams[n]->priv_data; - - av_assert0(avist->frames_hdr_strm); - stream = s->streams[n]->codec; - avio_seek(pb, avist->frames_hdr_strm, SEEK_SET); - ff_parse_specific_params(stream, &au_byterate, &au_ssize, &au_scale); - if(au_ssize == 0) { - avio_wl32(pb, avist->packet_count); - } else { - avio_wl32(pb, avist->audio_strm_length / au_ssize); - } - if(stream->codec_type == AVMEDIA_TYPE_VIDEO) - nb_frames = FFMAX(nb_frames, avist->packet_count); - } - if(riff_id == 1) { - av_assert0(avi->frames_hdr_all); - avio_seek(pb, avi->frames_hdr_all, SEEK_SET); - avio_wl32(pb, nb_frames); - } - avio_seek(pb, file_size, SEEK_SET); - - return 0; -} - -static int avi_write_header(AVFormatContext *s) -{ - AVIContext *avi = s->priv_data; - AVIOContext *pb = s->pb; - int bitrate, n, i, nb_frames, au_byterate, au_ssize, au_scale; - AVCodecContext *stream, *video_enc; - int64_t list1, list2, strh, strf; - AVDictionaryEntry *t = NULL; - - if (s->nb_streams > AVI_MAX_STREAM_COUNT) { - av_log(s, AV_LOG_ERROR, "AVI does not support >%d streams\n", - AVI_MAX_STREAM_COUNT); - return AVERROR(EINVAL); - } - - for(n=0;nnb_streams;n++) { - s->streams[n]->priv_data= av_mallocz(sizeof(AVIStream)); - if(!s->streams[n]->priv_data) - return AVERROR(ENOMEM); - } - - /* header list */ - avi->riff_id = 0; - list1 = avi_start_new_riff(s, pb, "AVI ", "hdrl"); - - /* avi header */ - ffio_wfourcc(pb, "avih"); - avio_wl32(pb, 14 * 4); - bitrate = 0; - - video_enc = NULL; - for(n=0;nnb_streams;n++) { - stream = s->streams[n]->codec; - bitrate += stream->bit_rate; - if (stream->codec_type == AVMEDIA_TYPE_VIDEO) - video_enc = stream; - } - - nb_frames = 0; - - if(video_enc){ - avio_wl32(pb, (uint32_t)(INT64_C(1000000) * video_enc->time_base.num / video_enc->time_base.den)); - } else { - avio_wl32(pb, 0); - } - avio_wl32(pb, bitrate / 8); /* XXX: not quite exact */ - avio_wl32(pb, 0); /* padding */ - if (!pb->seekable) - avio_wl32(pb, AVIF_TRUSTCKTYPE | AVIF_ISINTERLEAVED); /* flags */ - else - avio_wl32(pb, AVIF_TRUSTCKTYPE | AVIF_HASINDEX | AVIF_ISINTERLEAVED); /* flags */ - avi->frames_hdr_all = avio_tell(pb); /* remember this offset to fill later */ - avio_wl32(pb, nb_frames); /* nb frames, filled later */ - avio_wl32(pb, 0); /* initial frame */ - avio_wl32(pb, s->nb_streams); /* nb streams */ - avio_wl32(pb, 1024 * 1024); /* suggested buffer size */ - if(video_enc){ - avio_wl32(pb, video_enc->width); - avio_wl32(pb, video_enc->height); - } else { - avio_wl32(pb, 0); - avio_wl32(pb, 0); - } - avio_wl32(pb, 0); /* reserved */ - avio_wl32(pb, 0); /* reserved */ - avio_wl32(pb, 0); /* reserved */ - avio_wl32(pb, 0); /* reserved */ - - /* stream list */ - for(i=0;istreams[i]->priv_data; - list2 = ff_start_tag(pb, "LIST"); - ffio_wfourcc(pb, "strl"); - - stream = s->streams[i]->codec; - - /* stream generic header */ - strh = ff_start_tag(pb, "strh"); - switch(stream->codec_type) { - case AVMEDIA_TYPE_SUBTITLE: - // XSUB subtitles behave like video tracks, other subtitles - // are not (yet) supported. - if (stream->codec_id != AV_CODEC_ID_XSUB) { - av_log(s, AV_LOG_ERROR, "Subtitle streams other than DivX XSUB are not supported by the AVI muxer.\n"); - return AVERROR_PATCHWELCOME; - } - case AVMEDIA_TYPE_VIDEO: ffio_wfourcc(pb, "vids"); break; - case AVMEDIA_TYPE_AUDIO: ffio_wfourcc(pb, "auds"); break; -// case AVMEDIA_TYPE_TEXT : ffio_wfourcc(pb, "txts"); break; - case AVMEDIA_TYPE_DATA : ffio_wfourcc(pb, "dats"); break; - } - if(stream->codec_type == AVMEDIA_TYPE_VIDEO || - stream->codec_id == AV_CODEC_ID_XSUB) - avio_wl32(pb, stream->codec_tag); - else - avio_wl32(pb, 1); - avio_wl32(pb, 0); /* flags */ - avio_wl16(pb, 0); /* priority */ - avio_wl16(pb, 0); /* language */ - avio_wl32(pb, 0); /* initial frame */ - - ff_parse_specific_params(stream, &au_byterate, &au_ssize, &au_scale); - - if ( stream->codec_type == AVMEDIA_TYPE_VIDEO - && stream->codec_id != AV_CODEC_ID_XSUB - && au_byterate > 1000LL*au_scale) { - au_byterate = 600; - au_scale = 1; - } - avpriv_set_pts_info(s->streams[i], 64, au_scale, au_byterate); - if(stream->codec_id == AV_CODEC_ID_XSUB) - au_scale = au_byterate = 0; - - avio_wl32(pb, au_scale); /* scale */ - avio_wl32(pb, au_byterate); /* rate */ - - avio_wl32(pb, 0); /* start */ - avist->frames_hdr_strm = avio_tell(pb); /* remember this offset to fill later */ - if (!pb->seekable) - avio_wl32(pb, AVI_MAX_RIFF_SIZE); /* FIXME: this may be broken, but who cares */ - else - avio_wl32(pb, 0); /* length, XXX: filled later */ - - /* suggested buffer size */ //FIXME set at the end to largest chunk - if(stream->codec_type == AVMEDIA_TYPE_VIDEO) - avio_wl32(pb, 1024 * 1024); - else if(stream->codec_type == AVMEDIA_TYPE_AUDIO) - avio_wl32(pb, 12 * 1024); - else - avio_wl32(pb, 0); - avio_wl32(pb, -1); /* quality */ - avio_wl32(pb, au_ssize); /* sample size */ - avio_wl32(pb, 0); - avio_wl16(pb, stream->width); - avio_wl16(pb, stream->height); - ff_end_tag(pb, strh); - - if(stream->codec_type != AVMEDIA_TYPE_DATA){ - int ret; - - strf = ff_start_tag(pb, "strf"); - switch(stream->codec_type) { - case AVMEDIA_TYPE_SUBTITLE: - // XSUB subtitles behave like video tracks, other subtitles - // are not (yet) supported. - if (stream->codec_id != AV_CODEC_ID_XSUB) break; - case AVMEDIA_TYPE_VIDEO: - ff_put_bmp_header(pb, stream, ff_codec_bmp_tags, 0); - break; - case AVMEDIA_TYPE_AUDIO: - if ((ret = ff_put_wav_header(pb, stream)) < 0) { - return ret; - } - break; - default: - av_log(s, AV_LOG_ERROR, - "Invalid or not supported codec type '%s' found in the input\n", - (char *)av_x_if_null(av_get_media_type_string(stream->codec_type), "?")); - return AVERROR(EINVAL); - } - ff_end_tag(pb, strf); - if ((t = av_dict_get(s->streams[i]->metadata, "title", NULL, 0))) { - ff_riff_write_info_tag(s->pb, "strn", t->value); - t = NULL; - } - } - - if (pb->seekable) { - unsigned char tag[5]; - int j; - - /* Starting to lay out AVI OpenDML master index. - * We want to make it JUNK entry for now, since we'd - * like to get away without making AVI an OpenDML one - * for compatibility reasons. - */ - avist->indexes.entry = avist->indexes.ents_allocated = 0; - avist->indexes.indx_start = ff_start_tag(pb, "JUNK"); - avio_wl16(pb, 4); /* wLongsPerEntry */ - avio_w8(pb, 0); /* bIndexSubType (0 == frame index) */ - avio_w8(pb, 0); /* bIndexType (0 == AVI_INDEX_OF_INDEXES) */ - avio_wl32(pb, 0); /* nEntriesInUse (will fill out later on) */ - ffio_wfourcc(pb, avi_stream2fourcc(tag, i, stream->codec_type)); - /* dwChunkId */ - avio_wl64(pb, 0); /* dwReserved[3] - avio_wl32(pb, 0); Must be 0. */ - for (j=0; j < AVI_MASTER_INDEX_SIZE * 2; j++) - avio_wl64(pb, 0); - ff_end_tag(pb, avist->indexes.indx_start); - } - - if( stream->codec_type == AVMEDIA_TYPE_VIDEO - && s->streams[i]->sample_aspect_ratio.num>0 - && s->streams[i]->sample_aspect_ratio.den>0){ - int vprp= ff_start_tag(pb, "vprp"); - AVRational dar = av_mul_q(s->streams[i]->sample_aspect_ratio, - (AVRational){stream->width, stream->height}); - int num, den; - av_reduce(&num, &den, dar.num, dar.den, 0xFFFF); - - avio_wl32(pb, 0); //video format = unknown - avio_wl32(pb, 0); //video standard= unknown - avio_wl32(pb, lrintf(1.0/av_q2d(stream->time_base))); - avio_wl32(pb, stream->width ); - avio_wl32(pb, stream->height); - avio_wl16(pb, den); - avio_wl16(pb, num); - avio_wl32(pb, stream->width ); - avio_wl32(pb, stream->height); - avio_wl32(pb, 1); //progressive FIXME - - avio_wl32(pb, stream->height); - avio_wl32(pb, stream->width ); - avio_wl32(pb, stream->height); - avio_wl32(pb, stream->width ); - avio_wl32(pb, 0); - avio_wl32(pb, 0); - - avio_wl32(pb, 0); - avio_wl32(pb, 0); - ff_end_tag(pb, vprp); - } - - ff_end_tag(pb, list2); - } - - if (pb->seekable) { - /* AVI could become an OpenDML one, if it grows beyond 2Gb range */ - avi->odml_list = ff_start_tag(pb, "JUNK"); - ffio_wfourcc(pb, "odml"); - ffio_wfourcc(pb, "dmlh"); - avio_wl32(pb, 248); - for (i = 0; i < 248; i+= 4) - avio_wl32(pb, 0); - ff_end_tag(pb, avi->odml_list); - } - - ff_end_tag(pb, list1); - - ff_riff_write_info(s); - - /* some padding for easier tag editing */ - list2 = ff_start_tag(pb, "JUNK"); - for (i = 0; i < 1016; i += 4) - avio_wl32(pb, 0); - ff_end_tag(pb, list2); - - avi->movi_list = ff_start_tag(pb, "LIST"); - ffio_wfourcc(pb, "movi"); - - avio_flush(pb); - - return 0; -} - -static int avi_write_ix(AVFormatContext *s) -{ - AVIOContext *pb = s->pb; - AVIContext *avi = s->priv_data; - char tag[5]; - char ix_tag[] = "ix00"; - int i, j; - - av_assert0(pb->seekable); - - if (avi->riff_id > AVI_MASTER_INDEX_SIZE) { - av_log(s, AV_LOG_ERROR, "Invalid riff index %d > %d\n", - avi->riff_id, AVI_MASTER_INDEX_SIZE); - return AVERROR(EINVAL); - } - - for (i=0;inb_streams;i++) { - AVIStream *avist= s->streams[i]->priv_data; - int64_t ix, pos; - - avi_stream2fourcc(tag, i, s->streams[i]->codec->codec_type); - ix_tag[3] = '0' + i; - - /* Writing AVI OpenDML leaf index chunk */ - ix = avio_tell(pb); - ffio_wfourcc(pb, ix_tag); /* ix?? */ - avio_wl32(pb, avist->indexes.entry * 8 + 24); - /* chunk size */ - avio_wl16(pb, 2); /* wLongsPerEntry */ - avio_w8(pb, 0); /* bIndexSubType (0 == frame index) */ - avio_w8(pb, 1); /* bIndexType (1 == AVI_INDEX_OF_CHUNKS) */ - avio_wl32(pb, avist->indexes.entry); - /* nEntriesInUse */ - ffio_wfourcc(pb, tag); /* dwChunkId */ - avio_wl64(pb, avi->movi_list);/* qwBaseOffset */ - avio_wl32(pb, 0); /* dwReserved_3 (must be 0) */ - - for (j=0; jindexes.entry; j++) { - AVIIentry* ie = avi_get_ientry(&avist->indexes, j); - avio_wl32(pb, ie->pos + 8); - avio_wl32(pb, ((uint32_t)ie->len & ~0x80000000) | - (ie->flags & 0x10 ? 0 : 0x80000000)); - } - avio_flush(pb); - pos = avio_tell(pb); - - /* Updating one entry in the AVI OpenDML master index */ - avio_seek(pb, avist->indexes.indx_start - 8, SEEK_SET); - ffio_wfourcc(pb, "indx"); /* enabling this entry */ - avio_skip(pb, 8); - avio_wl32(pb, avi->riff_id); /* nEntriesInUse */ - avio_skip(pb, 16*avi->riff_id); - avio_wl64(pb, ix); /* qwOffset */ - avio_wl32(pb, pos - ix); /* dwSize */ - avio_wl32(pb, avist->indexes.entry); /* dwDuration */ - - avio_seek(pb, pos, SEEK_SET); - } - return 0; -} - -static int avi_write_idx1(AVFormatContext *s) -{ - AVIOContext *pb = s->pb; - AVIContext *avi = s->priv_data; - int64_t idx_chunk; - int i; - char tag[5]; - - if (pb->seekable) { - AVIStream *avist; - AVIIentry* ie = 0, *tie; - int empty, stream_id = -1; - - idx_chunk = ff_start_tag(pb, "idx1"); - for(i=0; inb_streams; i++){ - avist= s->streams[i]->priv_data; - avist->entry=0; - } - - do { - empty = 1; - for (i=0; inb_streams; i++) { - avist= s->streams[i]->priv_data; - if (avist->indexes.entry <= avist->entry) - continue; - - tie = avi_get_ientry(&avist->indexes, avist->entry); - if (empty || tie->pos < ie->pos) { - ie = tie; - stream_id = i; - } - empty = 0; - } - if (!empty) { - avist= s->streams[stream_id]->priv_data; - avi_stream2fourcc(tag, stream_id, - s->streams[stream_id]->codec->codec_type); - ffio_wfourcc(pb, tag); - avio_wl32(pb, ie->flags); - avio_wl32(pb, ie->pos); - avio_wl32(pb, ie->len); - avist->entry++; - } - } while (!empty); - ff_end_tag(pb, idx_chunk); - - avi_write_counters(s, avi->riff_id); - } - return 0; -} - -static int avi_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - AVIContext *avi = s->priv_data; - AVIOContext *pb = s->pb; - unsigned char tag[5]; - unsigned int flags=0; - const int stream_index= pkt->stream_index; - AVIStream *avist= s->streams[stream_index]->priv_data; - AVCodecContext *enc= s->streams[stream_index]->codec; - int size= pkt->size; - - av_dlog(s, "dts:%s packet_count:%d stream_index:%d\n", av_ts2str(pkt->dts), avist->packet_count, stream_index); - while(enc->block_align==0 && pkt->dts != AV_NOPTS_VALUE && pkt->dts > avist->packet_count && enc->codec_id != AV_CODEC_ID_XSUB){ - AVPacket empty_packet; - - if(pkt->dts - avist->packet_count > 60000){ - av_log(s, AV_LOG_ERROR, "Too large number of skipped frames %"PRId64" > 60000\n", pkt->dts - avist->packet_count); - return AVERROR(EINVAL); - } - - 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_dlog(s, "dup dts:%s packet_count:%d\n", av_ts2str(pkt->dts), avist->packet_count); - } - avist->packet_count++; - - // Make sure to put an OpenDML chunk when the file size exceeds the limits - if (pb->seekable && - (avio_tell(pb) - avi->riff_start > AVI_MAX_RIFF_SIZE)) { - - avi_write_ix(s); - ff_end_tag(pb, avi->movi_list); - - if (avi->riff_id == 1) - avi_write_idx1(s); - - ff_end_tag(pb, avi->riff_start); - avi->movi_list = avi_start_new_riff(s, pb, "AVIX", "movi"); - } - - avi_stream2fourcc(tag, stream_index, enc->codec_type); - if(pkt->flags&AV_PKT_FLAG_KEY) - flags = 0x10; - if (enc->codec_type == AVMEDIA_TYPE_AUDIO) { - avist->audio_strm_length += size; - } - - if (s->pb->seekable) { - AVIIndex* idx = &avist->indexes; - int cl = idx->entry / AVI_INDEX_CLUSTER_SIZE; - int id = idx->entry % AVI_INDEX_CLUSTER_SIZE; - if (idx->ents_allocated <= idx->entry) { - idx->cluster = av_realloc_f(idx->cluster, sizeof(void*), cl+1); - if (!idx->cluster) - return AVERROR(ENOMEM); - idx->cluster[cl] = av_malloc(AVI_INDEX_CLUSTER_SIZE*sizeof(AVIIentry)); - if (!idx->cluster[cl]) - return AVERROR(ENOMEM); - idx->ents_allocated += AVI_INDEX_CLUSTER_SIZE; - } - - idx->cluster[cl][id].flags = flags; - idx->cluster[cl][id].pos = avio_tell(pb) - avi->movi_list; - idx->cluster[cl][id].len = size; - idx->entry++; - } - - avio_write(pb, tag, 4); - avio_wl32(pb, size); - avio_write(pb, pkt->data, size); - if (size & 1) - avio_w8(pb, 0); - - avio_flush(pb); - return 0; -} - -static int avi_write_trailer(AVFormatContext *s) -{ - AVIContext *avi = s->priv_data; - AVIOContext *pb = s->pb; - int res = 0; - int i, j, n, nb_frames; - int64_t file_size; - - if (pb->seekable){ - if (avi->riff_id == 1) { - ff_end_tag(pb, avi->movi_list); - res = avi_write_idx1(s); - ff_end_tag(pb, avi->riff_start); - } else { - avi_write_ix(s); - ff_end_tag(pb, avi->movi_list); - ff_end_tag(pb, avi->riff_start); - - file_size = avio_tell(pb); - avio_seek(pb, avi->odml_list - 8, SEEK_SET); - ffio_wfourcc(pb, "LIST"); /* Making this AVI OpenDML one */ - avio_skip(pb, 16); - - for (n=nb_frames=0;nnb_streams;n++) { - AVCodecContext *stream = s->streams[n]->codec; - AVIStream *avist= s->streams[n]->priv_data; - - if (stream->codec_type == AVMEDIA_TYPE_VIDEO) { - if (nb_frames < avist->packet_count) - nb_frames = avist->packet_count; - } else { - if (stream->codec_id == AV_CODEC_ID_MP2 || stream->codec_id == AV_CODEC_ID_MP3) { - nb_frames += avist->packet_count; - } - } - } - avio_wl32(pb, nb_frames); - avio_seek(pb, file_size, SEEK_SET); - - avi_write_counters(s, avi->riff_id); - } - } - - for (i=0; inb_streams; i++) { - AVIStream *avist= s->streams[i]->priv_data; - for (j=0; jindexes.ents_allocated/AVI_INDEX_CLUSTER_SIZE; j++) - av_free(avist->indexes.cluster[j]); - av_freep(&avist->indexes.cluster); - avist->indexes.ents_allocated = avist->indexes.entry = 0; - } - - return res; -} - -AVOutputFormat ff_avi_muxer = { - .name = "avi", - .long_name = NULL_IF_CONFIG_SMALL("AVI (Audio Video Interleaved)"), - .mime_type = "video/x-msvideo", - .extensions = "avi", - .priv_data_size = sizeof(AVIContext), - .audio_codec = CONFIG_LIBMP3LAME ? AV_CODEC_ID_MP3 : AV_CODEC_ID_AC3, - .video_codec = AV_CODEC_ID_MPEG4, - .write_header = avi_write_header, - .write_packet = avi_write_packet, - .write_trailer = avi_write_trailer, - .codec_tag = (const AVCodecTag* const []){ - ff_codec_bmp_tags, ff_codec_wav_tags, 0 - }, - .flags = AVFMT_VARIABLE_FPS, -}; diff --git a/ffmpeg1/libavformat/avio.c b/ffmpeg1/libavformat/avio.c deleted file mode 100644 index f6af0cb..0000000 --- a/ffmpeg1/libavformat/avio.c +++ /dev/null @@ -1,434 +0,0 @@ -/* - * unbuffered I/O - * 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 - */ - -#include "libavutil/avstring.h" -#include "libavutil/dict.h" -#include "libavutil/opt.h" -#include "libavutil/time.h" -#include "os_support.h" -#include "avformat.h" -#if CONFIG_NETWORK -#include "network.h" -#endif -#include "url.h" - -static URLProtocol *first_protocol = NULL; - -URLProtocol *ffurl_protocol_next(URLProtocol *prev) -{ - return prev ? prev->next : first_protocol; -} - -/** @name Logging context. */ -/*@{*/ -static const char *urlcontext_to_name(void *ptr) -{ - URLContext *h = (URLContext *)ptr; - if(h->prot) return h->prot->name; - else return "NULL"; -} - -static void *urlcontext_child_next(void *obj, void *prev) -{ - URLContext *h = obj; - if (!prev && h->priv_data && h->prot->priv_data_class) - return h->priv_data; - return NULL; -} - -static const AVClass *urlcontext_child_class_next(const AVClass *prev) -{ - URLProtocol *p = NULL; - - /* find the protocol that corresponds to prev */ - while (prev && (p = ffurl_protocol_next(p))) - if (p->priv_data_class == prev) - break; - - /* find next protocol with priv options */ - while (p = ffurl_protocol_next(p)) - if (p->priv_data_class) - return p->priv_data_class; - return NULL; - -} - -static const AVOption options[] = {{NULL}}; -const AVClass ffurl_context_class = { - .class_name = "URLContext", - .item_name = urlcontext_to_name, - .option = options, - .version = LIBAVUTIL_VERSION_INT, - .child_next = urlcontext_child_next, - .child_class_next = urlcontext_child_class_next, -}; -/*@}*/ - - -const char *avio_enum_protocols(void **opaque, int output) -{ - URLProtocol *p; - *opaque = ffurl_protocol_next(*opaque); - if (!(p = *opaque)) return NULL; - if ((output && p->url_write) || (!output && p->url_read)) - return p->name; - return avio_enum_protocols(opaque, output); -} - -int ffurl_register_protocol(URLProtocol *protocol, int size) -{ - URLProtocol **p; - if (size < sizeof(URLProtocol)) { - URLProtocol* temp = av_mallocz(sizeof(URLProtocol)); - memcpy(temp, protocol, size); - protocol = temp; - } - p = &first_protocol; - while (*p != NULL) p = &(*p)->next; - *p = protocol; - protocol->next = NULL; - return 0; -} - -static int url_alloc_for_protocol (URLContext **puc, struct URLProtocol *up, - const char *filename, int flags, - const AVIOInterruptCB *int_cb) -{ - URLContext *uc; - int err; - -#if CONFIG_NETWORK - if (up->flags & URL_PROTOCOL_FLAG_NETWORK && !ff_network_init()) - return AVERROR(EIO); -#endif - if ((flags & AVIO_FLAG_READ) && !up->url_read) { - av_log(NULL, AV_LOG_ERROR, - "Impossible to open the '%s' protocol for reading\n", up->name); - return AVERROR(EIO); - } - if ((flags & AVIO_FLAG_WRITE) && !up->url_write) { - av_log(NULL, AV_LOG_ERROR, - "Impossible to open the '%s' protocol for writing\n", up->name); - return AVERROR(EIO); - } - uc = av_mallocz(sizeof(URLContext) + strlen(filename) + 1); - if (!uc) { - err = AVERROR(ENOMEM); - goto fail; - } - uc->av_class = &ffurl_context_class; - uc->filename = (char *) &uc[1]; - strcpy(uc->filename, filename); - uc->prot = up; - uc->flags = flags; - uc->is_streamed = 0; /* default = not streamed */ - uc->max_packet_size = 0; /* default: stream file */ - if (up->priv_data_size) { - uc->priv_data = av_mallocz(up->priv_data_size); - if (up->priv_data_class) { - int proto_len= strlen(up->name); - char *start = strchr(uc->filename, ','); - *(const AVClass**)uc->priv_data = up->priv_data_class; - av_opt_set_defaults(uc->priv_data); - if(!strncmp(up->name, uc->filename, proto_len) && uc->filename + proto_len == start){ - int ret= 0; - char *p= start; - char sep= *++p; - char *key, *val; - p++; - while(ret >= 0 && (key= strchr(p, sep)) && ppriv_data, p, key+1, 0); - if (ret == AVERROR_OPTION_NOT_FOUND) - av_log(uc, AV_LOG_ERROR, "Key '%s' not found.\n", p); - *val= *key= sep; - p= val+1; - } - if(ret<0 || p!=key){ - av_log(uc, AV_LOG_ERROR, "Error parsing options string %s\n", start); - av_freep(&uc->priv_data); - av_freep(&uc); - err = AVERROR(EINVAL); - goto fail; - } - memmove(start, key+1, strlen(key)); - } - } - } - if (int_cb) - uc->interrupt_callback = *int_cb; - - *puc = uc; - return 0; - fail: - *puc = NULL; -#if CONFIG_NETWORK - if (up->flags & URL_PROTOCOL_FLAG_NETWORK) - ff_network_close(); -#endif - return err; -} - -int ffurl_connect(URLContext* uc, AVDictionary **options) -{ - int err = - uc->prot->url_open2 ? uc->prot->url_open2(uc, uc->filename, uc->flags, options) : - uc->prot->url_open(uc, uc->filename, uc->flags); - if (err) - return err; - uc->is_connected = 1; - //We must be careful here as ffurl_seek() could be slow, for example for http - if( (uc->flags & AVIO_FLAG_WRITE) - || !strcmp(uc->prot->name, "file")) - if(!uc->is_streamed && ffurl_seek(uc, 0, SEEK_SET) < 0) - uc->is_streamed= 1; - return 0; -} - -#define URL_SCHEME_CHARS \ - "abcdefghijklmnopqrstuvwxyz" \ - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \ - "0123456789+-." - -int ffurl_alloc(URLContext **puc, const char *filename, int flags, - const AVIOInterruptCB *int_cb) -{ - URLProtocol *up = NULL; - char proto_str[128], proto_nested[128], *ptr; - size_t proto_len = strspn(filename, URL_SCHEME_CHARS); - - if (!first_protocol) { - av_log(NULL, AV_LOG_WARNING, "No URL Protocols are registered. " - "Missing call to av_register_all()?\n"); - } - - if (filename[proto_len] != ':' && - (filename[proto_len] != ',' || !strchr(filename + proto_len + 1, ':')) || - is_dos_path(filename)) - strcpy(proto_str, "file"); - else - av_strlcpy(proto_str, filename, FFMIN(proto_len+1, sizeof(proto_str))); - - if ((ptr = strchr(proto_str, ','))) - *ptr = '\0'; - av_strlcpy(proto_nested, proto_str, sizeof(proto_nested)); - if ((ptr = strchr(proto_nested, '+'))) - *ptr = '\0'; - - while (up = ffurl_protocol_next(up)) { - if (!strcmp(proto_str, up->name)) - return url_alloc_for_protocol (puc, up, filename, flags, int_cb); - if (up->flags & URL_PROTOCOL_FLAG_NESTED_SCHEME && - !strcmp(proto_nested, up->name)) - return url_alloc_for_protocol (puc, up, filename, flags, int_cb); - } - *puc = NULL; - return AVERROR_PROTOCOL_NOT_FOUND; -} - -int ffurl_open(URLContext **puc, const char *filename, int flags, - const AVIOInterruptCB *int_cb, AVDictionary **options) -{ - int ret = ffurl_alloc(puc, filename, flags, int_cb); - if (ret) - return ret; - if (options && (*puc)->prot->priv_data_class && - (ret = av_opt_set_dict((*puc)->priv_data, options)) < 0) - goto fail; - ret = ffurl_connect(*puc, options); - if (!ret) - return 0; -fail: - ffurl_close(*puc); - *puc = NULL; - return ret; -} - -static inline int retry_transfer_wrapper(URLContext *h, unsigned char *buf, int size, int size_min, - int (*transfer_func)(URLContext *h, unsigned char *buf, int size)) -{ - int ret, len; - int fast_retries = 5; - int64_t wait_since = 0; - - len = 0; - while (len < size_min) { - ret = transfer_func(h, buf+len, size-len); - if (ret == AVERROR(EINTR)) - continue; - if (h->flags & AVIO_FLAG_NONBLOCK) - return ret; - if (ret == AVERROR(EAGAIN)) { - ret = 0; - if (fast_retries) { - fast_retries--; - } else { - if (h->rw_timeout) { - if (!wait_since) - wait_since = av_gettime(); - else if (av_gettime() > wait_since + h->rw_timeout) - return AVERROR(EIO); - } - av_usleep(1000); - } - } else if (ret < 1) - return ret < 0 ? ret : len; - if (ret) - fast_retries = FFMAX(fast_retries, 2); - len += ret; - if (len < size && ff_check_interrupt(&h->interrupt_callback)) - return AVERROR_EXIT; - } - return len; -} - -int ffurl_read(URLContext *h, unsigned char *buf, int size) -{ - if (!(h->flags & AVIO_FLAG_READ)) - return AVERROR(EIO); - return retry_transfer_wrapper(h, buf, size, 1, h->prot->url_read); -} - -int ffurl_read_complete(URLContext *h, unsigned char *buf, int size) -{ - if (!(h->flags & AVIO_FLAG_READ)) - return AVERROR(EIO); - return retry_transfer_wrapper(h, buf, size, size, h->prot->url_read); -} - -int ffurl_write(URLContext *h, const unsigned char *buf, int size) -{ - if (!(h->flags & AVIO_FLAG_WRITE)) - return AVERROR(EIO); - /* avoid sending too big packets */ - if (h->max_packet_size && size > h->max_packet_size) - return AVERROR(EIO); - - return retry_transfer_wrapper(h, (unsigned char *)buf, size, size, (void*)h->prot->url_write); -} - -int64_t ffurl_seek(URLContext *h, int64_t pos, int whence) -{ - int64_t ret; - - if (!h->prot->url_seek) - return AVERROR(ENOSYS); - ret = h->prot->url_seek(h, pos, whence & ~AVSEEK_FORCE); - return ret; -} - -int ffurl_closep(URLContext **hh) -{ - URLContext *h= *hh; - int ret = 0; - if (!h) return 0; /* can happen when ffurl_open fails */ - - if (h->is_connected && h->prot->url_close) - ret = h->prot->url_close(h); -#if CONFIG_NETWORK - if (h->prot->flags & URL_PROTOCOL_FLAG_NETWORK) - ff_network_close(); -#endif - if (h->prot->priv_data_size) { - if (h->prot->priv_data_class) - av_opt_free(h->priv_data); - av_freep(&h->priv_data); - } - av_freep(hh); - return ret; -} - -int ffurl_close(URLContext *h) -{ - return ffurl_closep(&h); -} - - -int avio_check(const char *url, int flags) -{ - URLContext *h; - int ret = ffurl_alloc(&h, url, flags, NULL); - if (ret) - return ret; - - if (h->prot->url_check) { - ret = h->prot->url_check(h, flags); - } else { - ret = ffurl_connect(h, NULL); - if (ret >= 0) - ret = flags; - } - - ffurl_close(h); - return ret; -} - -int64_t ffurl_size(URLContext *h) -{ - int64_t pos, size; - - size= ffurl_seek(h, 0, AVSEEK_SIZE); - if(size<0){ - pos = ffurl_seek(h, 0, SEEK_CUR); - if ((size = ffurl_seek(h, -1, SEEK_END)) < 0) - return size; - size++; - ffurl_seek(h, pos, SEEK_SET); - } - return size; -} - -int ffurl_get_file_handle(URLContext *h) -{ - if (!h->prot->url_get_file_handle) - return -1; - return h->prot->url_get_file_handle(h); -} - -int ffurl_get_multi_file_handle(URLContext *h, int **handles, int *numhandles) -{ - if (!h->prot->url_get_multi_file_handle) { - if (!h->prot->url_get_file_handle) - return AVERROR(ENOSYS); - *handles = av_malloc(sizeof(**handles)); - if (!*handles) - return AVERROR(ENOMEM); - *numhandles = 1; - *handles[0] = h->prot->url_get_file_handle(h); - return 0; - } - return h->prot->url_get_multi_file_handle(h, handles, numhandles); -} - -int ffurl_shutdown(URLContext *h, int flags) -{ - if (!h->prot->url_shutdown) - return AVERROR(EINVAL); - return h->prot->url_shutdown(h, flags); -} - -int ff_check_interrupt(AVIOInterruptCB *cb) -{ - int ret; - if (cb && cb->callback && (ret = cb->callback(cb->opaque))) - return ret; - return 0; -} diff --git a/ffmpeg1/libavformat/avio.h b/ffmpeg1/libavformat/avio.h deleted file mode 100644 index 8de28bf..0000000 --- a/ffmpeg1/libavformat/avio.h +++ /dev/null @@ -1,475 +0,0 @@ -/* - * 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 AVFORMAT_AVIO_H -#define AVFORMAT_AVIO_H - -/** - * @file - * @ingroup lavf_io - * Buffered I/O operations - */ - -#include - -#include "libavutil/common.h" -#include "libavutil/dict.h" -#include "libavutil/log.h" - -#include "libavformat/version.h" - - -#define AVIO_SEEKABLE_NORMAL 0x0001 /**< Seeking works like for a local file */ - -/** - * Callback for checking whether to abort blocking functions. - * AVERROR_EXIT is returned in this case by the interrupted - * function. During blocking operations, callback is called with - * opaque as parameter. If the callback returns 1, the - * blocking operation will be aborted. - * - * No members can be added to this struct without a major bump, if - * new elements have been added after this struct in AVFormatContext - * or AVIOContext. - */ -typedef struct AVIOInterruptCB { - int (*callback)(void*); - void *opaque; -} AVIOInterruptCB; - -/** - * Bytestream IO Context. - * New fields can be added to the end with minor version bumps. - * Removal, reordering and changes to existing fields require a major - * version bump. - * sizeof(AVIOContext) must not be used outside libav*. - * - * @note None of the function pointers in AVIOContext should be called - * directly, they should only be set by the client application - * when implementing custom I/O. Normally these are set to the - * function pointers specified in avio_alloc_context() - */ -typedef struct AVIOContext { - /** - * A class for private options. - * - * If this AVIOContext is created by avio_open2(), av_class is set and - * passes the options down to protocols. - * - * If this AVIOContext is manually allocated, then av_class may be set by - * the caller. - * - * warning -- this field can be NULL, be sure to not pass this AVIOContext - * to any av_opt_* functions in that case. - */ - const AVClass *av_class; - unsigned char *buffer; /**< Start of the buffer. */ - int buffer_size; /**< Maximum buffer size */ - unsigned char *buf_ptr; /**< Current position in the buffer */ - unsigned char *buf_end; /**< End of the data, may be less than - buffer+buffer_size if the read function returned - less data than requested, e.g. for streams where - no more data has been received yet. */ - void *opaque; /**< A private pointer, passed to the read/write/seek/... - functions. */ - int (*read_packet)(void *opaque, uint8_t *buf, int buf_size); - int (*write_packet)(void *opaque, uint8_t *buf, int buf_size); - int64_t (*seek)(void *opaque, int64_t offset, int whence); - int64_t pos; /**< position in the file of the current buffer */ - int must_flush; /**< true if the next seek should flush */ - int eof_reached; /**< true if eof reached */ - int write_flag; /**< true if open for writing */ - int max_packet_size; - unsigned long checksum; - unsigned char *checksum_ptr; - unsigned long (*update_checksum)(unsigned long checksum, const uint8_t *buf, unsigned int size); - int error; /**< contains the error code or 0 if no error happened */ - /** - * Pause or resume playback for network streaming protocols - e.g. MMS. - */ - int (*read_pause)(void *opaque, int pause); - /** - * Seek to a given timestamp in stream with the specified stream_index. - * Needed for some network streaming protocols which don't support seeking - * to byte position. - */ - int64_t (*read_seek)(void *opaque, int stream_index, - int64_t timestamp, int flags); - /** - * A combination of AVIO_SEEKABLE_ flags or 0 when the stream is not seekable. - */ - int seekable; - - /** - * max filesize, used to limit allocations - * This field is internal to libavformat and access from outside is not allowed. - */ - int64_t maxsize; - - /** - * avio_read and avio_write should if possible be satisfied directly - * instead of going through a buffer, and avio_seek will always - * call the underlying seek function directly. - */ - int direct; - - /** - * Bytes read statistic - * This field is internal to libavformat and access from outside is not allowed. - */ - int64_t bytes_read; - - /** - * seek statistic - * This field is internal to libavformat and access from outside is not allowed. - */ - int seek_count; -} AVIOContext; - -/* unbuffered I/O */ - -/** - * Return AVIO_FLAG_* access flags corresponding to the access permissions - * of the resource in url, or a negative value corresponding to an - * AVERROR code in case of failure. The returned access flags are - * masked by the value in flags. - * - * @note This function is intrinsically unsafe, in the sense that the - * checked resource may change its existence or permission status from - * one call to another. Thus you should not trust the returned value, - * unless you are sure that no other processes are accessing the - * checked resource. - */ -int avio_check(const char *url, int flags); - -/** - * Allocate and initialize an AVIOContext for buffered I/O. It must be later - * freed with av_free(). - * - * @param buffer Memory block for input/output operations via AVIOContext. - * The buffer must be allocated with av_malloc() and friends. - * @param buffer_size The buffer size is very important for performance. - * For protocols with fixed blocksize it should be set to this blocksize. - * For others a typical size is a cache page, e.g. 4kb. - * @param write_flag Set to 1 if the buffer should be writable, 0 otherwise. - * @param opaque An opaque pointer to user-specific data. - * @param read_packet A function for refilling the buffer, may be NULL. - * @param write_packet A function for writing the buffer contents, may be NULL. - * The function may not change the input buffers content. - * @param seek A function for seeking to specified byte position, may be NULL. - * - * @return Allocated AVIOContext or NULL on failure. - */ -AVIOContext *avio_alloc_context( - unsigned char *buffer, - int buffer_size, - int write_flag, - void *opaque, - int (*read_packet)(void *opaque, uint8_t *buf, int buf_size), - int (*write_packet)(void *opaque, uint8_t *buf, int buf_size), - int64_t (*seek)(void *opaque, int64_t offset, int whence)); - -void avio_w8(AVIOContext *s, int b); -void avio_write(AVIOContext *s, const unsigned char *buf, int size); -void avio_wl64(AVIOContext *s, uint64_t val); -void avio_wb64(AVIOContext *s, uint64_t val); -void avio_wl32(AVIOContext *s, unsigned int val); -void avio_wb32(AVIOContext *s, unsigned int val); -void avio_wl24(AVIOContext *s, unsigned int val); -void avio_wb24(AVIOContext *s, unsigned int val); -void avio_wl16(AVIOContext *s, unsigned int val); -void avio_wb16(AVIOContext *s, unsigned int val); - -/** - * Write a NULL-terminated string. - * @return number of bytes written. - */ -int avio_put_str(AVIOContext *s, const char *str); - -/** - * Convert an UTF-8 string to UTF-16LE and write it. - * @return number of bytes written. - */ -int avio_put_str16le(AVIOContext *s, const char *str); - -/** - * Passing this as the "whence" parameter to a seek function causes it to - * return the filesize without seeking anywhere. Supporting this is optional. - * If it is not supported then the seek function will return <0. - */ -#define AVSEEK_SIZE 0x10000 - -/** - * Oring this flag as into the "whence" parameter to a seek function causes it to - * seek by any means (like reopening and linear reading) or other normally unreasonable - * means that can be extremely slow. - * This may be ignored by the seek code. - */ -#define AVSEEK_FORCE 0x20000 - -/** - * fseek() equivalent for AVIOContext. - * @return new position or AVERROR. - */ -int64_t avio_seek(AVIOContext *s, int64_t offset, int whence); - -/** - * Skip given number of bytes forward - * @return new position or AVERROR. - */ -int64_t avio_skip(AVIOContext *s, int64_t offset); - -/** - * ftell() equivalent for AVIOContext. - * @return position or AVERROR. - */ -static av_always_inline int64_t avio_tell(AVIOContext *s) -{ - return avio_seek(s, 0, SEEK_CUR); -} - -/** - * Get the filesize. - * @return filesize or AVERROR - */ -int64_t avio_size(AVIOContext *s); - -/** - * feof() equivalent for AVIOContext. - * @return non zero if and only if end of file - */ -int url_feof(AVIOContext *s); - -/** @warning currently size is limited */ -int avio_printf(AVIOContext *s, const char *fmt, ...) av_printf_format(2, 3); - -/** - * Force flushing of buffered data to the output s. - * - * Force the buffered data to be immediately written to the output, - * without to wait to fill the internal buffer. - */ -void avio_flush(AVIOContext *s); - -/** - * Read size bytes from AVIOContext into buf. - * @return number of bytes read or AVERROR - */ -int avio_read(AVIOContext *s, unsigned char *buf, int size); - -/** - * @name Functions for reading from AVIOContext - * @{ - * - * @note return 0 if EOF, so you cannot use it if EOF handling is - * necessary - */ -int avio_r8 (AVIOContext *s); -unsigned int avio_rl16(AVIOContext *s); -unsigned int avio_rl24(AVIOContext *s); -unsigned int avio_rl32(AVIOContext *s); -uint64_t avio_rl64(AVIOContext *s); -unsigned int avio_rb16(AVIOContext *s); -unsigned int avio_rb24(AVIOContext *s); -unsigned int avio_rb32(AVIOContext *s); -uint64_t avio_rb64(AVIOContext *s); -/** - * @} - */ - -/** - * Read a string from pb into buf. The reading will terminate when either - * a NULL character was encountered, maxlen bytes have been read, or nothing - * more can be read from pb. The result is guaranteed to be NULL-terminated, it - * will be truncated if buf is too small. - * Note that the string is not interpreted or validated in any way, it - * might get truncated in the middle of a sequence for multi-byte encodings. - * - * @return number of bytes read (is always <= maxlen). - * If reading ends on EOF or error, the return value will be one more than - * bytes actually read. - */ -int avio_get_str(AVIOContext *pb, int maxlen, char *buf, int buflen); - -/** - * Read a UTF-16 string from pb and convert it to UTF-8. - * The reading will terminate when either a null or invalid character was - * encountered or maxlen bytes have been read. - * @return number of bytes read (is always <= maxlen) - */ -int avio_get_str16le(AVIOContext *pb, int maxlen, char *buf, int buflen); -int avio_get_str16be(AVIOContext *pb, int maxlen, char *buf, int buflen); - - -/** - * @name URL open modes - * The flags argument to avio_open must be one of the following - * constants, optionally ORed with other flags. - * @{ - */ -#define AVIO_FLAG_READ 1 /**< read-only */ -#define AVIO_FLAG_WRITE 2 /**< write-only */ -#define AVIO_FLAG_READ_WRITE (AVIO_FLAG_READ|AVIO_FLAG_WRITE) /**< read-write pseudo flag */ -/** - * @} - */ - -/** - * Use non-blocking mode. - * If this flag is set, operations on the context will return - * AVERROR(EAGAIN) if they can not be performed immediately. - * If this flag is not set, operations on the context will never return - * AVERROR(EAGAIN). - * Note that this flag does not affect the opening/connecting of the - * context. Connecting a protocol will always block if necessary (e.g. on - * network protocols) but never hang (e.g. on busy devices). - * Warning: non-blocking protocols is work-in-progress; this flag may be - * silently ignored. - */ -#define AVIO_FLAG_NONBLOCK 8 - -/** - * Use direct mode. - * avio_read and avio_write should if possible be satisfied directly - * instead of going through a buffer, and avio_seek will always - * call the underlying seek function directly. - */ -#define AVIO_FLAG_DIRECT 0x8000 - -/** - * Create and initialize a AVIOContext for accessing the - * resource indicated by url. - * @note When the resource indicated by url has been opened in - * read+write mode, the AVIOContext can be used only for writing. - * - * @param s Used to return the pointer to the created AVIOContext. - * In case of failure the pointed to value is set to NULL. - * @param flags flags which control how the resource indicated by url - * is to be opened - * @return 0 in case of success, a negative value corresponding to an - * AVERROR code in case of failure - */ -int avio_open(AVIOContext **s, const char *url, int flags); - -/** - * Create and initialize a AVIOContext for accessing the - * resource indicated by url. - * @note When the resource indicated by url has been opened in - * read+write mode, the AVIOContext can be used only for writing. - * - * @param s Used to return the pointer to the created AVIOContext. - * In case of failure the pointed to value is set to NULL. - * @param flags flags which control how the resource indicated by url - * is to be opened - * @param int_cb an interrupt callback to be used at the protocols level - * @param options A dictionary filled with protocol-private options. On return - * this parameter will be destroyed and replaced with a dict containing options - * that were not found. May be NULL. - * @return 0 in case of success, a negative value corresponding to an - * AVERROR code in case of failure - */ -int avio_open2(AVIOContext **s, const char *url, int flags, - const AVIOInterruptCB *int_cb, AVDictionary **options); - -/** - * Close the resource accessed by the AVIOContext s and free it. - * This function can only be used if s was opened by avio_open(). - * - * The internal buffer is automatically flushed before closing the - * resource. - * - * @return 0 on success, an AVERROR < 0 on error. - * @see avio_closep - */ -int avio_close(AVIOContext *s); - -/** - * Close the resource accessed by the AVIOContext *s, free it - * and set the pointer pointing to it to NULL. - * This function can only be used if s was opened by avio_open(). - * - * The internal buffer is automatically flushed before closing the - * resource. - * - * @return 0 on success, an AVERROR < 0 on error. - * @see avio_close - */ -int avio_closep(AVIOContext **s); - - -/** - * Open a write only memory stream. - * - * @param s new IO context - * @return zero if no error. - */ -int avio_open_dyn_buf(AVIOContext **s); - -/** - * Return the written size and a pointer to the buffer. The buffer - * must be freed with av_free(). - * Padding of FF_INPUT_BUFFER_PADDING_SIZE is added to the buffer. - * - * @param s IO context - * @param pbuffer pointer to a byte buffer - * @return the length of the byte buffer - */ -int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer); - -/** - * Iterate through names of available protocols. - * - * @param opaque A private pointer representing current protocol. - * It must be a pointer to NULL on first iteration and will - * be updated by successive calls to avio_enum_protocols. - * @param output If set to 1, iterate over output protocols, - * otherwise over input protocols. - * - * @return A static string containing the name of current protocol or NULL - */ -const char *avio_enum_protocols(void **opaque, int output); - -/** - * Pause and resume playing - only meaningful if using a network streaming - * protocol (e.g. MMS). - * @param pause 1 for pause, 0 for resume - */ -int avio_pause(AVIOContext *h, int pause); - -/** - * Seek to a given timestamp relative to some component stream. - * Only meaningful if using a network streaming protocol (e.g. MMS.). - * @param stream_index The stream index that the timestamp is relative to. - * If stream_index is (-1) the timestamp should be in AV_TIME_BASE - * units from the beginning of the presentation. - * If a stream_index >= 0 is used and the protocol does not support - * seeking based on component streams, the call will fail. - * @param timestamp timestamp in AVStream.time_base units - * or if there is no stream specified then in AV_TIME_BASE units. - * @param flags Optional combination of AVSEEK_FLAG_BACKWARD, AVSEEK_FLAG_BYTE - * and AVSEEK_FLAG_ANY. The protocol may silently ignore - * AVSEEK_FLAG_BACKWARD and AVSEEK_FLAG_ANY, but AVSEEK_FLAG_BYTE will - * fail if used and not supported. - * @return >= 0 on success - * @see AVInputFormat::read_seek - */ -int64_t avio_seek_time(AVIOContext *h, int stream_index, - int64_t timestamp, int flags); - -#endif /* AVFORMAT_AVIO_H */ diff --git a/ffmpeg1/libavformat/avio_internal.h b/ffmpeg1/libavformat/avio_internal.h deleted file mode 100644 index cf36764..0000000 --- a/ffmpeg1/libavformat/avio_internal.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * - * 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 AVFORMAT_AVIO_INTERNAL_H -#define AVFORMAT_AVIO_INTERNAL_H - -#include "avio.h" -#include "url.h" - -#include "libavutil/log.h" - -extern const AVClass ffio_url_class; - -int ffio_init_context(AVIOContext *s, - unsigned char *buffer, - int buffer_size, - int write_flag, - void *opaque, - int (*read_packet)(void *opaque, uint8_t *buf, int buf_size), - int (*write_packet)(void *opaque, uint8_t *buf, int buf_size), - int64_t (*seek)(void *opaque, int64_t offset, int whence)); - - -/** - * Read size bytes from AVIOContext into buf. - * This reads at most 1 packet. If that is not enough fewer bytes will be - * returned. - * @return number of bytes read or AVERROR - */ -int ffio_read_partial(AVIOContext *s, unsigned char *buf, int size); - -void ffio_fill(AVIOContext *s, int b, int count); - -static av_always_inline void ffio_wfourcc(AVIOContext *pb, const uint8_t *s) -{ - avio_wl32(pb, MKTAG(s[0], s[1], s[2], s[3])); -} - -/** - * Rewind the AVIOContext using the specified buffer containing the first buf_size bytes of the file. - * Used after probing to avoid seeking. - * Joins buf and s->buffer, taking any overlap into consideration. - * @note s->buffer must overlap with buf or they can't be joined and the function fails - * - * @param s The read-only AVIOContext to rewind - * @param buf The probe buffer containing the first buf_size bytes of the file - * @param buf_size The size of buf - * @return 0 in case of success, a negative value corresponding to an - * AVERROR code in case of failure - */ -int ffio_rewind_with_probe_data(AVIOContext *s, unsigned char **buf, int buf_size); - -uint64_t ffio_read_varlen(AVIOContext *bc); - -/** @warning must be called before any I/O */ -int ffio_set_buf_size(AVIOContext *s, int buf_size); - -int ffio_limit(AVIOContext *s, int size); - -void ffio_init_checksum(AVIOContext *s, - unsigned long (*update_checksum)(unsigned long c, const uint8_t *p, unsigned int len), - unsigned long checksum); -unsigned long ffio_get_checksum(AVIOContext *s); -unsigned long ff_crc04C11DB7_update(unsigned long checksum, const uint8_t *buf, - unsigned int len); - -/** - * Open a write only packetized memory stream with a maximum packet - * size of 'max_packet_size'. The stream is stored in a memory buffer - * with a big-endian 4 byte header giving the packet size in bytes. - * - * @param s new IO context - * @param max_packet_size maximum packet size (must be > 0) - * @return zero if no error. - */ -int ffio_open_dyn_packet_buf(AVIOContext **s, int max_packet_size); - -/** - * Create and initialize a AVIOContext for accessing the - * resource referenced by the URLContext h. - * @note When the URLContext h has been opened in read+write mode, the - * AVIOContext can be used only for writing. - * - * @param s Used to return the pointer to the created AVIOContext. - * In case of failure the pointed to value is set to NULL. - * @return 0 in case of success, a negative value corresponding to an - * AVERROR code in case of failure - */ -int ffio_fdopen(AVIOContext **s, URLContext *h); - -#endif /* AVFORMAT_AVIO_INTERNAL_H */ diff --git a/ffmpeg1/libavformat/aviobuf.c b/ffmpeg1/libavformat/aviobuf.c deleted file mode 100644 index 7a73a17..0000000 --- a/ffmpeg1/libavformat/aviobuf.c +++ /dev/null @@ -1,1005 +0,0 @@ -/* - * buffered I/O - * Copyright (c) 2000,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 - */ - -#include "libavutil/crc.h" -#include "libavutil/dict.h" -#include "libavutil/intreadwrite.h" -#include "libavutil/log.h" -#include "libavutil/opt.h" -#include "libavutil/avassert.h" -#include "avformat.h" -#include "avio.h" -#include "avio_internal.h" -#include "internal.h" -#include "url.h" -#include - -#define IO_BUFFER_SIZE 32768 - -/** - * Do seeks within this distance ahead of the current buffer by skipping - * data instead of calling the protocol seek function, for seekable - * protocols. - */ -#define SHORT_SEEK_THRESHOLD 4096 - -static void *ffio_url_child_next(void *obj, void *prev) -{ - AVIOContext *s = obj; - return prev ? NULL : s->opaque; -} - -static const AVClass *ffio_url_child_class_next(const AVClass *prev) -{ - return prev ? NULL : &ffurl_context_class; -} - -static const AVOption ffio_url_options[] = { - { NULL }, -}; - -const AVClass ffio_url_class = { - .class_name = "AVIOContext", - .item_name = av_default_item_name, - .version = LIBAVUTIL_VERSION_INT, - .option = ffio_url_options, - .child_next = ffio_url_child_next, - .child_class_next = ffio_url_child_class_next, -}; - -static void fill_buffer(AVIOContext *s); -static int url_resetbuf(AVIOContext *s, int flags); - -int ffio_init_context(AVIOContext *s, - unsigned char *buffer, - int buffer_size, - int write_flag, - void *opaque, - int (*read_packet)(void *opaque, uint8_t *buf, int buf_size), - int (*write_packet)(void *opaque, uint8_t *buf, int buf_size), - int64_t (*seek)(void *opaque, int64_t offset, int whence)) -{ - s->buffer = buffer; - s->buffer_size = buffer_size; - s->buf_ptr = buffer; - s->opaque = opaque; - s->direct = 0; - - url_resetbuf(s, write_flag ? AVIO_FLAG_WRITE : AVIO_FLAG_READ); - - s->write_packet = write_packet; - s->read_packet = read_packet; - s->seek = seek; - s->pos = 0; - s->must_flush = 0; - s->eof_reached = 0; - s->error = 0; - s->seekable = AVIO_SEEKABLE_NORMAL; - s->max_packet_size = 0; - s->update_checksum = NULL; - - if (!read_packet && !write_flag) { - s->pos = buffer_size; - s->buf_end = s->buffer + buffer_size; - } - s->read_pause = NULL; - s->read_seek = NULL; - - return 0; -} - -AVIOContext *avio_alloc_context( - unsigned char *buffer, - int buffer_size, - int write_flag, - void *opaque, - int (*read_packet)(void *opaque, uint8_t *buf, int buf_size), - int (*write_packet)(void *opaque, uint8_t *buf, int buf_size), - int64_t (*seek)(void *opaque, int64_t offset, int whence)) -{ - AVIOContext *s = av_mallocz(sizeof(AVIOContext)); - if (!s) - return NULL; - ffio_init_context(s, buffer, buffer_size, write_flag, opaque, - read_packet, write_packet, seek); - return s; -} - -static void writeout(AVIOContext *s, const uint8_t *data, int len) -{ - if (s->write_packet && !s->error) { - int ret = s->write_packet(s->opaque, (uint8_t *)data, len); - if (ret < 0) { - s->error = ret; - } - } - s->pos += len; -} - -static void flush_buffer(AVIOContext *s) -{ - if (s->buf_ptr > s->buffer) { - writeout(s, s->buffer, s->buf_ptr - s->buffer); - if (s->update_checksum) { - s->checksum = s->update_checksum(s->checksum, s->checksum_ptr, - s->buf_ptr - s->checksum_ptr); - s->checksum_ptr = s->buffer; - } - } - s->buf_ptr = s->buffer; -} - -void avio_w8(AVIOContext *s, int b) -{ - av_assert2(b>=-128 && b<=255); - *s->buf_ptr++ = b; - if (s->buf_ptr >= s->buf_end) - flush_buffer(s); -} - -void ffio_fill(AVIOContext *s, int b, int count) -{ - while (count > 0) { - int len = FFMIN(s->buf_end - s->buf_ptr, count); - memset(s->buf_ptr, b, len); - s->buf_ptr += len; - - if (s->buf_ptr >= s->buf_end) - flush_buffer(s); - - count -= len; - } -} - -void avio_write(AVIOContext *s, const unsigned char *buf, int size) -{ - if (s->direct && !s->update_checksum) { - avio_flush(s); - writeout(s, buf, size); - return; - } - while (size > 0) { - int len = FFMIN(s->buf_end - s->buf_ptr, size); - memcpy(s->buf_ptr, buf, len); - s->buf_ptr += len; - - if (s->buf_ptr >= s->buf_end) - flush_buffer(s); - - buf += len; - size -= len; - } -} - -void avio_flush(AVIOContext *s) -{ - flush_buffer(s); - s->must_flush = 0; -} - -int64_t avio_seek(AVIOContext *s, int64_t offset, int whence) -{ - int64_t offset1; - int64_t pos; - int force = whence & AVSEEK_FORCE; - whence &= ~AVSEEK_FORCE; - - if(!s) - return AVERROR(EINVAL); - - pos = s->pos - (s->write_flag ? 0 : (s->buf_end - s->buffer)); - - if (whence != SEEK_CUR && whence != SEEK_SET) - return AVERROR(EINVAL); - - if (whence == SEEK_CUR) { - offset1 = pos + (s->buf_ptr - s->buffer); - if (offset == 0) - return offset1; - offset += offset1; - } - offset1 = offset - pos; - if (!s->must_flush && (!s->direct || !s->seek) && - offset1 >= 0 && offset1 <= (s->buf_end - s->buffer)) { - /* can do the seek inside the buffer */ - s->buf_ptr = s->buffer + offset1; - } else if ((!s->seekable || - offset1 <= s->buf_end + SHORT_SEEK_THRESHOLD - s->buffer) && - !s->write_flag && offset1 >= 0 && - (!s->direct || !s->seek) && - (whence != SEEK_END || force)) { - while(s->pos < offset && !s->eof_reached) - fill_buffer(s); - if (s->eof_reached) - return AVERROR_EOF; - s->buf_ptr = s->buf_end + offset - s->pos; - } else { - int64_t res; - - if (s->write_flag) { - flush_buffer(s); - s->must_flush = 1; - } - if (!s->seek) - return AVERROR(EPIPE); - if ((res = s->seek(s->opaque, offset, SEEK_SET)) < 0) - return res; - s->seek_count ++; - if (!s->write_flag) - s->buf_end = s->buffer; - s->buf_ptr = s->buffer; - s->pos = offset; - } - s->eof_reached = 0; - return offset; -} - -int64_t avio_skip(AVIOContext *s, int64_t offset) -{ - return avio_seek(s, offset, SEEK_CUR); -} - -int64_t avio_size(AVIOContext *s) -{ - int64_t size; - - if (!s) - return AVERROR(EINVAL); - - if (!s->seek) - return AVERROR(ENOSYS); - size = s->seek(s->opaque, 0, AVSEEK_SIZE); - if (size < 0) { - if ((size = s->seek(s->opaque, -1, SEEK_END)) < 0) - return size; - size++; - s->seek(s->opaque, s->pos, SEEK_SET); - } - return size; -} - -int url_feof(AVIOContext *s) -{ - if(!s) - return 0; - if(s->eof_reached){ - s->eof_reached=0; - fill_buffer(s); - } - return s->eof_reached; -} - -void avio_wl32(AVIOContext *s, unsigned int val) -{ - avio_w8(s, (uint8_t) val ); - avio_w8(s, (uint8_t)(val >> 8 )); - avio_w8(s, (uint8_t)(val >> 16)); - avio_w8(s, val >> 24 ); -} - -void avio_wb32(AVIOContext *s, unsigned int val) -{ - avio_w8(s, val >> 24 ); - avio_w8(s, (uint8_t)(val >> 16)); - avio_w8(s, (uint8_t)(val >> 8 )); - avio_w8(s, (uint8_t) val ); -} - -int avio_put_str(AVIOContext *s, const char *str) -{ - int len = 1; - if (str) { - len += strlen(str); - avio_write(s, (const unsigned char *) str, len); - } else - avio_w8(s, 0); - return len; -} - -int avio_put_str16le(AVIOContext *s, const char *str) -{ - const uint8_t *q = str; - int ret = 0; - - while (*q) { - uint32_t ch; - uint16_t tmp; - - GET_UTF8(ch, *q++, break;) - PUT_UTF16(ch, tmp, avio_wl16(s, tmp); ret += 2;) - } - avio_wl16(s, 0); - ret += 2; - return ret; -} - -int ff_get_v_length(uint64_t val) -{ - int i = 1; - - while (val >>= 7) - i++; - - return i; -} - -void ff_put_v(AVIOContext *bc, uint64_t val) -{ - int i = ff_get_v_length(val); - - while (--i > 0) - avio_w8(bc, 128 | (uint8_t)(val >> (7*i))); - - avio_w8(bc, val & 127); -} - -void avio_wl64(AVIOContext *s, uint64_t val) -{ - avio_wl32(s, (uint32_t)(val & 0xffffffff)); - avio_wl32(s, (uint32_t)(val >> 32)); -} - -void avio_wb64(AVIOContext *s, uint64_t val) -{ - avio_wb32(s, (uint32_t)(val >> 32)); - avio_wb32(s, (uint32_t)(val & 0xffffffff)); -} - -void avio_wl16(AVIOContext *s, unsigned int val) -{ - avio_w8(s, (uint8_t)val); - avio_w8(s, (int)val >> 8); -} - -void avio_wb16(AVIOContext *s, unsigned int val) -{ - avio_w8(s, (int)val >> 8); - avio_w8(s, (uint8_t)val); -} - -void avio_wl24(AVIOContext *s, unsigned int val) -{ - avio_wl16(s, val & 0xffff); - avio_w8(s, (int)val >> 16); -} - -void avio_wb24(AVIOContext *s, unsigned int val) -{ - avio_wb16(s, (int)val >> 8); - avio_w8(s, (uint8_t)val); -} - -/* Input stream */ - -static void fill_buffer(AVIOContext *s) -{ - uint8_t *dst = !s->max_packet_size && - s->buf_end - s->buffer < s->buffer_size ? - s->buf_end : s->buffer; - int len = s->buffer_size - (dst - s->buffer); - int max_buffer_size = s->max_packet_size ? - s->max_packet_size : IO_BUFFER_SIZE; - - /* can't fill the buffer without read_packet, just set EOF if appropriate */ - if (!s->read_packet && s->buf_ptr >= s->buf_end) - s->eof_reached = 1; - - /* no need to do anything if EOF already reached */ - if (s->eof_reached) - return; - - if (s->update_checksum && dst == s->buffer) { - if (s->buf_end > s->checksum_ptr) - s->checksum = s->update_checksum(s->checksum, s->checksum_ptr, - s->buf_end - s->checksum_ptr); - s->checksum_ptr = s->buffer; - } - - /* make buffer smaller in case it ended up large after probing */ - if (s->read_packet && s->buffer_size > max_buffer_size) { - ffio_set_buf_size(s, max_buffer_size); - - s->checksum_ptr = dst = s->buffer; - len = s->buffer_size; - } - - if (s->read_packet) - len = s->read_packet(s->opaque, dst, len); - else - len = 0; - if (len <= 0) { - /* do not modify buffer if EOF reached so that a seek back can - be done without rereading data */ - s->eof_reached = 1; - if (len < 0) - s->error = len; - } else { - s->pos += len; - s->buf_ptr = dst; - s->buf_end = dst + len; - s->bytes_read += len; - } -} - -unsigned long ff_crc04C11DB7_update(unsigned long checksum, const uint8_t *buf, - unsigned int len) -{ - return av_crc(av_crc_get_table(AV_CRC_32_IEEE), checksum, buf, len); -} - -unsigned long ffio_get_checksum(AVIOContext *s) -{ - s->checksum = s->update_checksum(s->checksum, s->checksum_ptr, - s->buf_ptr - s->checksum_ptr); - s->update_checksum = NULL; - return s->checksum; -} - -void ffio_init_checksum(AVIOContext *s, - unsigned long (*update_checksum)(unsigned long c, const uint8_t *p, unsigned int len), - unsigned long checksum) -{ - s->update_checksum = update_checksum; - if (s->update_checksum) { - s->checksum = checksum; - s->checksum_ptr = s->buf_ptr; - } -} - -/* XXX: put an inline version */ -int avio_r8(AVIOContext *s) -{ - if (s->buf_ptr >= s->buf_end) - fill_buffer(s); - if (s->buf_ptr < s->buf_end) - return *s->buf_ptr++; - return 0; -} - -int avio_read(AVIOContext *s, unsigned char *buf, int size) -{ - int len, size1; - - size1 = size; - while (size > 0) { - len = s->buf_end - s->buf_ptr; - if (len > size) - len = size; - if (len == 0 || s->write_flag) { - if((s->direct || size > s->buffer_size) && !s->update_checksum){ - if(s->read_packet) - len = s->read_packet(s->opaque, buf, size); - if (len <= 0) { - /* do not modify buffer if EOF reached so that a seek back can - be done without rereading data */ - s->eof_reached = 1; - if(len<0) - s->error= len; - break; - } else { - s->pos += len; - s->bytes_read += len; - size -= len; - buf += len; - s->buf_ptr = s->buffer; - s->buf_end = s->buffer/* + len*/; - } - } else { - fill_buffer(s); - len = s->buf_end - s->buf_ptr; - if (len == 0) - break; - } - } else { - memcpy(buf, s->buf_ptr, len); - buf += len; - s->buf_ptr += len; - size -= len; - } - } - if (size1 == size) { - if (s->error) return s->error; - if (url_feof(s)) return AVERROR_EOF; - } - return size1 - size; -} - -int ffio_read_partial(AVIOContext *s, unsigned char *buf, int size) -{ - int len; - - if (size < 0) - return -1; - - if (s->read_packet && s->write_flag) { - len = s->read_packet(s->opaque, buf, size); - if (len > 0) - s->pos += len; - return len; - } - - len = s->buf_end - s->buf_ptr; - if (len == 0) { - /* Reset the buf_end pointer to the start of the buffer, to make sure - * the fill_buffer call tries to read as much data as fits into the - * full buffer, instead of just what space is left after buf_end. - * This avoids returning partial packets at the end of the buffer, - * for packet based inputs. - */ - s->buf_end = s->buf_ptr = s->buffer; - fill_buffer(s); - len = s->buf_end - s->buf_ptr; - } - if (len > size) - len = size; - memcpy(buf, s->buf_ptr, len); - s->buf_ptr += len; - if (!len) { - if (s->error) return s->error; - if (url_feof(s)) return AVERROR_EOF; - } - return len; -} - -unsigned int avio_rl16(AVIOContext *s) -{ - unsigned int val; - val = avio_r8(s); - val |= avio_r8(s) << 8; - return val; -} - -unsigned int avio_rl24(AVIOContext *s) -{ - unsigned int val; - val = avio_rl16(s); - val |= avio_r8(s) << 16; - return val; -} - -unsigned int avio_rl32(AVIOContext *s) -{ - unsigned int val; - val = avio_rl16(s); - val |= avio_rl16(s) << 16; - return val; -} - -uint64_t avio_rl64(AVIOContext *s) -{ - uint64_t val; - val = (uint64_t)avio_rl32(s); - val |= (uint64_t)avio_rl32(s) << 32; - return val; -} - -unsigned int avio_rb16(AVIOContext *s) -{ - unsigned int val; - val = avio_r8(s) << 8; - val |= avio_r8(s); - return val; -} - -unsigned int avio_rb24(AVIOContext *s) -{ - unsigned int val; - val = avio_rb16(s) << 8; - val |= avio_r8(s); - return val; -} -unsigned int avio_rb32(AVIOContext *s) -{ - unsigned int val; - val = avio_rb16(s) << 16; - val |= avio_rb16(s); - return val; -} - -int ff_get_line(AVIOContext *s, char *buf, int maxlen) -{ - int i = 0; - char c; - - do { - c = avio_r8(s); - if (c && i < maxlen-1) - buf[i++] = c; - } while (c != '\n' && c); - - buf[i] = 0; - return i; -} - -int avio_get_str(AVIOContext *s, int maxlen, char *buf, int buflen) -{ - int i; - - if (buflen <= 0) - return AVERROR(EINVAL); - // reserve 1 byte for terminating 0 - buflen = FFMIN(buflen - 1, maxlen); - for (i = 0; i < buflen; i++) - if (!(buf[i] = avio_r8(s))) - return i + 1; - buf[i] = 0; - for (; i < maxlen; i++) - if (!avio_r8(s)) - return i + 1; - return maxlen; -} - -#define GET_STR16(type, read) \ - int avio_get_str16 ##type(AVIOContext *pb, int maxlen, char *buf, int buflen)\ -{\ - char* q = buf;\ - int ret = 0;\ - if (buflen <= 0) \ - return AVERROR(EINVAL); \ - while (ret + 1 < maxlen) {\ - uint8_t tmp;\ - uint32_t ch;\ - GET_UTF16(ch, (ret += 2) <= maxlen ? read(pb) : 0, break;)\ - if (!ch)\ - break;\ - PUT_UTF8(ch, tmp, if (q - buf < buflen - 1) *q++ = tmp;)\ - }\ - *q = 0;\ - return ret;\ -}\ - -GET_STR16(le, avio_rl16) -GET_STR16(be, avio_rb16) - -#undef GET_STR16 - -uint64_t avio_rb64(AVIOContext *s) -{ - uint64_t val; - val = (uint64_t)avio_rb32(s) << 32; - val |= (uint64_t)avio_rb32(s); - return val; -} - -uint64_t ffio_read_varlen(AVIOContext *bc){ - uint64_t val = 0; - int tmp; - - do{ - tmp = avio_r8(bc); - val= (val<<7) + (tmp&127); - }while(tmp&128); - return val; -} - -int ffio_fdopen(AVIOContext **s, URLContext *h) -{ - uint8_t *buffer; - int buffer_size, max_packet_size; - - max_packet_size = h->max_packet_size; - if (max_packet_size) { - buffer_size = max_packet_size; /* no need to bufferize more than one packet */ - } else { - buffer_size = IO_BUFFER_SIZE; - } - buffer = av_malloc(buffer_size); - if (!buffer) - return AVERROR(ENOMEM); - - *s = avio_alloc_context(buffer, buffer_size, h->flags & AVIO_FLAG_WRITE, h, - (void*)ffurl_read, (void*)ffurl_write, (void*)ffurl_seek); - if (!*s) { - av_free(buffer); - return AVERROR(ENOMEM); - } - (*s)->direct = h->flags & AVIO_FLAG_DIRECT; - (*s)->seekable = h->is_streamed ? 0 : AVIO_SEEKABLE_NORMAL; - (*s)->max_packet_size = max_packet_size; - if(h->prot) { - (*s)->read_pause = (int (*)(void *, int))h->prot->url_read_pause; - (*s)->read_seek = (int64_t (*)(void *, int, int64_t, int))h->prot->url_read_seek; - } - (*s)->av_class = &ffio_url_class; - return 0; -} - -int ffio_set_buf_size(AVIOContext *s, int buf_size) -{ - uint8_t *buffer; - buffer = av_malloc(buf_size); - if (!buffer) - return AVERROR(ENOMEM); - - av_free(s->buffer); - s->buffer = buffer; - s->buffer_size = buf_size; - s->buf_ptr = buffer; - url_resetbuf(s, s->write_flag ? AVIO_FLAG_WRITE : AVIO_FLAG_READ); - return 0; -} - -static int url_resetbuf(AVIOContext *s, int flags) -{ - av_assert1(flags == AVIO_FLAG_WRITE || flags == AVIO_FLAG_READ); - - if (flags & AVIO_FLAG_WRITE) { - s->buf_end = s->buffer + s->buffer_size; - s->write_flag = 1; - } else { - s->buf_end = s->buffer; - s->write_flag = 0; - } - return 0; -} - -int ffio_rewind_with_probe_data(AVIOContext *s, unsigned char **bufp, int buf_size) -{ - int64_t buffer_start; - int buffer_size; - int overlap, new_size, alloc_size; - uint8_t *buf = *bufp; - - if (s->write_flag) { - av_freep(bufp); - return AVERROR(EINVAL); - } - - buffer_size = s->buf_end - s->buffer; - - /* the buffers must touch or overlap */ - if ((buffer_start = s->pos - buffer_size) > buf_size) { - av_freep(bufp); - return AVERROR(EINVAL); - } - - overlap = buf_size - buffer_start; - new_size = buf_size + buffer_size - overlap; - - alloc_size = FFMAX(s->buffer_size, new_size); - if (alloc_size > buf_size) - if (!(buf = (*bufp) = av_realloc_f(buf, 1, alloc_size))) - return AVERROR(ENOMEM); - - if (new_size > buf_size) { - memcpy(buf + buf_size, s->buffer + overlap, buffer_size - overlap); - buf_size = new_size; - } - - av_free(s->buffer); - s->buf_ptr = s->buffer = buf; - s->buffer_size = alloc_size; - s->pos = buf_size; - s->buf_end = s->buf_ptr + buf_size; - s->eof_reached = 0; - s->must_flush = 0; - - return 0; -} - -int avio_open(AVIOContext **s, const char *filename, int flags) -{ - return avio_open2(s, filename, flags, NULL, NULL); -} - -int avio_open2(AVIOContext **s, const char *filename, int flags, - const AVIOInterruptCB *int_cb, AVDictionary **options) -{ - URLContext *h; - int err; - - err = ffurl_open(&h, filename, flags, int_cb, options); - if (err < 0) - return err; - err = ffio_fdopen(s, h); - if (err < 0) { - ffurl_close(h); - return err; - } - return 0; -} - -int avio_close(AVIOContext *s) -{ - URLContext *h; - - if (!s) - return 0; - - avio_flush(s); - h = s->opaque; - av_freep(&s->buffer); - if (!s->write_flag) - av_log(s, AV_LOG_DEBUG, "Statistics: %"PRId64" bytes read, %d seeks\n", s->bytes_read, s->seek_count); - av_free(s); - return ffurl_close(h); -} - -int avio_closep(AVIOContext **s) -{ - int ret = avio_close(*s); - *s = NULL; - return ret; -} - -int avio_printf(AVIOContext *s, const char *fmt, ...) -{ - va_list ap; - char buf[4096]; - int ret; - - va_start(ap, fmt); - ret = vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - avio_write(s, buf, strlen(buf)); - return ret; -} - -int avio_pause(AVIOContext *s, int pause) -{ - if (!s->read_pause) - return AVERROR(ENOSYS); - return s->read_pause(s->opaque, pause); -} - -int64_t avio_seek_time(AVIOContext *s, int stream_index, - int64_t timestamp, int flags) -{ - URLContext *h = s->opaque; - int64_t ret; - if (!s->read_seek) - return AVERROR(ENOSYS); - ret = s->read_seek(h, stream_index, timestamp, flags); - if (ret >= 0) { - int64_t pos; - s->buf_ptr = s->buf_end; // Flush buffer - pos = s->seek(h, 0, SEEK_CUR); - if (pos >= 0) - s->pos = pos; - else if (pos != AVERROR(ENOSYS)) - ret = pos; - } - return ret; -} - -/* output in a dynamic buffer */ - -typedef struct DynBuffer { - int pos, size, allocated_size; - uint8_t *buffer; - int io_buffer_size; - uint8_t io_buffer[1]; -} DynBuffer; - -static int dyn_buf_write(void *opaque, uint8_t *buf, int buf_size) -{ - DynBuffer *d = opaque; - unsigned new_size, new_allocated_size; - - /* reallocate buffer if needed */ - new_size = d->pos + buf_size; - new_allocated_size = d->allocated_size; - if (new_size < d->pos || new_size > INT_MAX/2) - return -1; - while (new_size > new_allocated_size) { - if (!new_allocated_size) - new_allocated_size = new_size; - else - new_allocated_size += new_allocated_size / 2 + 1; - } - - if (new_allocated_size > d->allocated_size) { - d->buffer = av_realloc_f(d->buffer, 1, new_allocated_size); - if(d->buffer == NULL) - return AVERROR(ENOMEM); - d->allocated_size = new_allocated_size; - } - memcpy(d->buffer + d->pos, buf, buf_size); - d->pos = new_size; - if (d->pos > d->size) - d->size = d->pos; - return buf_size; -} - -static int dyn_packet_buf_write(void *opaque, uint8_t *buf, int buf_size) -{ - unsigned char buf1[4]; - int ret; - - /* packetized write: output the header */ - AV_WB32(buf1, buf_size); - ret = dyn_buf_write(opaque, buf1, 4); - if (ret < 0) - return ret; - - /* then the data */ - return dyn_buf_write(opaque, buf, buf_size); -} - -static int64_t dyn_buf_seek(void *opaque, int64_t offset, int whence) -{ - DynBuffer *d = opaque; - - if (whence == SEEK_CUR) - offset += d->pos; - else if (whence == SEEK_END) - offset += d->size; - if (offset < 0 || offset > 0x7fffffffLL) - return -1; - d->pos = offset; - return 0; -} - -static int url_open_dyn_buf_internal(AVIOContext **s, int max_packet_size) -{ - DynBuffer *d; - unsigned io_buffer_size = max_packet_size ? max_packet_size : 1024; - - if (sizeof(DynBuffer) + io_buffer_size < io_buffer_size) - return -1; - d = av_mallocz(sizeof(DynBuffer) + io_buffer_size); - if (!d) - return AVERROR(ENOMEM); - d->io_buffer_size = io_buffer_size; - *s = avio_alloc_context(d->io_buffer, d->io_buffer_size, 1, d, NULL, - max_packet_size ? dyn_packet_buf_write : dyn_buf_write, - max_packet_size ? NULL : dyn_buf_seek); - if(!*s) { - av_free(d); - return AVERROR(ENOMEM); - } - (*s)->max_packet_size = max_packet_size; - return 0; -} - -int avio_open_dyn_buf(AVIOContext **s) -{ - return url_open_dyn_buf_internal(s, 0); -} - -int ffio_open_dyn_packet_buf(AVIOContext **s, int max_packet_size) -{ - if (max_packet_size <= 0) - return -1; - return url_open_dyn_buf_internal(s, max_packet_size); -} - -int avio_close_dyn_buf(AVIOContext *s, uint8_t **pbuffer) -{ - DynBuffer *d = s->opaque; - int size; - static const char padbuf[FF_INPUT_BUFFER_PADDING_SIZE] = {0}; - int padding = 0; - - /* don't attempt to pad fixed-size packet buffers */ - if (!s->max_packet_size) { - avio_write(s, padbuf, sizeof(padbuf)); - padding = FF_INPUT_BUFFER_PADDING_SIZE; - } - - avio_flush(s); - - *pbuffer = d->buffer; - size = d->size; - av_free(d); - av_free(s); - return size - padding; -} diff --git a/ffmpeg1/libavformat/avisynth.c b/ffmpeg1/libavformat/avisynth.c deleted file mode 100644 index d31031d..0000000 --- a/ffmpeg1/libavformat/avisynth.c +++ /dev/null @@ -1,641 +0,0 @@ -/* - * Avi/AvxSynth support - * Copyright (c) 2012 AvxSynth Team. - * - * 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 "internal.h" -#include "libavcodec/internal.h" - -// Enable function pointer definitions for runtime loading. -#define AVSC_NO_DECLSPEC - -// Shut up ffmpeg error messages. -// avisynth_c.h contains inline functions that call these functions. -#undef malloc -#undef free -#undef printf - -// Platform-specific directives for AviSynth vs AvxSynth. -#ifdef _WIN32 - #include - #undef EXTERN_C - #include "compat/avisynth/avisynth_c.h" - #define AVISYNTH_LIB "avisynth" -#else - #include - #include "compat/avisynth/avxsynth_c.h" - #if defined (__APPLE__) - #define AVISYNTH_LIB "libavxsynth.dylib" - #else - #define AVISYNTH_LIB "libavxsynth.so" - #endif - - #define LoadLibrary(x) dlopen(x, RTLD_NOW | RTLD_GLOBAL) - #define GetProcAddress dlsym - #define FreeLibrary dlclose -#endif - -// AvxSynth doesn't have these colorspaces, so disable them -#ifndef _WIN32 -#define avs_is_yv24(vi) 0 -#define avs_is_yv16(vi) 0 -#define avs_is_yv411(vi) 0 -#define avs_is_y8(vi) 0 -#endif - -typedef struct { - void *library; -#define AVSC_DECLARE_FUNC(name) name##_func name - AVSC_DECLARE_FUNC(avs_create_script_environment); - AVSC_DECLARE_FUNC(avs_delete_script_environment); - AVSC_DECLARE_FUNC(avs_get_error); - AVSC_DECLARE_FUNC(avs_clip_get_error); - AVSC_DECLARE_FUNC(avs_invoke); - AVSC_DECLARE_FUNC(avs_release_value); - AVSC_DECLARE_FUNC(avs_get_video_info); - AVSC_DECLARE_FUNC(avs_take_clip); - AVSC_DECLARE_FUNC(avs_release_clip); - AVSC_DECLARE_FUNC(avs_bit_blt); - AVSC_DECLARE_FUNC(avs_get_audio); - AVSC_DECLARE_FUNC(avs_get_frame); - AVSC_DECLARE_FUNC(avs_release_video_frame); -#undef AVSC_DECLARE_FUNC -} AviSynthLibrary; - -struct AviSynthContext { - AVS_ScriptEnvironment *env; - AVS_Clip *clip; - const AVS_VideoInfo *vi; - - // avisynth_read_packet_video() iterates over this. - int n_planes; - const int *planes; - - int curr_stream; - int curr_frame; - int64_t curr_sample; - - int error; - - // Linked list pointers. - struct AviSynthContext *next; -}; -typedef struct AviSynthContext AviSynthContext; - -static const int avs_planes_packed[1] = {0}; -static const int avs_planes_grey[1] = {AVS_PLANAR_Y}; -static const int avs_planes_yuv[3] = {AVS_PLANAR_Y, AVS_PLANAR_U, AVS_PLANAR_V}; - -// A conflict between C++ global objects, atexit, and dynamic loading requires -// us to register our own atexit handler to prevent double freeing. -static AviSynthLibrary *avs_library = NULL; -static int avs_atexit_called = 0; - -// Linked list of AviSynthContexts. An atexit handler destroys this list. -static AviSynthContext *avs_ctx_list = NULL; - -static av_cold void avisynth_atexit_handler(void); - -static av_cold int avisynth_load_library(void) { - avs_library = av_mallocz(sizeof(AviSynthLibrary)); - if (!avs_library) - return AVERROR_UNKNOWN; - - avs_library->library = LoadLibrary(AVISYNTH_LIB); - if (!avs_library->library) - goto init_fail; - -#define LOAD_AVS_FUNC(name, continue_on_fail) \ -{ \ - avs_library->name = (void*)GetProcAddress(avs_library->library, #name); \ - if(!continue_on_fail && !avs_library->name) \ - goto fail; \ -} - LOAD_AVS_FUNC(avs_create_script_environment, 0); - LOAD_AVS_FUNC(avs_delete_script_environment, 0); - LOAD_AVS_FUNC(avs_get_error, 1); // New to AviSynth 2.6 - LOAD_AVS_FUNC(avs_clip_get_error, 0); - LOAD_AVS_FUNC(avs_invoke, 0); - LOAD_AVS_FUNC(avs_release_value, 0); - LOAD_AVS_FUNC(avs_get_video_info, 0); - LOAD_AVS_FUNC(avs_take_clip, 0); - LOAD_AVS_FUNC(avs_release_clip, 0); - LOAD_AVS_FUNC(avs_bit_blt, 0); - LOAD_AVS_FUNC(avs_get_audio, 0); - LOAD_AVS_FUNC(avs_get_frame, 0); - LOAD_AVS_FUNC(avs_release_video_frame, 0); -#undef LOAD_AVS_FUNC - - atexit(avisynth_atexit_handler); - return 0; - -fail: - FreeLibrary(avs_library->library); -init_fail: - av_freep(&avs_library); - return AVERROR_UNKNOWN; -} - -// Note that avisynth_context_create and avisynth_context_destroy -// do not allocate or free the actual context! That is taken care of -// by libavformat. -static av_cold int avisynth_context_create(AVFormatContext *s) { - AviSynthContext *avs = (AviSynthContext *)s->priv_data; - int ret; - - if (!avs_library) { - if (ret = avisynth_load_library()) - return ret; - } - - if (!avs) - return AVERROR_UNKNOWN; - - if (!avs_ctx_list) { - avs_ctx_list = avs; - } else { - avs->next = avs_ctx_list; - avs_ctx_list = avs; - } - - avs->env = avs_library->avs_create_script_environment(3); - if (avs_library->avs_get_error) { - const char *error = avs_library->avs_get_error(avs->env); - if (error) { - av_log(s, AV_LOG_ERROR, "%s\n", error); - av_free(avs); - return AVERROR_UNKNOWN; - } - } - - return 0; -} - -static av_cold void avisynth_context_destroy(AviSynthContext *avs) { - if (avs_atexit_called) - return; - - if (avs == avs_ctx_list) { - avs_ctx_list = avs->next; - } else { - AviSynthContext *prev = avs_ctx_list; - while (prev->next != avs) - prev = prev->next; - prev->next = avs->next; - } - - if (avs->clip) { - avs_library->avs_release_clip(avs->clip); - avs->clip = NULL; - } - if (avs->env) { - avs_library->avs_delete_script_environment(avs->env); - avs->env = NULL; - } -} - -static av_cold void avisynth_atexit_handler(void) { - AviSynthContext *avs = avs_ctx_list; - - while (avs) { - AviSynthContext *next = avs->next; - avisynth_context_destroy(avs); - avs = next; - } - FreeLibrary(avs_library->library); - av_freep(&avs_library); - - avs_atexit_called = 1; -} - -// Create AVStream from audio and video data. -static int avisynth_create_stream_video(AVFormatContext *s, AVStream *st) { - AviSynthContext *avs = s->priv_data; - int planar = 0; // 0: packed, 1: YUV, 2: Y8 - - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = CODEC_ID_RAWVIDEO; - st->codec->width = avs->vi->width; - st->codec->height = avs->vi->height; - - st->time_base = (AVRational) {avs->vi->fps_denominator, avs->vi->fps_numerator}; - st->avg_frame_rate = (AVRational) {avs->vi->fps_numerator, avs->vi->fps_denominator}; - st->start_time = 0; - st->duration = avs->vi->num_frames; - st->nb_frames = avs->vi->num_frames; - - switch (avs->vi->pixel_type) { -#ifdef _WIN32 - case AVS_CS_YV24: - st->codec->pix_fmt = PIX_FMT_YUV444P; - planar = 1; - break; - case AVS_CS_YV16: - st->codec->pix_fmt = PIX_FMT_YUV422P; - planar = 1; - break; - case AVS_CS_YV411: - st->codec->pix_fmt = PIX_FMT_YUV411P; - planar = 1; - break; - case AVS_CS_Y8: - st->codec->pix_fmt = PIX_FMT_GRAY8; - planar = 2; - break; -#endif - case AVS_CS_BGR24: - st->codec->pix_fmt = PIX_FMT_RGB24; - break; - case AVS_CS_BGR32: - st->codec->pix_fmt = PIX_FMT_RGB32; - break; - case AVS_CS_YUY2: - st->codec->pix_fmt = PIX_FMT_YUYV422; - break; - case AVS_CS_YV12: - st->codec->pix_fmt = PIX_FMT_YUV420P; - planar = 1; - break; - case AVS_CS_I420: // Is this even used anywhere? - st->codec->pix_fmt = PIX_FMT_YUV420P; - planar = 1; - break; - default: - av_log(s, AV_LOG_ERROR, "unknown AviSynth colorspace %d\n", avs->vi->pixel_type); - avs->error = 1; - return AVERROR_UNKNOWN; - } - - switch (planar) { - case 2: // Y8 - avs->n_planes = 1; - avs->planes = avs_planes_grey; - break; - case 1: // YUV - avs->n_planes = 3; - avs->planes = avs_planes_yuv; - break; - default: - avs->n_planes = 1; - avs->planes = avs_planes_packed; - } - return 0; -} - -static int avisynth_create_stream_audio(AVFormatContext *s, AVStream *st) { - AviSynthContext *avs = s->priv_data; - - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->sample_rate = avs->vi->audio_samples_per_second; - st->codec->channels = avs->vi->nchannels; - st->time_base = (AVRational) {1, avs->vi->audio_samples_per_second}; - - switch (avs->vi->sample_type) { - case AVS_SAMPLE_INT8: - st->codec->codec_id = CODEC_ID_PCM_U8; - break; - case AVS_SAMPLE_INT16: - st->codec->codec_id = CODEC_ID_PCM_S16LE; - break; - case AVS_SAMPLE_INT24: - st->codec->codec_id = CODEC_ID_PCM_S24LE; - break; - case AVS_SAMPLE_INT32: - st->codec->codec_id = CODEC_ID_PCM_S32LE; - break; - case AVS_SAMPLE_FLOAT: - st->codec->codec_id = CODEC_ID_PCM_F32LE; - break; - default: - av_log(s, AV_LOG_ERROR, "unknown AviSynth sample type %d\n", avs->vi->sample_type); - avs->error = 1; - return AVERROR_UNKNOWN; - } - return 0; -} - -static int avisynth_create_stream(AVFormatContext *s) { - AviSynthContext *avs = s->priv_data; - AVStream *st; - int ret; - int id = 0; - - if (avs_has_video(avs->vi)) { - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR_UNKNOWN; - st->id = id++; - if (ret = avisynth_create_stream_video(s, st)) - return ret; - } - if (avs_has_audio(avs->vi)) { - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR_UNKNOWN; - st->id = id++; - if (ret = avisynth_create_stream_audio(s, st)) - return ret; - } - return 0; -} - -static int avisynth_open_file(AVFormatContext *s) { - AviSynthContext *avs = (AviSynthContext *)s->priv_data; - AVS_Value arg, val; - int ret; - - if (ret = avisynth_context_create(s)) - return ret; - - arg = avs_new_value_string(s->filename); - val = avs_library->avs_invoke(avs->env, "Import", arg, 0); - if (avs_is_error(val)) { - av_log(s, AV_LOG_ERROR, "%s\n", avs_as_error(val)); - ret = AVERROR_UNKNOWN; - goto fail; - } - if (!avs_is_clip(val)) { - av_log(s, AV_LOG_ERROR, "%s\n", "AviSynth script did not return a clip"); - ret = AVERROR_UNKNOWN; - goto fail; - } - - avs->clip = avs_library->avs_take_clip(val, avs->env); - avs->vi = avs_library->avs_get_video_info(avs->clip); - - // Release the AVS_Value as it will go out of scope. - avs_library->avs_release_value(val); - - if (ret = avisynth_create_stream(s)) - goto fail; - - return 0; - -fail: - avisynth_context_destroy(avs); - return ret; -} - -static void avisynth_next_stream(AVFormatContext *s, AVStream **st, AVPacket *pkt, int *discard) { - AviSynthContext *avs = s->priv_data; - - pkt->stream_index = avs->curr_stream++; - avs->curr_stream %= s->nb_streams; - - *st = s->streams[pkt->stream_index]; - if ((*st)->discard == AVDISCARD_ALL) - *discard = 1; - else - *discard = 0; - - return; -} - -// Copy AviSynth clip data into an AVPacket. -static int avisynth_read_packet_video(AVFormatContext *s, AVPacket *pkt, int discard) { - AviSynthContext *avs = s->priv_data; - AVS_VideoFrame *frame; - unsigned char* dst_p; - const unsigned char* src_p; - int i, plane, rowsize, planeheight, pitch, bits; - const char* error; - - if (avs->curr_frame >= avs->vi->num_frames) - return AVERROR_EOF; - - // This must happen even if the stream is discarded to prevent desync. - avs->curr_frame++; - if (discard) - return 0; - - pkt->pts = avs->curr_frame; - pkt->dts = avs->curr_frame; - pkt->duration = 1; - - // Define the bpp values for the new AviSynth 2.6 colorspaces - if (avs_is_yv24(avs->vi)) { - bits = 24; - } else if (avs_is_yv16(avs->vi)) { - bits = 16; - } else if (avs_is_yv411(avs->vi)) { - bits = 12; - } else if (avs_is_y8(avs->vi)) { - bits = 8; - } else { - bits = avs_bits_per_pixel(avs->vi); - } - - // Without cast to int64_t, calculation overflows at about 9k x 9k resolution. - pkt->size = (((int64_t)avs->vi->width * (int64_t)avs->vi->height) * bits) / 8; - if (!pkt->size) - return AVERROR_UNKNOWN; - pkt->data = av_malloc(pkt->size); - if (!pkt->data) - return AVERROR_UNKNOWN; - - frame = avs_library->avs_get_frame(avs->clip, avs->curr_frame); - error = avs_library->avs_clip_get_error(avs->clip); - if (error) { - av_log(s, AV_LOG_ERROR, "%s\n", error); - avs->error = 1; - av_freep(&pkt->data); - return AVERROR_UNKNOWN; - } - - dst_p = pkt->data; - for (i = 0; i < avs->n_planes; i++) { - plane = avs->planes[i]; - src_p = avs_get_read_ptr_p(frame, plane); - rowsize = avs_get_row_size_p(frame, plane); - planeheight = avs_get_height_p(frame, plane); - pitch = avs_get_pitch_p(frame, plane); - - // Flip RGB video. - if (avs_is_rgb24(avs->vi) || avs_is_rgb(avs->vi)) { - src_p = src_p + (planeheight - 1) * pitch; - pitch = -pitch; - } - - avs_library->avs_bit_blt(avs->env, dst_p, rowsize, src_p, pitch, rowsize, planeheight); - dst_p += rowsize * planeheight; - } - - avs_library->avs_release_video_frame(frame); - return 0; -} - -static int avisynth_read_packet_audio(AVFormatContext *s, AVPacket *pkt, int discard) { - AviSynthContext *avs = s->priv_data; - AVRational fps, samplerate; - int samples; - const char* error; - - if (avs->curr_sample >= avs->vi->num_audio_samples) - return AVERROR_EOF; - - fps.num = avs->vi->fps_numerator; - fps.den = avs->vi->fps_denominator; - samplerate.num = avs->vi->audio_samples_per_second; - samplerate.den = 1; - - if (avs_has_video(avs->vi)) { - if (avs->curr_frame < avs->vi->num_frames) - samples = av_rescale_q(avs->curr_frame, samplerate, fps) - avs->curr_sample; - else - samples = av_rescale_q(1, samplerate, fps); - } else { - samples = 1000; - } - - // After seeking, audio may catch up with video. - if (samples <= 0) { - pkt->size = 0; - pkt->data = NULL; - return 0; - } - - if (avs->curr_sample + samples > avs->vi->num_audio_samples) - samples = avs->vi->num_audio_samples - avs->curr_sample; - - // This must happen even if the stream is discarded to prevent desync. - avs->curr_sample += samples; - if (discard) - return 0; - - pkt->pts = avs->curr_sample; - pkt->dts = avs->curr_sample; - pkt->duration = samples; - - pkt->size = avs_bytes_per_channel_sample(avs->vi) * samples * avs->vi->nchannels; - if (!pkt->size) - return AVERROR_UNKNOWN; - pkt->data = av_malloc(pkt->size); - if (!pkt->data) - return AVERROR_UNKNOWN; - - avs_library->avs_get_audio(avs->clip, pkt->data, avs->curr_sample, samples); - error = avs_library->avs_clip_get_error(avs->clip); - if (error) { - av_log(s, AV_LOG_ERROR, "%s\n", error); - avs->error = 1; - av_freep(&pkt->data); - return AVERROR_UNKNOWN; - } - return 0; -} - -static av_cold int avisynth_read_header(AVFormatContext *s) { - int ret; - - // Calling library must implement a lock for thread-safe opens. - if (ret = avpriv_lock_avformat()) - return ret; - - if (ret = avisynth_open_file(s)) { - avpriv_unlock_avformat(); - return ret; - } - - avpriv_unlock_avformat(); - return 0; -} - -static int avisynth_read_packet(AVFormatContext *s, AVPacket *pkt) { - AviSynthContext *avs = s->priv_data; - AVStream *st; - int discard = 0; - int ret; - - if (avs->error) - return AVERROR_UNKNOWN; - - pkt->destruct = av_destruct_packet; - - // If either stream reaches EOF, try to read the other one before giving up. - avisynth_next_stream(s, &st, pkt, &discard); - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { - ret = avisynth_read_packet_video(s, pkt, discard); - if (ret == AVERROR_EOF && avs_has_audio(avs->vi)) { - avisynth_next_stream(s, &st, pkt, &discard); - return avisynth_read_packet_audio(s, pkt, discard); - } - return ret; - } else { - ret = avisynth_read_packet_audio(s, pkt, discard); - if (ret == AVERROR_EOF && avs_has_video(avs->vi)) { - avisynth_next_stream(s, &st, pkt, &discard); - return avisynth_read_packet_video(s, pkt, discard); - } - return ret; - } -} - -static av_cold int avisynth_read_close(AVFormatContext *s) { - if (avpriv_lock_avformat()) - return AVERROR_UNKNOWN; - - avisynth_context_destroy(s->priv_data); - avpriv_unlock_avformat(); - return 0; -} - -static int avisynth_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) { - AviSynthContext *avs = s->priv_data; - AVStream *st; - AVRational fps, samplerate; - - if (avs->error) - return AVERROR_UNKNOWN; - - fps = (AVRational) {avs->vi->fps_numerator, avs->vi->fps_denominator}; - samplerate = (AVRational) {avs->vi->audio_samples_per_second, 1}; - - st = s->streams[stream_index]; - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { - // AviSynth frame counts are signed int. - if ((timestamp >= avs->vi->num_frames) || (timestamp > INT_MAX) || (timestamp < 0)) - return AVERROR_EOF; - avs->curr_frame = timestamp; - if (avs_has_audio(avs->vi)) - avs->curr_sample = av_rescale_q(timestamp, samplerate, fps); - } else { - if ((timestamp >= avs->vi->num_audio_samples) || (timestamp < 0)) - return AVERROR_EOF; - // Force frame granularity for seeking. - if (avs_has_video(avs->vi)) { - avs->curr_frame = av_rescale_q(timestamp, fps, samplerate); - avs->curr_sample = av_rescale_q(avs->curr_frame, samplerate, fps); - } else { - avs->curr_sample = timestamp; - } - } - - return 0; -} - -AVInputFormat ff_avisynth_demuxer = { - .name = "avisynth", - .long_name = NULL_IF_CONFIG_SMALL("AviSynth script"), - .priv_data_size = sizeof(AviSynthContext), - .read_header = avisynth_read_header, - .read_packet = avisynth_read_packet, - .read_close = avisynth_read_close, - .read_seek = avisynth_read_seek, - .extensions = "avs", -}; diff --git a/ffmpeg1/libavformat/avlanguage.c b/ffmpeg1/libavformat/avlanguage.c deleted file mode 100644 index 39f2560..0000000 --- a/ffmpeg1/libavformat/avlanguage.c +++ /dev/null @@ -1,765 +0,0 @@ -/* - * Cyril Comparon, Larbi Joubala, Resonate-MP4 2009 - * - * 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 "avlanguage.h" -#include "libavutil/avstring.h" -#include "libavutil/common.h" -#include -#include -#include - -typedef struct LangEntry { - const char str[4]; - uint16_t next_equivalent; -} LangEntry; - -static const uint16_t lang_table_counts[] = { 484, 20, 184 }; -static const uint16_t lang_table_offsets[] = { 0, 484, 504 }; - -static const LangEntry lang_table[] = { - /*----- AV_LANG_ISO639_2_BIBL entries (484) -----*/ - /*0000*/ { "aar", 504 }, - /*0001*/ { "abk", 505 }, - /*0002*/ { "ace", 2 }, - /*0003*/ { "ach", 3 }, - /*0004*/ { "ada", 4 }, - /*0005*/ { "ady", 5 }, - /*0006*/ { "afa", 6 }, - /*0007*/ { "afh", 7 }, - /*0008*/ { "afr", 507 }, - /*0009*/ { "ain", 9 }, - /*0010*/ { "aka", 508 }, - /*0011*/ { "akk", 11 }, - /*0012*/ { "alb", 502 }, - /*0013*/ { "ale", 13 }, - /*0014*/ { "alg", 14 }, - /*0015*/ { "alt", 15 }, - /*0016*/ { "amh", 509 }, - /*0017*/ { "ang", 17 }, - /*0018*/ { "anp", 18 }, - /*0019*/ { "apa", 19 }, - /*0020*/ { "ara", 511 }, - /*0021*/ { "arc", 21 }, - /*0022*/ { "arg", 510 }, - /*0023*/ { "arm", 492 }, - /*0024*/ { "arn", 24 }, - /*0025*/ { "arp", 25 }, - /*0026*/ { "art", 26 }, - /*0027*/ { "arw", 27 }, - /*0028*/ { "asm", 512 }, - /*0029*/ { "ast", 29 }, - /*0030*/ { "ath", 30 }, - /*0031*/ { "aus", 31 }, - /*0032*/ { "ava", 513 }, - /*0033*/ { "ave", 506 }, - /*0034*/ { "awa", 34 }, - /*0035*/ { "aym", 514 }, - /*0036*/ { "aze", 515 }, - /*0037*/ { "bad", 37 }, - /*0038*/ { "bai", 38 }, - /*0039*/ { "bak", 516 }, - /*0040*/ { "bal", 40 }, - /*0041*/ { "bam", 521 }, - /*0042*/ { "ban", 42 }, - /*0043*/ { "baq", 489 }, - /*0044*/ { "bas", 44 }, - /*0045*/ { "bat", 45 }, - /*0046*/ { "bej", 46 }, - /*0047*/ { "bel", 517 }, - /*0048*/ { "bem", 48 }, - /*0049*/ { "ben", 522 }, - /*0050*/ { "ber", 50 }, - /*0051*/ { "bho", 51 }, - /*0052*/ { "bih", 519 }, - /*0053*/ { "bik", 53 }, - /*0054*/ { "bin", 54 }, - /*0055*/ { "bis", 520 }, - /*0056*/ { "bla", 56 }, - /*0057*/ { "bnt", 57 }, - /*0058*/ { "bos", 525 }, - /*0059*/ { "bra", 59 }, - /*0060*/ { "bre", 524 }, - /*0061*/ { "btk", 61 }, - /*0062*/ { "bua", 62 }, - /*0063*/ { "bug", 63 }, - /*0064*/ { "bul", 518 }, - /*0065*/ { "bur", 498 }, - /*0066*/ { "byn", 66 }, - /*0067*/ { "cad", 67 }, - /*0068*/ { "cai", 68 }, - /*0069*/ { "car", 69 }, - /*0070*/ { "cat", 526 }, - /*0071*/ { "cau", 71 }, - /*0072*/ { "ceb", 72 }, - /*0073*/ { "cel", 73 }, - /*0074*/ { "cha", 528 }, - /*0075*/ { "chb", 75 }, - /*0076*/ { "che", 527 }, - /*0077*/ { "chg", 77 }, - /*0078*/ { "chi", 503 }, - /*0079*/ { "chk", 79 }, - /*0080*/ { "chm", 80 }, - /*0081*/ { "chn", 81 }, - /*0082*/ { "cho", 82 }, - /*0083*/ { "chp", 83 }, - /*0084*/ { "chr", 84 }, - /*0085*/ { "chu", 532 }, - /*0086*/ { "chv", 533 }, - /*0087*/ { "chy", 87 }, - /*0088*/ { "cmc", 88 }, - /*0089*/ { "cop", 89 }, - /*0090*/ { "cor", 593 }, - /*0091*/ { "cos", 529 }, - /*0092*/ { "cpe", 92 }, - /*0093*/ { "cpf", 93 }, - /*0094*/ { "cpp", 94 }, - /*0095*/ { "cre", 530 }, - /*0096*/ { "crh", 96 }, - /*0097*/ { "crp", 97 }, - /*0098*/ { "csb", 98 }, - /*0099*/ { "cus", 99 }, - /*0100*/ { "cze", 485 }, - /*0101*/ { "dak", 101 }, - /*0102*/ { "dan", 535 }, - /*0103*/ { "dar", 103 }, - /*0104*/ { "day", 104 }, - /*0105*/ { "del", 105 }, - /*0106*/ { "den", 106 }, - /*0107*/ { "dgr", 107 }, - /*0108*/ { "din", 108 }, - /*0109*/ { "div", 537 }, - /*0110*/ { "doi", 110 }, - /*0111*/ { "dra", 111 }, - /*0112*/ { "dsb", 112 }, - /*0113*/ { "dua", 113 }, - /*0114*/ { "dum", 114 }, - /*0115*/ { "dut", 499 }, - /*0116*/ { "dyu", 116 }, - /*0117*/ { "dzo", 538 }, - /*0118*/ { "efi", 118 }, - /*0119*/ { "egy", 119 }, - /*0120*/ { "eka", 120 }, - /*0121*/ { "elx", 121 }, - /*0122*/ { "eng", 541 }, - /*0123*/ { "enm", 123 }, - /*0124*/ { "epo", 542 }, - /*0125*/ { "est", 544 }, - /*0126*/ { "ewe", 539 }, - /*0127*/ { "ewo", 127 }, - /*0128*/ { "fan", 128 }, - /*0129*/ { "fao", 550 }, - /*0130*/ { "fat", 130 }, - /*0131*/ { "fij", 549 }, - /*0132*/ { "fil", 132 }, - /*0133*/ { "fin", 548 }, - /*0134*/ { "fiu", 134 }, - /*0135*/ { "fon", 135 }, - /*0136*/ { "fre", 491 }, - /*0137*/ { "frm", 137 }, - /*0138*/ { "fro", 138 }, - /*0139*/ { "frr", 139 }, - /*0140*/ { "frs", 140 }, - /*0141*/ { "fry", 552 }, - /*0142*/ { "ful", 547 }, - /*0143*/ { "fur", 143 }, - /*0144*/ { "gaa", 144 }, - /*0145*/ { "gay", 145 }, - /*0146*/ { "gba", 146 }, - /*0147*/ { "gem", 147 }, - /*0148*/ { "geo", 494 }, - /*0149*/ { "ger", 487 }, - /*0150*/ { "gez", 150 }, - /*0151*/ { "gil", 151 }, - /*0152*/ { "gla", 554 }, - /*0153*/ { "gle", 553 }, - /*0154*/ { "glg", 555 }, - /*0155*/ { "glv", 558 }, - /*0156*/ { "gmh", 156 }, - /*0157*/ { "goh", 157 }, - /*0158*/ { "gon", 158 }, - /*0159*/ { "gor", 159 }, - /*0160*/ { "got", 160 }, - /*0161*/ { "grb", 161 }, - /*0162*/ { "grc", 162 }, - /*0163*/ { "gre", 488 }, - /*0164*/ { "grn", 556 }, - /*0165*/ { "gsw", 165 }, - /*0166*/ { "guj", 557 }, - /*0167*/ { "gwi", 167 }, - /*0168*/ { "hai", 168 }, - /*0169*/ { "hat", 564 }, - /*0170*/ { "hau", 559 }, - /*0171*/ { "haw", 171 }, - /*0172*/ { "heb", 560 }, - /*0173*/ { "her", 567 }, - /*0174*/ { "hil", 174 }, - /*0175*/ { "him", 175 }, - /*0176*/ { "hin", 561 }, - /*0177*/ { "hit", 177 }, - /*0178*/ { "hmn", 178 }, - /*0179*/ { "hmo", 562 }, - /*0180*/ { "hrv", 563 }, - /*0181*/ { "hsb", 181 }, - /*0182*/ { "hun", 565 }, - /*0183*/ { "hup", 183 }, - /*0184*/ { "iba", 184 }, - /*0185*/ { "ibo", 571 }, - /*0186*/ { "ice", 493 }, - /*0187*/ { "ido", 574 }, - /*0188*/ { "iii", 572 }, - /*0189*/ { "ijo", 189 }, - /*0190*/ { "iku", 577 }, - /*0191*/ { "ile", 570 }, - /*0192*/ { "ilo", 192 }, - /*0193*/ { "ina", 568 }, - /*0194*/ { "inc", 194 }, - /*0195*/ { "ind", 569 }, - /*0196*/ { "ine", 196 }, - /*0197*/ { "inh", 197 }, - /*0198*/ { "ipk", 573 }, - /*0199*/ { "ira", 199 }, - /*0200*/ { "iro", 200 }, - /*0201*/ { "ita", 576 }, - /*0202*/ { "jav", 579 }, - /*0203*/ { "jbo", 203 }, - /*0204*/ { "jpn", 578 }, - /*0205*/ { "jpr", 205 }, - /*0206*/ { "jrb", 206 }, - /*0207*/ { "kaa", 207 }, - /*0208*/ { "kab", 208 }, - /*0209*/ { "kac", 209 }, - /*0210*/ { "kal", 585 }, - /*0211*/ { "kam", 211 }, - /*0212*/ { "kan", 587 }, - /*0213*/ { "kar", 213 }, - /*0214*/ { "kas", 590 }, - /*0215*/ { "kau", 589 }, - /*0216*/ { "kaw", 216 }, - /*0217*/ { "kaz", 584 }, - /*0218*/ { "kbd", 218 }, - /*0219*/ { "kha", 219 }, - /*0220*/ { "khi", 220 }, - /*0221*/ { "khm", 586 }, - /*0222*/ { "kho", 222 }, - /*0223*/ { "kik", 582 }, - /*0224*/ { "kin", 640 }, - /*0225*/ { "kir", 594 }, - /*0226*/ { "kmb", 226 }, - /*0227*/ { "kok", 227 }, - /*0228*/ { "kom", 592 }, - /*0229*/ { "kon", 581 }, - /*0230*/ { "kor", 588 }, - /*0231*/ { "kos", 231 }, - /*0232*/ { "kpe", 232 }, - /*0233*/ { "krc", 233 }, - /*0234*/ { "krl", 234 }, - /*0235*/ { "kro", 235 }, - /*0236*/ { "kru", 236 }, - /*0237*/ { "kua", 583 }, - /*0238*/ { "kum", 238 }, - /*0239*/ { "kur", 591 }, - /*0240*/ { "kut", 240 }, - /*0241*/ { "lad", 241 }, - /*0242*/ { "lah", 242 }, - /*0243*/ { "lam", 243 }, - /*0244*/ { "lao", 600 }, - /*0245*/ { "lat", 595 }, - /*0246*/ { "lav", 603 }, - /*0247*/ { "lez", 247 }, - /*0248*/ { "lim", 598 }, - /*0249*/ { "lin", 599 }, - /*0250*/ { "lit", 601 }, - /*0251*/ { "lol", 251 }, - /*0252*/ { "loz", 252 }, - /*0253*/ { "ltz", 596 }, - /*0254*/ { "lua", 254 }, - /*0255*/ { "lub", 602 }, - /*0256*/ { "lug", 597 }, - /*0257*/ { "lui", 257 }, - /*0258*/ { "lun", 258 }, - /*0259*/ { "luo", 259 }, - /*0260*/ { "lus", 260 }, - /*0261*/ { "mac", 495 }, - /*0262*/ { "mad", 262 }, - /*0263*/ { "mag", 263 }, - /*0264*/ { "mah", 605 }, - /*0265*/ { "mai", 265 }, - /*0266*/ { "mak", 266 }, - /*0267*/ { "mal", 608 }, - /*0268*/ { "man", 268 }, - /*0269*/ { "mao", 496 }, - /*0270*/ { "map", 270 }, - /*0271*/ { "mar", 610 }, - /*0272*/ { "mas", 272 }, - /*0273*/ { "may", 497 }, - /*0274*/ { "mdf", 274 }, - /*0275*/ { "mdr", 275 }, - /*0276*/ { "men", 276 }, - /*0277*/ { "mga", 277 }, - /*0278*/ { "mic", 278 }, - /*0279*/ { "min", 279 }, - /*0280*/ { "mis", 280 }, - /*0281*/ { "mkh", 281 }, - /*0282*/ { "mlg", 604 }, - /*0283*/ { "mlt", 612 }, - /*0284*/ { "mnc", 284 }, - /*0285*/ { "mni", 285 }, - /*0286*/ { "mno", 286 }, - /*0287*/ { "moh", 287 }, - /*0288*/ { "mon", 609 }, - /*0289*/ { "mos", 289 }, - /*0290*/ { "mul", 290 }, - /*0291*/ { "mun", 291 }, - /*0292*/ { "mus", 292 }, - /*0293*/ { "mwl", 293 }, - /*0294*/ { "mwr", 294 }, - /*0295*/ { "myn", 295 }, - /*0296*/ { "myv", 296 }, - /*0297*/ { "nah", 297 }, - /*0298*/ { "nai", 298 }, - /*0299*/ { "nap", 299 }, - /*0300*/ { "nau", 614 }, - /*0301*/ { "nav", 623 }, - /*0302*/ { "nbl", 622 }, - /*0303*/ { "nde", 616 }, - /*0304*/ { "ndo", 618 }, - /*0305*/ { "nds", 305 }, - /*0306*/ { "nep", 617 }, - /*0307*/ { "new", 307 }, - /*0308*/ { "nia", 308 }, - /*0309*/ { "nic", 309 }, - /*0310*/ { "niu", 310 }, - /*0311*/ { "nno", 620 }, - /*0312*/ { "nob", 615 }, - /*0313*/ { "nog", 313 }, - /*0314*/ { "non", 314 }, - /*0315*/ { "nor", 621 }, - /*0316*/ { "nqo", 316 }, - /*0317*/ { "nso", 317 }, - /*0318*/ { "nub", 318 }, - /*0319*/ { "nwc", 319 }, - /*0320*/ { "nya", 624 }, - /*0321*/ { "nym", 321 }, - /*0322*/ { "nyn", 322 }, - /*0323*/ { "nyo", 323 }, - /*0324*/ { "nzi", 324 }, - /*0325*/ { "oci", 625 }, - /*0326*/ { "oji", 626 }, - /*0327*/ { "ori", 628 }, - /*0328*/ { "orm", 627 }, - /*0329*/ { "osa", 329 }, - /*0330*/ { "oss", 629 }, - /*0331*/ { "ota", 331 }, - /*0332*/ { "oto", 332 }, - /*0333*/ { "paa", 333 }, - /*0334*/ { "pag", 334 }, - /*0335*/ { "pal", 335 }, - /*0336*/ { "pam", 336 }, - /*0337*/ { "pan", 630 }, - /*0338*/ { "pap", 338 }, - /*0339*/ { "pau", 339 }, - /*0340*/ { "peo", 340 }, - /*0341*/ { "per", 490 }, - /*0342*/ { "phi", 342 }, - /*0343*/ { "phn", 343 }, - /*0344*/ { "pli", 631 }, - /*0345*/ { "pol", 632 }, - /*0346*/ { "pon", 346 }, - /*0347*/ { "por", 634 }, - /*0348*/ { "pra", 348 }, - /*0349*/ { "pro", 349 }, - /*0350*/ { "pus", 633 }, - /*0351*/ { "que", 635 }, - /*0352*/ { "raj", 352 }, - /*0353*/ { "rap", 353 }, - /*0354*/ { "rar", 354 }, - /*0355*/ { "roa", 355 }, - /*0356*/ { "roh", 636 }, - /*0357*/ { "rom", 357 }, - /*0358*/ { "rum", 500 }, - /*0359*/ { "run", 637 }, - /*0360*/ { "rup", 360 }, - /*0361*/ { "rus", 639 }, - /*0362*/ { "sad", 362 }, - /*0363*/ { "sag", 645 }, - /*0364*/ { "sah", 364 }, - /*0365*/ { "sai", 365 }, - /*0366*/ { "sal", 366 }, - /*0367*/ { "sam", 367 }, - /*0368*/ { "san", 641 }, - /*0369*/ { "sas", 369 }, - /*0370*/ { "sat", 370 }, - /*0371*/ { "scn", 371 }, - /*0372*/ { "sco", 372 }, - /*0373*/ { "sel", 373 }, - /*0374*/ { "sem", 374 }, - /*0375*/ { "sga", 375 }, - /*0376*/ { "sgn", 376 }, - /*0377*/ { "shn", 377 }, - /*0378*/ { "sid", 378 }, - /*0379*/ { "sin", 646 }, - /*0380*/ { "sio", 380 }, - /*0381*/ { "sit", 381 }, - /*0382*/ { "sla", 382 }, - /*0383*/ { "slo", 501 }, - /*0384*/ { "slv", 648 }, - /*0385*/ { "sma", 385 }, - /*0386*/ { "sme", 644 }, - /*0387*/ { "smi", 387 }, - /*0388*/ { "smj", 388 }, - /*0389*/ { "smn", 389 }, - /*0390*/ { "smo", 649 }, - /*0391*/ { "sms", 391 }, - /*0392*/ { "sna", 650 }, - /*0393*/ { "snd", 643 }, - /*0394*/ { "snk", 394 }, - /*0395*/ { "sog", 395 }, - /*0396*/ { "som", 651 }, - /*0397*/ { "son", 397 }, - /*0398*/ { "sot", 655 }, - /*0399*/ { "spa", 543 }, - /*0400*/ { "srd", 642 }, - /*0401*/ { "srn", 401 }, - /*0402*/ { "srp", 653 }, - /*0403*/ { "srr", 403 }, - /*0404*/ { "ssa", 404 }, - /*0405*/ { "ssw", 654 }, - /*0406*/ { "suk", 406 }, - /*0407*/ { "sun", 656 }, - /*0408*/ { "sus", 408 }, - /*0409*/ { "sux", 409 }, - /*0410*/ { "swa", 658 }, - /*0411*/ { "swe", 657 }, - /*0412*/ { "syc", 412 }, - /*0413*/ { "syr", 413 }, - /*0414*/ { "tah", 672 }, - /*0415*/ { "tai", 415 }, - /*0416*/ { "tam", 659 }, - /*0417*/ { "tat", 670 }, - /*0418*/ { "tel", 660 }, - /*0419*/ { "tem", 419 }, - /*0420*/ { "ter", 420 }, - /*0421*/ { "tet", 421 }, - /*0422*/ { "tgk", 661 }, - /*0423*/ { "tgl", 665 }, - /*0424*/ { "tha", 662 }, - /*0425*/ { "tib", 484 }, - /*0426*/ { "tig", 426 }, - /*0427*/ { "tir", 663 }, - /*0428*/ { "tiv", 428 }, - /*0429*/ { "tkl", 429 }, - /*0430*/ { "tlh", 430 }, - /*0431*/ { "tli", 431 }, - /*0432*/ { "tmh", 432 }, - /*0433*/ { "tog", 433 }, - /*0434*/ { "ton", 667 }, - /*0435*/ { "tpi", 435 }, - /*0436*/ { "tsi", 436 }, - /*0437*/ { "tsn", 666 }, - /*0438*/ { "tso", 669 }, - /*0439*/ { "tuk", 664 }, - /*0440*/ { "tum", 440 }, - /*0441*/ { "tup", 441 }, - /*0442*/ { "tur", 668 }, - /*0443*/ { "tut", 443 }, - /*0444*/ { "tvl", 444 }, - /*0445*/ { "twi", 671 }, - /*0446*/ { "tyv", 446 }, - /*0447*/ { "udm", 447 }, - /*0448*/ { "uga", 448 }, - /*0449*/ { "uig", 673 }, - /*0450*/ { "ukr", 674 }, - /*0451*/ { "umb", 451 }, - /*0452*/ { "und", 452 }, - /*0453*/ { "urd", 675 }, - /*0454*/ { "uzb", 676 }, - /*0455*/ { "vai", 455 }, - /*0456*/ { "ven", 677 }, - /*0457*/ { "vie", 678 }, - /*0458*/ { "vol", 679 }, - /*0459*/ { "vot", 459 }, - /*0460*/ { "wak", 460 }, - /*0461*/ { "wal", 461 }, - /*0462*/ { "war", 462 }, - /*0463*/ { "was", 463 }, - /*0464*/ { "wel", 486 }, - /*0465*/ { "wen", 465 }, - /*0466*/ { "wln", 680 }, - /*0467*/ { "wol", 681 }, - /*0468*/ { "xal", 468 }, - /*0469*/ { "xho", 682 }, - /*0470*/ { "yao", 470 }, - /*0471*/ { "yap", 471 }, - /*0472*/ { "yid", 683 }, - /*0473*/ { "yor", 684 }, - /*0474*/ { "ypk", 474 }, - /*0475*/ { "zap", 475 }, - /*0476*/ { "zbl", 476 }, - /*0477*/ { "zen", 477 }, - /*0478*/ { "zha", 685 }, - /*0479*/ { "znd", 479 }, - /*0480*/ { "zul", 687 }, - /*0481*/ { "zun", 481 }, - /*0482*/ { "zxx", 482 }, - /*0483*/ { "zza", 483 }, - /*----- AV_LANG_ISO639_2_TERM entries (20) -----*/ - /*0484*/ { "bod", 523 }, - /*0485*/ { "ces", 531 }, - /*0486*/ { "cym", 534 }, - /*0487*/ { "deu", 536 }, - /*0488*/ { "ell", 540 }, - /*0489*/ { "eus", 545 }, - /*0490*/ { "fas", 546 }, - /*0491*/ { "fra", 551 }, - /*0492*/ { "hye", 566 }, - /*0493*/ { "isl", 575 }, - /*0494*/ { "kat", 580 }, - /*0495*/ { "mkd", 607 }, - /*0496*/ { "mri", 606 }, - /*0497*/ { "msa", 611 }, - /*0498*/ { "mya", 613 }, - /*0499*/ { "nld", 619 }, - /*0500*/ { "ron", 638 }, - /*0501*/ { "slk", 647 }, - /*0502*/ { "sqi", 652 }, - /*0503*/ { "zho", 686 }, - /*----- AV_LANG_ISO639_1 entries (184) -----*/ - /*0504*/ { "aa" , 0 }, - /*0505*/ { "ab" , 1 }, - /*0506*/ { "ae" , 33 }, - /*0507*/ { "af" , 8 }, - /*0508*/ { "ak" , 10 }, - /*0509*/ { "am" , 16 }, - /*0510*/ { "an" , 22 }, - /*0511*/ { "ar" , 20 }, - /*0512*/ { "as" , 28 }, - /*0513*/ { "av" , 32 }, - /*0514*/ { "ay" , 35 }, - /*0515*/ { "az" , 36 }, - /*0516*/ { "ba" , 39 }, - /*0517*/ { "be" , 47 }, - /*0518*/ { "bg" , 64 }, - /*0519*/ { "bh" , 52 }, - /*0520*/ { "bi" , 55 }, - /*0521*/ { "bm" , 41 }, - /*0522*/ { "bn" , 49 }, - /*0523*/ { "bo" , 425 }, - /*0524*/ { "br" , 60 }, - /*0525*/ { "bs" , 58 }, - /*0526*/ { "ca" , 70 }, - /*0527*/ { "ce" , 76 }, - /*0528*/ { "ch" , 74 }, - /*0529*/ { "co" , 91 }, - /*0530*/ { "cr" , 95 }, - /*0531*/ { "cs" , 100 }, - /*0532*/ { "cu" , 85 }, - /*0533*/ { "cv" , 86 }, - /*0534*/ { "cy" , 464 }, - /*0535*/ { "da" , 102 }, - /*0536*/ { "de" , 149 }, - /*0537*/ { "dv" , 109 }, - /*0538*/ { "dz" , 117 }, - /*0539*/ { "ee" , 126 }, - /*0540*/ { "el" , 163 }, - /*0541*/ { "en" , 122 }, - /*0542*/ { "eo" , 124 }, - /*0543*/ { "es" , 399 }, - /*0544*/ { "et" , 125 }, - /*0545*/ { "eu" , 43 }, - /*0546*/ { "fa" , 341 }, - /*0547*/ { "ff" , 142 }, - /*0548*/ { "fi" , 133 }, - /*0549*/ { "fj" , 131 }, - /*0550*/ { "fo" , 129 }, - /*0551*/ { "fr" , 136 }, - /*0552*/ { "fy" , 141 }, - /*0553*/ { "ga" , 153 }, - /*0554*/ { "gd" , 152 }, - /*0555*/ { "gl" , 154 }, - /*0556*/ { "gn" , 164 }, - /*0557*/ { "gu" , 166 }, - /*0558*/ { "gv" , 155 }, - /*0559*/ { "ha" , 170 }, - /*0560*/ { "he" , 172 }, - /*0561*/ { "hi" , 176 }, - /*0562*/ { "ho" , 179 }, - /*0563*/ { "hr" , 180 }, - /*0564*/ { "ht" , 169 }, - /*0565*/ { "hu" , 182 }, - /*0566*/ { "hy" , 23 }, - /*0567*/ { "hz" , 173 }, - /*0568*/ { "ia" , 193 }, - /*0569*/ { "id" , 195 }, - /*0570*/ { "ie" , 191 }, - /*0571*/ { "ig" , 185 }, - /*0572*/ { "ii" , 188 }, - /*0573*/ { "ik" , 198 }, - /*0574*/ { "io" , 187 }, - /*0575*/ { "is" , 186 }, - /*0576*/ { "it" , 201 }, - /*0577*/ { "iu" , 190 }, - /*0578*/ { "ja" , 204 }, - /*0579*/ { "jv" , 202 }, - /*0580*/ { "ka" , 148 }, - /*0581*/ { "kg" , 229 }, - /*0582*/ { "ki" , 223 }, - /*0583*/ { "kj" , 237 }, - /*0584*/ { "kk" , 217 }, - /*0585*/ { "kl" , 210 }, - /*0586*/ { "km" , 221 }, - /*0587*/ { "kn" , 212 }, - /*0588*/ { "ko" , 230 }, - /*0589*/ { "kr" , 215 }, - /*0590*/ { "ks" , 214 }, - /*0591*/ { "ku" , 239 }, - /*0592*/ { "kv" , 228 }, - /*0593*/ { "kw" , 90 }, - /*0594*/ { "ky" , 225 }, - /*0595*/ { "la" , 245 }, - /*0596*/ { "lb" , 253 }, - /*0597*/ { "lg" , 256 }, - /*0598*/ { "li" , 248 }, - /*0599*/ { "ln" , 249 }, - /*0600*/ { "lo" , 244 }, - /*0601*/ { "lt" , 250 }, - /*0602*/ { "lu" , 255 }, - /*0603*/ { "lv" , 246 }, - /*0604*/ { "mg" , 282 }, - /*0605*/ { "mh" , 264 }, - /*0606*/ { "mi" , 269 }, - /*0607*/ { "mk" , 261 }, - /*0608*/ { "ml" , 267 }, - /*0609*/ { "mn" , 288 }, - /*0610*/ { "mr" , 271 }, - /*0611*/ { "ms" , 273 }, - /*0612*/ { "mt" , 283 }, - /*0613*/ { "my" , 65 }, - /*0614*/ { "na" , 300 }, - /*0615*/ { "nb" , 312 }, - /*0616*/ { "nd" , 303 }, - /*0617*/ { "ne" , 306 }, - /*0618*/ { "ng" , 304 }, - /*0619*/ { "nl" , 115 }, - /*0620*/ { "nn" , 311 }, - /*0621*/ { "no" , 315 }, - /*0622*/ { "nr" , 302 }, - /*0623*/ { "nv" , 301 }, - /*0624*/ { "ny" , 320 }, - /*0625*/ { "oc" , 325 }, - /*0626*/ { "oj" , 326 }, - /*0627*/ { "om" , 328 }, - /*0628*/ { "or" , 327 }, - /*0629*/ { "os" , 330 }, - /*0630*/ { "pa" , 337 }, - /*0631*/ { "pi" , 344 }, - /*0632*/ { "pl" , 345 }, - /*0633*/ { "ps" , 350 }, - /*0634*/ { "pt" , 347 }, - /*0635*/ { "qu" , 351 }, - /*0636*/ { "rm" , 356 }, - /*0637*/ { "rn" , 359 }, - /*0638*/ { "ro" , 358 }, - /*0639*/ { "ru" , 361 }, - /*0640*/ { "rw" , 224 }, - /*0641*/ { "sa" , 368 }, - /*0642*/ { "sc" , 400 }, - /*0643*/ { "sd" , 393 }, - /*0644*/ { "se" , 386 }, - /*0645*/ { "sg" , 363 }, - /*0646*/ { "si" , 379 }, - /*0647*/ { "sk" , 383 }, - /*0648*/ { "sl" , 384 }, - /*0649*/ { "sm" , 390 }, - /*0650*/ { "sn" , 392 }, - /*0651*/ { "so" , 396 }, - /*0652*/ { "sq" , 12 }, - /*0653*/ { "sr" , 402 }, - /*0654*/ { "ss" , 405 }, - /*0655*/ { "st" , 398 }, - /*0656*/ { "su" , 407 }, - /*0657*/ { "sv" , 411 }, - /*0658*/ { "sw" , 410 }, - /*0659*/ { "ta" , 416 }, - /*0660*/ { "te" , 418 }, - /*0661*/ { "tg" , 422 }, - /*0662*/ { "th" , 424 }, - /*0663*/ { "ti" , 427 }, - /*0664*/ { "tk" , 439 }, - /*0665*/ { "tl" , 423 }, - /*0666*/ { "tn" , 437 }, - /*0667*/ { "to" , 434 }, - /*0668*/ { "tr" , 442 }, - /*0669*/ { "ts" , 438 }, - /*0670*/ { "tt" , 417 }, - /*0671*/ { "tw" , 445 }, - /*0672*/ { "ty" , 414 }, - /*0673*/ { "ug" , 449 }, - /*0674*/ { "uk" , 450 }, - /*0675*/ { "ur" , 453 }, - /*0676*/ { "uz" , 454 }, - /*0677*/ { "ve" , 456 }, - /*0678*/ { "vi" , 457 }, - /*0679*/ { "vo" , 458 }, - /*0680*/ { "wa" , 466 }, - /*0681*/ { "wo" , 467 }, - /*0682*/ { "xh" , 469 }, - /*0683*/ { "yi" , 472 }, - /*0684*/ { "yo" , 473 }, - /*0685*/ { "za" , 478 }, - /*0686*/ { "zh" , 78 }, - /*0687*/ { "zu" , 480 }, - { "", 0 } -}; - -static int lang_table_compare(const void *lhs, const void *rhs) -{ - return strcmp(lhs, ((const LangEntry *)rhs)->str); -} - -const char *av_convert_lang_to(const char *lang, enum AVLangCodespace target_codespace) -{ - int i; - const LangEntry *entry = NULL; - const int NB_CODESPACES = FF_ARRAY_ELEMS(lang_table_counts); - - if (target_codespace >= NB_CODESPACES) - return NULL; - - for (i=0; !entry && i= lang_table + lang_table_offsets[target_codespace] && - entry < lang_table + lang_table_offsets[target_codespace] + lang_table_counts[target_codespace]) - return entry->str; - else - entry = lang_table + entry->next_equivalent; - - if (target_codespace == AV_LANG_ISO639_2_TERM) - return av_convert_lang_to(lang, AV_LANG_ISO639_2_BIBL); - - return NULL; -} diff --git a/ffmpeg1/libavformat/avlanguage.h b/ffmpeg1/libavformat/avlanguage.h deleted file mode 100644 index 7fb8968..0000000 --- a/ffmpeg1/libavformat/avlanguage.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Cyril Comparon, Larbi Joubala, Resonate-MP4 2009 - * - * 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 AVFORMAT_AVLANGUAGE_H -#define AVFORMAT_AVLANGUAGE_H - -/** - * Known language codespaces - */ -enum AVLangCodespace { - AV_LANG_ISO639_2_BIBL, /** 3-char bibliographic language codes as per ISO-IEC 639-2 */ - AV_LANG_ISO639_2_TERM, /** 3-char terminologic language codes as per ISO-IEC 639-2 */ - AV_LANG_ISO639_1 /** 2-char code of language as per ISO/IEC 639-1 */ -}; - -/** - * Convert a language code to a target codespace. The source codespace is guessed. - * @return NULL if the provided lang is null or invalid. - */ -const char *av_convert_lang_to(const char *lang, enum AVLangCodespace target_codespace); - -#endif /* AVFORMAT_AVLANGUAGE_H */ diff --git a/ffmpeg1/libavformat/avr.c b/ffmpeg1/libavformat/avr.c deleted file mode 100644 index 473136e..0000000 --- a/ffmpeg1/libavformat/avr.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * AVR demuxer - * Copyright (c) 2012 Paul B Mahol - * - * 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 "libavutil/intreadwrite.h" -#include "avformat.h" -#include "internal.h" -#include "pcm.h" - -static int avr_probe(AVProbeData *p) -{ - if (AV_RL32(p->buf) == MKTAG('2', 'B', 'I', 'T')) - return AVPROBE_SCORE_MAX / 2; - return 0; -} - -static int avr_read_header(AVFormatContext *s) -{ - uint16_t chan, sign, bps; - AVStream *st; - - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - - avio_skip(s->pb, 4); // magic - avio_skip(s->pb, 8); // sample_name - - chan = avio_rb16(s->pb); - if (!chan) { - st->codec->channels = 1; - } else if (chan == 0xFFFFu) { - st->codec->channels = 2; - } else { - avpriv_request_sample(s, "chan %d", chan); - return AVERROR_PATCHWELCOME; - } - - st->codec->bits_per_coded_sample = bps = avio_rb16(s->pb); - - sign = avio_rb16(s->pb); - - avio_skip(s->pb, 2); // loop - avio_skip(s->pb, 2); // midi - avio_skip(s->pb, 1); // replay speed - - st->codec->sample_rate = avio_rb24(s->pb); - avio_skip(s->pb, 4 * 3); - avio_skip(s->pb, 2 * 3); - avio_skip(s->pb, 20); - avio_skip(s->pb, 64); - - if (!sign && bps == 8) { - st->codec->codec_id = AV_CODEC_ID_PCM_U8; - } else if (!sign && bps == 16) { - st->codec->codec_id = AV_CODEC_ID_PCM_U16BE; - } else if (sign == 0xFFFFu && bps == 8) { - st->codec->codec_id = AV_CODEC_ID_PCM_S8; - } else if (sign == 0xFFFFu && bps == 16) { - st->codec->codec_id = AV_CODEC_ID_PCM_S16BE; - } else { - avpriv_request_sample(s, "bits per sample %d", bps); - return AVERROR_PATCHWELCOME; - } - - st->codec->block_align = bps * st->codec->channels / 8; - - avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); - return 0; -} - -AVInputFormat ff_avr_demuxer = { - .name = "avr", - .long_name = NULL_IF_CONFIG_SMALL("AVR (Audio Visual Research)"), - .read_probe = avr_probe, - .read_header = avr_read_header, - .read_packet = ff_pcm_read_packet, - .read_seek = ff_pcm_read_seek, - .extensions = "avr", - .flags = AVFMT_GENERIC_INDEX, -}; diff --git a/ffmpeg1/libavformat/avs.c b/ffmpeg1/libavformat/avs.c deleted file mode 100644 index ec9198b..0000000 --- a/ffmpeg1/libavformat/avs.c +++ /dev/null @@ -1,232 +0,0 @@ -/* - * AVS demuxer. - * Copyright (c) 2006 Aurelien Jacobs - * - * 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 "voc.h" - - -typedef struct avs_format { - VocDecContext voc; - AVStream *st_video; - AVStream *st_audio; - int width; - int height; - int bits_per_sample; - int fps; - int nb_frames; - int remaining_frame_size; - int remaining_audio_size; -} AvsFormat; - -typedef enum avs_block_type { - AVS_NONE = 0x00, - AVS_VIDEO = 0x01, - AVS_AUDIO = 0x02, - AVS_PALETTE = 0x03, - AVS_GAME_DATA = 0x04, -} AvsBlockType; - -static int avs_probe(AVProbeData * p) -{ - const uint8_t *d; - - d = p->buf; - if (d[0] == 'w' && d[1] == 'W' && d[2] == 0x10 && d[3] == 0) - return 55; - - return 0; -} - -static int avs_read_header(AVFormatContext * s) -{ - AvsFormat *avs = s->priv_data; - - s->ctx_flags |= AVFMTCTX_NOHEADER; - - avio_skip(s->pb, 4); - avs->width = avio_rl16(s->pb); - avs->height = avio_rl16(s->pb); - avs->bits_per_sample = avio_rl16(s->pb); - avs->fps = avio_rl16(s->pb); - avs->nb_frames = avio_rl32(s->pb); - avs->remaining_frame_size = 0; - avs->remaining_audio_size = 0; - - avs->st_video = avs->st_audio = NULL; - - if (avs->width != 318 || avs->height != 198) - av_log(s, AV_LOG_ERROR, "This avs pretend to be %dx%d " - "when the avs format is supposed to be 318x198 only.\n", - avs->width, avs->height); - - return 0; -} - -static int -avs_read_video_packet(AVFormatContext * s, AVPacket * pkt, - AvsBlockType type, int sub_type, int size, - uint8_t * palette, int palette_size) -{ - AvsFormat *avs = s->priv_data; - int ret; - - ret = av_new_packet(pkt, size + palette_size); - if (ret < 0) - return ret; - - if (palette_size) { - pkt->data[0] = 0x00; - pkt->data[1] = 0x03; - pkt->data[2] = palette_size & 0xFF; - pkt->data[3] = (palette_size >> 8) & 0xFF; - memcpy(pkt->data + 4, palette, palette_size - 4); - } - - pkt->data[palette_size + 0] = sub_type; - pkt->data[palette_size + 1] = type; - pkt->data[palette_size + 2] = size & 0xFF; - pkt->data[palette_size + 3] = (size >> 8) & 0xFF; - ret = avio_read(s->pb, pkt->data + palette_size + 4, size - 4) + 4; - if (ret < size) { - av_free_packet(pkt); - return AVERROR(EIO); - } - - pkt->size = ret + palette_size; - pkt->stream_index = avs->st_video->index; - if (sub_type == 0) - pkt->flags |= AV_PKT_FLAG_KEY; - - return 0; -} - -static int avs_read_audio_packet(AVFormatContext * s, AVPacket * pkt) -{ - AvsFormat *avs = s->priv_data; - int ret, size; - - size = avio_tell(s->pb); - ret = ff_voc_get_packet(s, pkt, avs->st_audio, avs->remaining_audio_size); - size = avio_tell(s->pb) - size; - avs->remaining_audio_size -= size; - - if (ret == AVERROR(EIO)) - return 0; /* this indicate EOS */ - if (ret < 0) - return ret; - - pkt->stream_index = avs->st_audio->index; - pkt->flags |= AV_PKT_FLAG_KEY; - - return size; -} - -static int avs_read_packet(AVFormatContext * s, AVPacket * pkt) -{ - AvsFormat *avs = s->priv_data; - int sub_type = 0, size = 0; - AvsBlockType type = AVS_NONE; - int palette_size = 0; - uint8_t palette[4 + 3 * 256]; - int ret; - - if (avs->remaining_audio_size > 0) - if (avs_read_audio_packet(s, pkt) > 0) - return 0; - - while (1) { - if (avs->remaining_frame_size <= 0) { - if (!avio_rl16(s->pb)) /* found EOF */ - return AVERROR(EIO); - avs->remaining_frame_size = avio_rl16(s->pb) - 4; - } - - while (avs->remaining_frame_size > 0) { - sub_type = avio_r8(s->pb); - type = avio_r8(s->pb); - size = avio_rl16(s->pb); - if (size < 4) - return AVERROR_INVALIDDATA; - avs->remaining_frame_size -= size; - - switch (type) { - case AVS_PALETTE: - if (size - 4 > sizeof(palette)) - return AVERROR_INVALIDDATA; - ret = avio_read(s->pb, palette, size - 4); - if (ret < size - 4) - return AVERROR(EIO); - palette_size = size; - break; - - case AVS_VIDEO: - if (!avs->st_video) { - avs->st_video = avformat_new_stream(s, NULL); - if (avs->st_video == NULL) - return AVERROR(ENOMEM); - avs->st_video->codec->codec_type = AVMEDIA_TYPE_VIDEO; - avs->st_video->codec->codec_id = AV_CODEC_ID_AVS; - avs->st_video->codec->width = avs->width; - avs->st_video->codec->height = avs->height; - avs->st_video->codec->bits_per_coded_sample=avs->bits_per_sample; - avs->st_video->nb_frames = avs->nb_frames; -#if FF_API_R_FRAME_RATE - avs->st_video->r_frame_rate = -#endif - avs->st_video->avg_frame_rate = (AVRational){avs->fps, 1}; - } - return avs_read_video_packet(s, pkt, type, sub_type, size, - palette, palette_size); - - case AVS_AUDIO: - if (!avs->st_audio) { - avs->st_audio = avformat_new_stream(s, NULL); - if (avs->st_audio == NULL) - return AVERROR(ENOMEM); - avs->st_audio->codec->codec_type = AVMEDIA_TYPE_AUDIO; - } - avs->remaining_audio_size = size - 4; - size = avs_read_audio_packet(s, pkt); - if (size != 0) - return size; - break; - - default: - avio_skip(s->pb, size - 4); - } - } - } -} - -static int avs_read_close(AVFormatContext * s) -{ - return 0; -} - -AVInputFormat ff_avs_demuxer = { - .name = "avs", - .long_name = NULL_IF_CONFIG_SMALL("AVS"), - .priv_data_size = sizeof(AvsFormat), - .read_probe = avs_probe, - .read_header = avs_read_header, - .read_packet = avs_read_packet, - .read_close = avs_read_close, -}; diff --git a/ffmpeg1/libavformat/bethsoftvid.c b/ffmpeg1/libavformat/bethsoftvid.c deleted file mode 100644 index b8f08c1..0000000 --- a/ffmpeg1/libavformat/bethsoftvid.c +++ /dev/null @@ -1,296 +0,0 @@ -/* - * Bethsoft VID format Demuxer - * Copyright (c) 2007 Nicholas Tung - * - * 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 - */ - -/** - * @file - * @brief Bethesda Softworks VID (.vid) file demuxer - * @author Nicholas Tung [ntung (at. ntung com] (2007-03) - * @see http://wiki.multimedia.cx/index.php?title=Bethsoft_VID - * @see http://www.svatopluk.com/andux/docs/dfvid.html - */ - -#include "libavutil/channel_layout.h" -#include "libavutil/intreadwrite.h" -#include "avformat.h" -#include "internal.h" -#include "libavcodec/bethsoftvideo.h" - -#define BVID_PALETTE_SIZE 3 * 256 - -#define DEFAULT_SAMPLE_RATE 11111 - -typedef struct BVID_DemuxContext -{ - int nframes; - int sample_rate; /**< audio sample rate */ - int width; /**< video width */ - int height; /**< video height */ - /** delay value between frames, added to individual frame delay. - * custom units, which will be added to other custom units (~=16ms according - * to free, unofficial documentation) */ - int bethsoft_global_delay; - int video_index; /**< video stream index */ - int audio_index; /**< audio stream index */ - uint8_t *palette; - - int is_finished; - -} BVID_DemuxContext; - -static int vid_probe(AVProbeData *p) -{ - // little-endian VID tag, file starts with "VID\0" - if (AV_RL32(p->buf) != MKTAG('V', 'I', 'D', 0)) - return 0; - - return AVPROBE_SCORE_MAX; -} - -static int vid_read_header(AVFormatContext *s) -{ - BVID_DemuxContext *vid = s->priv_data; - AVIOContext *pb = s->pb; - - /* load main header. Contents: - * bytes: 'V' 'I' 'D' - * int16s: always_512, nframes, width, height, delay, always_14 - */ - avio_skip(pb, 5); - vid->nframes = avio_rl16(pb); - vid->width = avio_rl16(pb); - vid->height = avio_rl16(pb); - vid->bethsoft_global_delay = avio_rl16(pb); - avio_rl16(pb); - - // wait until the first packet to create each stream - vid->video_index = -1; - vid->audio_index = -1; - vid->sample_rate = DEFAULT_SAMPLE_RATE; - s->ctx_flags |= AVFMTCTX_NOHEADER; - - return 0; -} - -#define BUFFER_PADDING_SIZE 1000 -static int read_frame(BVID_DemuxContext *vid, AVIOContext *pb, AVPacket *pkt, - uint8_t block_type, AVFormatContext *s) -{ - uint8_t * vidbuf_start = NULL; - int vidbuf_nbytes = 0; - int code; - int bytes_copied = 0; - int position, duration, npixels; - unsigned int vidbuf_capacity; - int ret = 0; - AVStream *st; - - if (vid->video_index < 0) { - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - vid->video_index = st->index; - if (vid->audio_index < 0) { - avpriv_request_sample(s, "Using default video time base since " - "having no audio packet before the first " - "video packet"); - } - avpriv_set_pts_info(st, 64, 185, vid->sample_rate); - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = AV_CODEC_ID_BETHSOFTVID; - st->codec->width = vid->width; - st->codec->height = vid->height; - } - st = s->streams[vid->video_index]; - npixels = st->codec->width * st->codec->height; - - vidbuf_start = av_malloc(vidbuf_capacity = BUFFER_PADDING_SIZE); - if(!vidbuf_start) - return AVERROR(ENOMEM); - - // save the file position for the packet, include block type - position = avio_tell(pb) - 1; - - vidbuf_start[vidbuf_nbytes++] = block_type; - - // get the current packet duration - duration = vid->bethsoft_global_delay + avio_rl16(pb); - - // set the y offset if it exists (decoder header data should be in data section) - if(block_type == VIDEO_YOFF_P_FRAME){ - if (avio_read(pb, &vidbuf_start[vidbuf_nbytes], 2) != 2) { - ret = AVERROR(EIO); - goto fail; - } - vidbuf_nbytes += 2; - } - - do{ - vidbuf_start = av_fast_realloc(vidbuf_start, &vidbuf_capacity, vidbuf_nbytes + BUFFER_PADDING_SIZE); - if(!vidbuf_start) - return AVERROR(ENOMEM); - - code = avio_r8(pb); - vidbuf_start[vidbuf_nbytes++] = code; - - if(code >= 0x80){ // rle sequence - if(block_type == VIDEO_I_FRAME) - vidbuf_start[vidbuf_nbytes++] = avio_r8(pb); - } else if(code){ // plain sequence - if (avio_read(pb, &vidbuf_start[vidbuf_nbytes], code) != code) { - ret = AVERROR(EIO); - goto fail; - } - vidbuf_nbytes += code; - } - bytes_copied += code & 0x7F; - if(bytes_copied == npixels){ // sometimes no stop character is given, need to keep track of bytes copied - // may contain a 0 byte even if read all pixels - if(avio_r8(pb)) - avio_seek(pb, -1, SEEK_CUR); - break; - } - if (bytes_copied > npixels) { - ret = AVERROR_INVALIDDATA; - goto fail; - } - } while(code); - - // copy data into packet - if ((ret = av_new_packet(pkt, vidbuf_nbytes)) < 0) - goto fail; - memcpy(pkt->data, vidbuf_start, vidbuf_nbytes); - av_free(vidbuf_start); - - pkt->pos = position; - pkt->stream_index = vid->video_index; - pkt->duration = duration; - if (block_type == VIDEO_I_FRAME) - pkt->flags |= AV_PKT_FLAG_KEY; - - /* if there is a new palette available, add it to packet side data */ - if (vid->palette) { - uint8_t *pdata = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, - BVID_PALETTE_SIZE); - if (pdata) - memcpy(pdata, vid->palette, BVID_PALETTE_SIZE); - av_freep(&vid->palette); - } - - vid->nframes--; // used to check if all the frames were read - return 0; -fail: - av_free(vidbuf_start); - return ret; -} - -static int vid_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - BVID_DemuxContext *vid = s->priv_data; - AVIOContext *pb = s->pb; - unsigned char block_type; - int audio_length; - int ret_value; - - if(vid->is_finished || url_feof(pb)) - return AVERROR_EOF; - - block_type = avio_r8(pb); - switch(block_type){ - case PALETTE_BLOCK: - if (vid->palette) { - av_log(s, AV_LOG_WARNING, "discarding unused palette\n"); - av_freep(&vid->palette); - } - vid->palette = av_malloc(BVID_PALETTE_SIZE); - if (!vid->palette) - return AVERROR(ENOMEM); - if (avio_read(pb, vid->palette, BVID_PALETTE_SIZE) != BVID_PALETTE_SIZE) { - av_freep(&vid->palette); - return AVERROR(EIO); - } - return vid_read_packet(s, pkt); - - case FIRST_AUDIO_BLOCK: - avio_rl16(pb); - // soundblaster DAC used for sample rate, as on specification page (link above) - vid->sample_rate = 1000000 / (256 - avio_r8(pb)); - case AUDIO_BLOCK: - if (vid->audio_index < 0) { - AVStream *st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - vid->audio_index = st->index; - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = AV_CODEC_ID_PCM_U8; - st->codec->channels = 1; - st->codec->channel_layout = AV_CH_LAYOUT_MONO; - st->codec->bits_per_coded_sample = 8; - st->codec->sample_rate = vid->sample_rate; - st->codec->bit_rate = 8 * st->codec->sample_rate; - st->start_time = 0; - avpriv_set_pts_info(st, 64, 1, vid->sample_rate); - } - audio_length = avio_rl16(pb); - if ((ret_value = av_get_packet(pb, pkt, audio_length)) != audio_length) { - if (ret_value < 0) - return ret_value; - av_log(s, AV_LOG_ERROR, "incomplete audio block\n"); - return AVERROR(EIO); - } - pkt->stream_index = vid->audio_index; - pkt->duration = audio_length; - pkt->flags |= AV_PKT_FLAG_KEY; - return 0; - - case VIDEO_P_FRAME: - case VIDEO_YOFF_P_FRAME: - case VIDEO_I_FRAME: - return read_frame(vid, pb, pkt, block_type, s); - - case EOF_BLOCK: - if(vid->nframes != 0) - av_log(s, AV_LOG_VERBOSE, "reached terminating character but not all frames read.\n"); - vid->is_finished = 1; - return AVERROR(EIO); - default: - av_log(s, AV_LOG_ERROR, "unknown block (character = %c, decimal = %d, hex = %x)!!!\n", - block_type, block_type, block_type); - return AVERROR_INVALIDDATA; - } -} - -static int vid_read_close(AVFormatContext *s) -{ - BVID_DemuxContext *vid = s->priv_data; - av_freep(&vid->palette); - return 0; -} - -AVInputFormat ff_bethsoftvid_demuxer = { - .name = "bethsoftvid", - .long_name = NULL_IF_CONFIG_SMALL("Bethesda Softworks VID"), - .priv_data_size = sizeof(BVID_DemuxContext), - .read_probe = vid_probe, - .read_header = vid_read_header, - .read_packet = vid_read_packet, - .read_close = vid_read_close, -}; diff --git a/ffmpeg1/libavformat/bfi.c b/ffmpeg1/libavformat/bfi.c deleted file mode 100644 index a28e09a..0000000 --- a/ffmpeg1/libavformat/bfi.c +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Brute Force & Ignorance (BFI) demuxer - * Copyright (c) 2008 Sisir Koppaka - * - * 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 - */ - -/** - * @file - * @brief Brute Force & Ignorance (.bfi) file demuxer - * @author Sisir Koppaka ( sisir.koppaka at gmail dot com ) - * @see http://wiki.multimedia.cx/index.php?title=BFI - */ - -#include "libavutil/channel_layout.h" -#include "libavutil/intreadwrite.h" -#include "avformat.h" -#include "internal.h" - -typedef struct BFIContext { - int nframes; - int audio_frame; - int video_frame; - int video_size; - int avflag; -} BFIContext; - -static int bfi_probe(AVProbeData * p) -{ - /* Check file header */ - if (AV_RL32(p->buf) == MKTAG('B', 'F', '&', 'I')) - return AVPROBE_SCORE_MAX; - else - return 0; -} - -static int bfi_read_header(AVFormatContext * s) -{ - BFIContext *bfi = s->priv_data; - AVIOContext *pb = s->pb; - AVStream *vstream; - AVStream *astream; - int fps, chunk_header; - - /* Initialize the video codec... */ - vstream = avformat_new_stream(s, NULL); - if (!vstream) - return AVERROR(ENOMEM); - - /* Initialize the audio codec... */ - astream = avformat_new_stream(s, NULL); - if (!astream) - return AVERROR(ENOMEM); - - /* Set the total number of frames. */ - avio_skip(pb, 8); - chunk_header = avio_rl32(pb); - bfi->nframes = avio_rl32(pb); - avio_rl32(pb); - avio_rl32(pb); - avio_rl32(pb); - fps = avio_rl32(pb); - avio_skip(pb, 12); - vstream->codec->width = avio_rl32(pb); - vstream->codec->height = avio_rl32(pb); - - /*Load the palette to extradata */ - avio_skip(pb, 8); - vstream->codec->extradata = av_malloc(768); - vstream->codec->extradata_size = 768; - avio_read(pb, vstream->codec->extradata, - vstream->codec->extradata_size); - - astream->codec->sample_rate = avio_rl32(pb); - - /* Set up the video codec... */ - avpriv_set_pts_info(vstream, 32, 1, fps); - vstream->codec->codec_type = AVMEDIA_TYPE_VIDEO; - vstream->codec->codec_id = AV_CODEC_ID_BFI; - vstream->codec->pix_fmt = AV_PIX_FMT_PAL8; - vstream->nb_frames = - vstream->duration = bfi->nframes; - - /* Set up the audio codec now... */ - astream->codec->codec_type = AVMEDIA_TYPE_AUDIO; - astream->codec->codec_id = AV_CODEC_ID_PCM_U8; - astream->codec->channels = 1; - astream->codec->channel_layout = AV_CH_LAYOUT_MONO; - astream->codec->bits_per_coded_sample = 8; - astream->codec->bit_rate = - astream->codec->sample_rate * astream->codec->bits_per_coded_sample; - avio_seek(pb, chunk_header - 3, SEEK_SET); - avpriv_set_pts_info(astream, 64, 1, astream->codec->sample_rate); - return 0; -} - - -static int bfi_read_packet(AVFormatContext * s, AVPacket * pkt) -{ - BFIContext *bfi = s->priv_data; - AVIOContext *pb = s->pb; - int ret, audio_offset, video_offset, chunk_size, audio_size = 0; - if (bfi->nframes == 0 || url_feof(pb)) { - return AVERROR_EOF; - } - - /* If all previous chunks were completely read, then find a new one... */ - if (!bfi->avflag) { - uint32_t state = 0; - while(state != MKTAG('S','A','V','I')){ - if (url_feof(pb)) - return AVERROR(EIO); - state = 256*state + avio_r8(pb); - } - /* Now that the chunk's location is confirmed, we proceed... */ - chunk_size = avio_rl32(pb); - avio_rl32(pb); - audio_offset = avio_rl32(pb); - avio_rl32(pb); - video_offset = avio_rl32(pb); - audio_size = video_offset - audio_offset; - bfi->video_size = chunk_size - video_offset; - - //Tossing an audio packet at the audio decoder. - ret = av_get_packet(pb, pkt, audio_size); - if (ret < 0) - return ret; - - pkt->pts = bfi->audio_frame; - bfi->audio_frame += ret; - } - - else { - - //Tossing a video packet at the video decoder. - ret = av_get_packet(pb, pkt, bfi->video_size); - if (ret < 0) - return ret; - - pkt->pts = bfi->video_frame; - bfi->video_frame += bfi->video_size ? ret / bfi->video_size : 1; - - /* One less frame to read. A cursory decrement. */ - bfi->nframes--; - } - - bfi->avflag = !bfi->avflag; - pkt->stream_index = bfi->avflag; - return ret; -} - -AVInputFormat ff_bfi_demuxer = { - .name = "bfi", - .long_name = NULL_IF_CONFIG_SMALL("Brute Force & Ignorance"), - .priv_data_size = sizeof(BFIContext), - .read_probe = bfi_probe, - .read_header = bfi_read_header, - .read_packet = bfi_read_packet, -}; diff --git a/ffmpeg1/libavformat/bink.c b/ffmpeg1/libavformat/bink.c deleted file mode 100644 index 887f70a..0000000 --- a/ffmpeg1/libavformat/bink.c +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Bink demuxer - * Copyright (c) 2008-2010 Peter Ross (pross@xvid.org) - * Copyright (c) 2009 Daniel Verkamp (daniel@drv.nu) - * - * 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 - */ - -/** - * @file - * Bink demuxer - * - * Technical details here: - * http://wiki.multimedia.cx/index.php?title=Bink_Container - */ - -#include "libavutil/channel_layout.h" -#include "libavutil/intreadwrite.h" -#include "avformat.h" -#include "internal.h" - -enum BinkAudFlags { - BINK_AUD_16BITS = 0x4000, ///< prefer 16-bit output - BINK_AUD_STEREO = 0x2000, - BINK_AUD_USEDCT = 0x1000, -}; - -#define BINK_EXTRADATA_SIZE 1 -#define BINK_MAX_AUDIO_TRACKS 256 -#define BINK_MAX_WIDTH 7680 -#define BINK_MAX_HEIGHT 4800 - -typedef struct { - uint32_t file_size; - - uint32_t num_audio_tracks; - int current_track; ///< audio track to return in next packet - int64_t video_pts; - int64_t audio_pts[BINK_MAX_AUDIO_TRACKS]; - - uint32_t remain_packet_size; -} BinkDemuxContext; - -static int probe(AVProbeData *p) -{ - const uint8_t *b = p->buf; - - if ( b[0] == 'B' && b[1] == 'I' && b[2] == 'K' && - (b[3] == 'b' || b[3] == 'f' || b[3] == 'g' || b[3] == 'h' || b[3] == 'i') && - AV_RL32(b+8) > 0 && // num_frames - AV_RL32(b+20) > 0 && AV_RL32(b+20) <= BINK_MAX_WIDTH && - AV_RL32(b+24) > 0 && AV_RL32(b+24) <= BINK_MAX_HEIGHT && - AV_RL32(b+28) > 0 && AV_RL32(b+32) > 0) // fps num,den - return AVPROBE_SCORE_MAX; - return 0; -} - -static int read_header(AVFormatContext *s) -{ - BinkDemuxContext *bink = s->priv_data; - AVIOContext *pb = s->pb; - uint32_t fps_num, fps_den; - AVStream *vst, *ast; - unsigned int i; - uint32_t pos, next_pos; - uint16_t flags; - int keyframe; - - vst = avformat_new_stream(s, NULL); - if (!vst) - return AVERROR(ENOMEM); - - vst->codec->codec_tag = avio_rl32(pb); - - bink->file_size = avio_rl32(pb) + 8; - vst->duration = avio_rl32(pb); - - if (vst->duration > 1000000) { - av_log(s, AV_LOG_ERROR, "invalid header: more than 1000000 frames\n"); - return AVERROR(EIO); - } - - if (avio_rl32(pb) > bink->file_size) { - av_log(s, AV_LOG_ERROR, - "invalid header: largest frame size greater than file size\n"); - return AVERROR(EIO); - } - - avio_skip(pb, 4); - - vst->codec->width = avio_rl32(pb); - vst->codec->height = avio_rl32(pb); - - fps_num = avio_rl32(pb); - fps_den = avio_rl32(pb); - if (fps_num == 0 || fps_den == 0) { - av_log(s, AV_LOG_ERROR, "invalid header: invalid fps (%d/%d)\n", fps_num, fps_den); - return AVERROR(EIO); - } - avpriv_set_pts_info(vst, 64, fps_den, fps_num); - vst->avg_frame_rate = av_inv_q(vst->time_base); - - vst->codec->codec_type = AVMEDIA_TYPE_VIDEO; - vst->codec->codec_id = AV_CODEC_ID_BINKVIDEO; - vst->codec->extradata = av_mallocz(4 + FF_INPUT_BUFFER_PADDING_SIZE); - if (!vst->codec->extradata) - return AVERROR(ENOMEM); - vst->codec->extradata_size = 4; - avio_read(pb, vst->codec->extradata, 4); - - bink->num_audio_tracks = avio_rl32(pb); - - if (bink->num_audio_tracks > BINK_MAX_AUDIO_TRACKS) { - av_log(s, AV_LOG_ERROR, - "invalid header: more than "AV_STRINGIFY(BINK_MAX_AUDIO_TRACKS)" audio tracks (%d)\n", - bink->num_audio_tracks); - return AVERROR(EIO); - } - - if (bink->num_audio_tracks) { - avio_skip(pb, 4 * bink->num_audio_tracks); - - for (i = 0; i < bink->num_audio_tracks; i++) { - ast = avformat_new_stream(s, NULL); - if (!ast) - return AVERROR(ENOMEM); - ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; - ast->codec->codec_tag = 0; - ast->codec->sample_rate = avio_rl16(pb); - avpriv_set_pts_info(ast, 64, 1, ast->codec->sample_rate); - flags = avio_rl16(pb); - ast->codec->codec_id = flags & BINK_AUD_USEDCT ? - AV_CODEC_ID_BINKAUDIO_DCT : AV_CODEC_ID_BINKAUDIO_RDFT; - if (flags & BINK_AUD_STEREO) { - ast->codec->channels = 2; - ast->codec->channel_layout = AV_CH_LAYOUT_STEREO; - } else { - ast->codec->channels = 1; - ast->codec->channel_layout = AV_CH_LAYOUT_MONO; - } - ast->codec->extradata = av_mallocz(4 + FF_INPUT_BUFFER_PADDING_SIZE); - if (!ast->codec->extradata) - return AVERROR(ENOMEM); - ast->codec->extradata_size = 4; - AV_WL32(ast->codec->extradata, vst->codec->codec_tag); - } - - for (i = 0; i < bink->num_audio_tracks; i++) - s->streams[i + 1]->id = avio_rl32(pb); - } - - /* frame index table */ - next_pos = avio_rl32(pb); - for (i = 0; i < vst->duration; i++) { - pos = next_pos; - if (i == vst->duration - 1) { - next_pos = bink->file_size; - keyframe = 0; - } else { - next_pos = avio_rl32(pb); - keyframe = pos & 1; - } - pos &= ~1; - next_pos &= ~1; - - if (next_pos <= pos) { - av_log(s, AV_LOG_ERROR, "invalid frame index table\n"); - return AVERROR(EIO); - } - av_add_index_entry(vst, pos, i, next_pos - pos, 0, - keyframe ? AVINDEX_KEYFRAME : 0); - } - - avio_skip(pb, 4); - - bink->current_track = -1; - return 0; -} - -static int read_packet(AVFormatContext *s, AVPacket *pkt) -{ - BinkDemuxContext *bink = s->priv_data; - AVIOContext *pb = s->pb; - int ret; - - if (bink->current_track < 0) { - int index_entry; - AVStream *st = s->streams[0]; // stream 0 is video stream with index - - if (bink->video_pts >= st->duration) - return AVERROR_EOF; - - index_entry = av_index_search_timestamp(st, bink->video_pts, - AVSEEK_FLAG_ANY); - if (index_entry < 0) { - av_log(s, AV_LOG_ERROR, - "could not find index entry for frame %"PRId64"\n", - bink->video_pts); - return AVERROR(EIO); - } - - bink->remain_packet_size = st->index_entries[index_entry].size; - bink->current_track = 0; - } - - while (bink->current_track < bink->num_audio_tracks) { - uint32_t audio_size = avio_rl32(pb); - if (audio_size > bink->remain_packet_size - 4) { - av_log(s, AV_LOG_ERROR, - "frame %"PRId64": audio size in header (%u) > size of packet left (%u)\n", - bink->video_pts, audio_size, bink->remain_packet_size); - return AVERROR(EIO); - } - bink->remain_packet_size -= 4 + audio_size; - bink->current_track++; - if (audio_size >= 4) { - /* get one audio packet per track */ - if ((ret = av_get_packet(pb, pkt, audio_size)) < 0) - return ret; - pkt->stream_index = bink->current_track; - pkt->pts = bink->audio_pts[bink->current_track - 1]; - - /* Each audio packet reports the number of decompressed samples - (in bytes). We use this value to calcuate the audio PTS */ - if (pkt->size >= 4) - bink->audio_pts[bink->current_track -1] += - AV_RL32(pkt->data) / (2 * s->streams[bink->current_track]->codec->channels); - return 0; - } else { - avio_skip(pb, audio_size); - } - } - - /* get video packet */ - if ((ret = av_get_packet(pb, pkt, bink->remain_packet_size)) < 0) - return ret; - pkt->stream_index = 0; - pkt->pts = bink->video_pts++; - pkt->flags |= AV_PKT_FLAG_KEY; - - /* -1 instructs the next call to read_packet() to read the next frame */ - bink->current_track = -1; - - return 0; -} - -static int read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) -{ - BinkDemuxContext *bink = s->priv_data; - AVStream *vst = s->streams[0]; - - if (!s->pb->seekable) - return -1; - - /* seek to the first frame */ - if (avio_seek(s->pb, vst->index_entries[0].pos, SEEK_SET) < 0) - return -1; - - bink->video_pts = 0; - memset(bink->audio_pts, 0, sizeof(bink->audio_pts)); - bink->current_track = -1; - return 0; -} - -AVInputFormat ff_bink_demuxer = { - .name = "bink", - .long_name = NULL_IF_CONFIG_SMALL("Bink"), - .priv_data_size = sizeof(BinkDemuxContext), - .read_probe = probe, - .read_header = read_header, - .read_packet = read_packet, - .read_seek = read_seek, -}; diff --git a/ffmpeg1/libavformat/bintext.c b/ffmpeg1/libavformat/bintext.c deleted file mode 100644 index 91f95f3..0000000 --- a/ffmpeg1/libavformat/bintext.c +++ /dev/null @@ -1,409 +0,0 @@ -/* - * Binary text demuxer - * eXtended BINary text (XBIN) demuxer - * Artworx Data Format demuxer - * iCEDraw File demuxer - * Copyright (c) 2010 Peter Ross - * - * 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 - */ - -/** - * @file - * Binary text demuxer - * eXtended BINary text (XBIN) demuxer - * Artworx Data Format demuxer - * iCEDraw File demuxer - */ - -#include "libavutil/intreadwrite.h" -#include "libavutil/opt.h" -#include "libavutil/parseutils.h" -#include "avformat.h" -#include "internal.h" -#include "sauce.h" -#include "libavcodec/bintext.h" - -typedef struct { - const AVClass *class; - int chars_per_frame; /**< characters to send decoder per frame; - set by private options as characters per second, and then - converted to characters per frame at runtime */ - char *video_size; /**< video size (WxH pixels) (private option) */ - char *framerate; /**< frames per second (private option) */ - uint64_t fsize; /**< file size less metadata buffer */ -} BinDemuxContext; - -static AVStream * init_stream(AVFormatContext *s) -{ - BinDemuxContext *bin = s->priv_data; - AVStream *st = avformat_new_stream(s, NULL); - if (!st) - return NULL; - st->codec->codec_tag = 0; - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - - if (bin->video_size) { - if (av_parse_video_size(&st->codec->width, &st->codec->height, bin->video_size) < 0) { - av_log(s, AV_LOG_ERROR, "Could not parse video size: '%s'\n", bin->video_size); - return NULL; - } - } else { - st->codec->width = (80<<3); - st->codec->height = (25<<4); - } - - if (bin->framerate) { - AVRational framerate; - if (av_parse_video_rate(&framerate, bin->framerate) < 0) { - av_log(s, AV_LOG_ERROR, "Could not parse framerate: '%s'\n", bin->framerate); - return NULL; - } - avpriv_set_pts_info(st, 60, framerate.den, framerate.num); - } else { - avpriv_set_pts_info(st, 60, 1, 25); - } - - /* simulate tty display speed */ - bin->chars_per_frame = FFMAX(av_q2d(st->time_base) * bin->chars_per_frame, 1); - - return st; -} - -#if CONFIG_BINTEXT_DEMUXER | CONFIG_ADF_DEMUXER | CONFIG_IDF_DEMUXER -/** - * Given filesize and width, calculate height (assume font_height of 16) - */ -static void calculate_height(AVCodecContext *avctx, uint64_t fsize) -{ - avctx->height = (fsize / ((avctx->width>>3)*2)) << 4; -} -#endif - -#if CONFIG_BINTEXT_DEMUXER -static const uint8_t next_magic[]={ - 0x1A, 0x1B, '[', '0', ';', '3', '0', ';', '4', '0', 'm', 'N', 'E', 'X', 'T', 0x00 -}; - -static int next_tag_read(AVFormatContext *avctx, uint64_t *fsize) -{ - AVIOContext *pb = avctx->pb; - char buf[36]; - int len; - uint64_t start_pos = avio_size(pb) - 256; - - avio_seek(pb, start_pos, SEEK_SET); - if (avio_read(pb, buf, sizeof(next_magic)) != sizeof(next_magic)) - return -1; - if (memcmp(buf, next_magic, sizeof(next_magic))) - return -1; - if (avio_r8(pb) != 0x01) - return -1; - - *fsize -= 256; - -#define GET_EFI2_META(name,size) \ - len = avio_r8(pb); \ - if (len < 1 || len > size) \ - return -1; \ - if (avio_read(pb, buf, size) == size && *buf) { \ - buf[len] = 0; \ - av_dict_set(&avctx->metadata, name, buf, 0); \ - } - - GET_EFI2_META("filename", 12) - GET_EFI2_META("author", 20) - GET_EFI2_META("publisher", 20) - GET_EFI2_META("title", 35) - - return 0; -} - -static void predict_width(AVCodecContext *avctx, uint64_t fsize, int got_width) -{ - /** attempt to guess width */ - if (!got_width) - avctx->width = fsize > 4000 ? (160<<3) : (80<<3); -} - -static int bintext_read_header(AVFormatContext *s) -{ - BinDemuxContext *bin = s->priv_data; - AVIOContext *pb = s->pb; - - AVStream *st = init_stream(s); - if (!st) - return AVERROR(ENOMEM); - st->codec->codec_id = AV_CODEC_ID_BINTEXT; - - st->codec->extradata_size = 2; - st->codec->extradata = av_malloc(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!st->codec->extradata) - return AVERROR(ENOMEM); - st->codec->extradata[0] = 16; - st->codec->extradata[1] = 0; - - if (pb->seekable) { - int got_width = 0; - bin->fsize = avio_size(pb); - if (ff_sauce_read(s, &bin->fsize, &got_width, 0) < 0) - next_tag_read(s, &bin->fsize); - if (!bin->video_size) { - predict_width(st->codec, bin->fsize, got_width); - calculate_height(st->codec, bin->fsize); - } - avio_seek(pb, 0, SEEK_SET); - } - return 0; -} -#endif /* CONFIG_BINTEXT_DEMUXER */ - -#if CONFIG_XBIN_DEMUXER -static int xbin_probe(AVProbeData *p) -{ - const uint8_t *d = p->buf; - - if (AV_RL32(d) == MKTAG('X','B','I','N') && d[4] == 0x1A && - AV_RL16(d+5) > 0 && AV_RL16(d+5) <= 160 && - d[9] > 0 && d[9] <= 32) - return AVPROBE_SCORE_MAX; - return 0; -} - -static int xbin_read_header(AVFormatContext *s) -{ - BinDemuxContext *bin = s->priv_data; - AVIOContext *pb = s->pb; - char fontheight, flags; - - AVStream *st = init_stream(s); - if (!st) - return AVERROR(ENOMEM); - - avio_skip(pb, 5); - st->codec->width = avio_rl16(pb)<<3; - st->codec->height = avio_rl16(pb); - fontheight = avio_r8(pb); - st->codec->height *= fontheight; - flags = avio_r8(pb); - - st->codec->extradata_size = 2; - if ((flags & BINTEXT_PALETTE)) - st->codec->extradata_size += 48; - if ((flags & BINTEXT_FONT)) - st->codec->extradata_size += fontheight * (flags & 0x10 ? 512 : 256); - st->codec->codec_id = flags & 4 ? AV_CODEC_ID_XBIN : AV_CODEC_ID_BINTEXT; - - st->codec->extradata = av_malloc(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!st->codec->extradata) - return AVERROR(ENOMEM); - st->codec->extradata[0] = fontheight; - st->codec->extradata[1] = flags; - if (avio_read(pb, st->codec->extradata + 2, st->codec->extradata_size - 2) < 0) - return AVERROR(EIO); - - if (pb->seekable) { - bin->fsize = avio_size(pb) - 9 - st->codec->extradata_size; - ff_sauce_read(s, &bin->fsize, NULL, 0); - avio_seek(pb, 9 + st->codec->extradata_size, SEEK_SET); - } - - return 0; -} -#endif /* CONFIG_XBIN_DEMUXER */ - -#if CONFIG_ADF_DEMUXER -static int adf_read_header(AVFormatContext *s) -{ - BinDemuxContext *bin = s->priv_data; - AVIOContext *pb = s->pb; - AVStream *st; - - if (avio_r8(pb) != 1) - return AVERROR_INVALIDDATA; - - st = init_stream(s); - if (!st) - return AVERROR(ENOMEM); - st->codec->codec_id = AV_CODEC_ID_BINTEXT; - - st->codec->extradata_size = 2 + 48 + 4096; - st->codec->extradata = av_malloc(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!st->codec->extradata) - return AVERROR(ENOMEM); - st->codec->extradata[0] = 16; - st->codec->extradata[1] = BINTEXT_PALETTE|BINTEXT_FONT; - - if (avio_read(pb, st->codec->extradata + 2, 24) < 0) - return AVERROR(EIO); - avio_skip(pb, 144); - if (avio_read(pb, st->codec->extradata + 2 + 24, 24) < 0) - return AVERROR(EIO); - if (avio_read(pb, st->codec->extradata + 2 + 48, 4096) < 0) - return AVERROR(EIO); - - if (pb->seekable) { - int got_width = 0; - bin->fsize = avio_size(pb) - 1 - 192 - 4096; - st->codec->width = 80<<3; - ff_sauce_read(s, &bin->fsize, &got_width, 0); - if (!bin->video_size) - calculate_height(st->codec, bin->fsize); - avio_seek(pb, 1 + 192 + 4096, SEEK_SET); - } - return 0; -} -#endif /* CONFIG_ADF_DEMUXER */ - -#if CONFIG_IDF_DEMUXER -static const uint8_t idf_magic[] = { - 0x04, 0x31, 0x2e, 0x34, 0x00, 0x00, 0x00, 0x00, 0x4f, 0x00, 0x15, 0x00 -}; - -static int idf_probe(AVProbeData *p) -{ - if (p->buf_size < sizeof(idf_magic)) - return 0; - if (!memcmp(p->buf, idf_magic, sizeof(idf_magic))) - return AVPROBE_SCORE_MAX; - return 0; -} - -static int idf_read_header(AVFormatContext *s) -{ - BinDemuxContext *bin = s->priv_data; - AVIOContext *pb = s->pb; - AVStream *st; - int got_width = 0; - - if (!pb->seekable) - return AVERROR(EIO); - - st = init_stream(s); - if (!st) - return AVERROR(ENOMEM); - st->codec->codec_id = AV_CODEC_ID_IDF; - - st->codec->extradata_size = 2 + 48 + 4096; - st->codec->extradata = av_malloc(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!st->codec->extradata) - return AVERROR(ENOMEM); - st->codec->extradata[0] = 16; - st->codec->extradata[1] = BINTEXT_PALETTE|BINTEXT_FONT; - - avio_seek(pb, avio_size(pb) - 4096 - 48, SEEK_SET); - - if (avio_read(pb, st->codec->extradata + 2 + 48, 4096) < 0) - return AVERROR(EIO); - if (avio_read(pb, st->codec->extradata + 2, 48) < 0) - return AVERROR(EIO); - - bin->fsize = avio_size(pb) - 12 - 4096 - 48; - ff_sauce_read(s, &bin->fsize, &got_width, 0); - if (!bin->video_size) - calculate_height(st->codec, bin->fsize); - avio_seek(pb, 12, SEEK_SET); - return 0; -} -#endif /* CONFIG_IDF_DEMUXER */ - -static int read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - BinDemuxContext *bin = s->priv_data; - - if (bin->fsize > 0) { - if (av_get_packet(s->pb, pkt, bin->fsize) < 0) - return AVERROR(EIO); - bin->fsize = -1; /* done */ - } else if (!bin->fsize) { - if (url_feof(s->pb)) - return AVERROR(EIO); - if (av_get_packet(s->pb, pkt, bin->chars_per_frame) < 0) - return AVERROR(EIO); - } else { - return AVERROR(EIO); - } - - pkt->flags |= AV_PKT_FLAG_KEY; - return 0; -} - -#define OFFSET(x) offsetof(BinDemuxContext, x) -static const AVOption options[] = { - { "linespeed", "set simulated line speed (bytes per second)", OFFSET(chars_per_frame), AV_OPT_TYPE_INT, {.i64 = 6000}, 1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM}, - { "video_size", "set video size, such as 640x480 or hd720.", OFFSET(video_size), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, AV_OPT_FLAG_DECODING_PARAM }, - { "framerate", "set framerate (frames per second)", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = "25"}, 0, 0, AV_OPT_FLAG_DECODING_PARAM }, - { NULL }, -}; - -#define CLASS(name) \ -(const AVClass[1]){{ \ - .class_name = name, \ - .item_name = av_default_item_name, \ - .option = options, \ - .version = LIBAVUTIL_VERSION_INT, \ -}} - -#if CONFIG_BINTEXT_DEMUXER -AVInputFormat ff_bintext_demuxer = { - .name = "bin", - .long_name = NULL_IF_CONFIG_SMALL("Binary text"), - .priv_data_size = sizeof(BinDemuxContext), - .read_header = bintext_read_header, - .read_packet = read_packet, - .extensions = "bin", - .priv_class = CLASS("Binary text demuxer"), -}; -#endif - -#if CONFIG_XBIN_DEMUXER -AVInputFormat ff_xbin_demuxer = { - .name = "xbin", - .long_name = NULL_IF_CONFIG_SMALL("eXtended BINary text (XBIN)"), - .priv_data_size = sizeof(BinDemuxContext), - .read_probe = xbin_probe, - .read_header = xbin_read_header, - .read_packet = read_packet, - .priv_class = CLASS("eXtended BINary text (XBIN) demuxer"), -}; -#endif - -#if CONFIG_ADF_DEMUXER -AVInputFormat ff_adf_demuxer = { - .name = "adf", - .long_name = NULL_IF_CONFIG_SMALL("Artworx Data Format"), - .priv_data_size = sizeof(BinDemuxContext), - .read_header = adf_read_header, - .read_packet = read_packet, - .extensions = "adf", - .priv_class = CLASS("Artworx Data Format demuxer"), -}; -#endif - -#if CONFIG_IDF_DEMUXER -AVInputFormat ff_idf_demuxer = { - .name = "idf", - .long_name = NULL_IF_CONFIG_SMALL("iCE Draw File"), - .priv_data_size = sizeof(BinDemuxContext), - .read_probe = idf_probe, - .read_header = idf_read_header, - .read_packet = read_packet, - .extensions = "idf", - .priv_class = CLASS("iCE Draw File demuxer"), -}; -#endif diff --git a/ffmpeg1/libavformat/bit.c b/ffmpeg1/libavformat/bit.c deleted file mode 100644 index 9f6ea4a..0000000 --- a/ffmpeg1/libavformat/bit.c +++ /dev/null @@ -1,157 +0,0 @@ -/* - * G.729 bit format muxer and demuxer - * Copyright (c) 2007-2008 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 "internal.h" -#include "libavcodec/get_bits.h" -#include "libavcodec/put_bits.h" - -#define MAX_FRAME_SIZE 10 - -#define SYNC_WORD 0x6b21 -#define BIT_0 0x7f -#define BIT_1 0x81 - -static int probe(AVProbeData *p) -{ - int i, j; - - if(p->buf_size < 0x40) - return 0; - - for(i=0; i+3buf_size && i< 10*0x50; ){ - if(AV_RL16(&p->buf[0]) != SYNC_WORD) - return 0; - j=AV_RL16(&p->buf[2]); - if(j!=0x40 && j!=0x50) - return 0; - i+=j; - } - return AVPROBE_SCORE_MAX/2; -} - -static int read_header(AVFormatContext *s) -{ - AVStream* st; - - st=avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id=AV_CODEC_ID_G729; - st->codec->sample_rate=8000; - st->codec->block_align = 16; - st->codec->channels=1; - - avpriv_set_pts_info(st, 64, 1, 100); - return 0; -} - -static int read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - AVIOContext *pb = s->pb; - PutBitContext pbo; - uint16_t buf[8 * MAX_FRAME_SIZE + 2]; - int packet_size; - uint16_t* src=buf; - int i, j, ret; - int64_t pos= avio_tell(pb); - - if(url_feof(pb)) - return AVERROR_EOF; - - avio_rl16(pb); // sync word - packet_size = avio_rl16(pb) / 8; - if(packet_size > MAX_FRAME_SIZE) - return AVERROR_INVALIDDATA; - - ret = avio_read(pb, (uint8_t*)buf, (8 * packet_size) * sizeof(uint16_t)); - if(ret<0) - return ret; - if(ret != 8 * packet_size * sizeof(uint16_t)) - return AVERROR(EIO); - - if (av_new_packet(pkt, packet_size) < 0) - return AVERROR(ENOMEM); - - init_put_bits(&pbo, pkt->data, packet_size); - for(j=0; j < packet_size; j++) - for(i=0; i<8;i++) - put_bits(&pbo,1, AV_RL16(src++) == BIT_1 ? 1 : 0); - - flush_put_bits(&pbo); - - pkt->duration=1; - pkt->pos = pos; - return 0; -} - -AVInputFormat ff_bit_demuxer = { - .name = "bit", - .long_name = NULL_IF_CONFIG_SMALL("G.729 BIT file format"), - .read_probe = probe, - .read_header = read_header, - .read_packet = read_packet, - .extensions = "bit", -}; - -#if CONFIG_MUXERS -static int write_header(AVFormatContext *s) -{ - AVCodecContext *enc = s->streams[0]->codec; - - enc->codec_id = AV_CODEC_ID_G729; - enc->channels = 1; - enc->bits_per_coded_sample = 16; - enc->block_align = (enc->bits_per_coded_sample * enc->channels) >> 3; - - return 0; -} - -static int write_packet(AVFormatContext *s, AVPacket *pkt) -{ - AVIOContext *pb = s->pb; - GetBitContext gb; - int i; - - avio_wl16(pb, SYNC_WORD); - avio_wl16(pb, 8 * 10); - - init_get_bits(&gb, pkt->data, 8*10); - for(i=0; i< 8 * 10; i++) - avio_wl16(pb, get_bits1(&gb) ? BIT_1 : BIT_0); - avio_flush(pb); - - return 0; -} - -AVOutputFormat ff_bit_muxer = { - .name = "bit", - .long_name = NULL_IF_CONFIG_SMALL("G.729 BIT file format"), - .mime_type = "audio/bit", - .extensions = "bit", - .audio_codec = AV_CODEC_ID_G729, - .video_codec = AV_CODEC_ID_NONE, - .write_header = write_header, - .write_packet = write_packet, -}; -#endif diff --git a/ffmpeg1/libavformat/bluray.c b/ffmpeg1/libavformat/bluray.c deleted file mode 100644 index d2c57aa..0000000 --- a/ffmpeg1/libavformat/bluray.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - * BluRay (libbluray) protocol - * - * Copyright (c) 2012 Petri Hintukainen users.sourceforge.net> - * - * 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 - -#include "libavutil/avstring.h" -#include "libavformat/avformat.h" -#include "libavformat/url.h" -#include "libavutil/opt.h" - -#define BLURAY_PROTO_PREFIX "bluray:" -#define MIN_PLAYLIST_LENGTH 180 /* 3 min */ - -typedef struct { - const AVClass *class; - - BLURAY *bd; - - int playlist; - int angle; - int chapter; - /*int region;*/ -} BlurayContext; - -#define OFFSET(x) offsetof(BlurayContext, x) -static const AVOption options[] = { -{"playlist", "", OFFSET(playlist), AV_OPT_TYPE_INT, { .i64=-1 }, -1, 99999, AV_OPT_FLAG_DECODING_PARAM }, -{"angle", "", OFFSET(angle), AV_OPT_TYPE_INT, { .i64=0 }, 0, 0xfe, AV_OPT_FLAG_DECODING_PARAM }, -{"chapter", "", OFFSET(chapter), AV_OPT_TYPE_INT, { .i64=1 }, 1, 0xfffe, AV_OPT_FLAG_DECODING_PARAM }, -/*{"region", "bluray player region code (1 = region A, 2 = region B, 4 = region C)", OFFSET(region), AV_OPT_TYPE_INT, { .i64=0 }, 0, 3, AV_OPT_FLAG_DECODING_PARAM },*/ -{NULL} -}; - -static const AVClass bluray_context_class = { - .class_name = "bluray", - .item_name = av_default_item_name, - .option = options, - .version = LIBAVUTIL_VERSION_INT, -}; - - -static int check_disc_info(URLContext *h) -{ - BlurayContext *bd = h->priv_data; - const BLURAY_DISC_INFO *disc_info; - - disc_info = bd_get_disc_info(bd->bd); - if (!disc_info) { - av_log(h, AV_LOG_ERROR, "bd_get_disc_info() failed\n"); - return -1; - } - - if (!disc_info->bluray_detected) { - av_log(h, AV_LOG_ERROR, "BluRay disc not detected\n"); - return -1; - } - - /* AACS */ - if (disc_info->aacs_detected && !disc_info->aacs_handled) { - if (!disc_info->libaacs_detected) { - av_log(h, AV_LOG_ERROR, - "Media stream encrypted with AACS, install and configure libaacs\n"); - } else { - av_log(h, AV_LOG_ERROR, "Your libaacs can't decrypt this media\n"); - } - return -1; - } - - /* BD+ */ - if (disc_info->bdplus_detected && !disc_info->bdplus_handled) { - /* - if (!disc_info->libbdplus_detected) { - av_log(h, AV_LOG_ERROR, - "Media stream encrypted with BD+, install and configure libbdplus"); - } else { - */ - av_log(h, AV_LOG_ERROR, "Unable to decrypt BD+ encrypted media\n"); - /*}*/ - return -1; - } - - return 0; -} - -static int bluray_close(URLContext *h) -{ - BlurayContext *bd = h->priv_data; - if (bd->bd) { - bd_close(bd->bd); - } - - return 0; -} - -static int bluray_open(URLContext *h, const char *path, int flags) -{ - BlurayContext *bd = h->priv_data; - int num_title_idx; - const char *diskname = path; - - av_strstart(path, BLURAY_PROTO_PREFIX, &diskname); - - bd->bd = bd_open(diskname, NULL); - if (!bd->bd) { - av_log(h, AV_LOG_ERROR, "bd_open() failed\n"); - return AVERROR(EIO); - } - - /* check if disc can be played */ - if (check_disc_info(h) < 0) { - return AVERROR(EIO); - } - - /* setup player registers */ - /* region code has no effect without menus - if (bd->region > 0 && bd->region < 5) { - av_log(h, AV_LOG_INFO, "setting region code to %d (%c)\n", bd->region, 'A' + (bd->region - 1)); - bd_set_player_setting(bd->bd, BLURAY_PLAYER_SETTING_REGION_CODE, bd->region); - } - */ - - /* load title list */ - num_title_idx = bd_get_titles(bd->bd, TITLES_RELEVANT, MIN_PLAYLIST_LENGTH); - av_log(h, AV_LOG_INFO, "%d usable playlists:\n", num_title_idx); - if (num_title_idx < 1) { - return AVERROR(EIO); - } - - /* if playlist was not given, select longest playlist */ - if (bd->playlist < 0) { - uint64_t duration = 0; - int i; - for (i = 0; i < num_title_idx; i++) { - BLURAY_TITLE_INFO *info = bd_get_title_info(bd->bd, i, 0); - - av_log(h, AV_LOG_INFO, "playlist %05d.mpls (%d:%02d:%02d)\n", - info->playlist, - ((int)(info->duration / 90000) / 3600), - ((int)(info->duration / 90000) % 3600) / 60, - ((int)(info->duration / 90000) % 60)); - - if (info->duration > duration) { - bd->playlist = info->playlist; - duration = info->duration; - } - - bd_free_title_info(info); - } - av_log(h, AV_LOG_INFO, "selected %05d.mpls\n", bd->playlist); - } - - /* select playlist */ - if (bd_select_playlist(bd->bd, bd->playlist) <= 0) { - av_log(h, AV_LOG_ERROR, "bd_select_playlist(%05d.mpls) failed\n", bd->playlist); - return AVERROR(EIO); - } - - /* select angle */ - if (bd->angle >= 0) { - bd_select_angle(bd->bd, bd->angle); - } - - /* select chapter */ - if (bd->chapter > 1) { - bd_seek_chapter(bd->bd, bd->chapter - 1); - } - - return 0; -} - -static int bluray_read(URLContext *h, unsigned char *buf, int size) -{ - BlurayContext *bd = h->priv_data; - int len; - - if (!bd || !bd->bd) { - return AVERROR(EFAULT); - } - - len = bd_read(bd->bd, buf, size); - - return len; -} - -static int64_t bluray_seek(URLContext *h, int64_t pos, int whence) -{ - BlurayContext *bd = h->priv_data; - - if (!bd || !bd->bd) { - return AVERROR(EFAULT); - } - - switch (whence) { - case SEEK_SET: - case SEEK_CUR: - case SEEK_END: - return bd_seek(bd->bd, pos); - - case AVSEEK_SIZE: - return bd_get_title_size(bd->bd); - } - - av_log(h, AV_LOG_ERROR, "Unsupported whence operation %d\n", whence); - return AVERROR(EINVAL); -} - - -URLProtocol ff_bluray_protocol = { - .name = "bluray", - .url_close = bluray_close, - .url_open = bluray_open, - .url_read = bluray_read, - .url_seek = bluray_seek, - .priv_data_size = sizeof(BlurayContext), - .priv_data_class = &bluray_context_class, -}; diff --git a/ffmpeg1/libavformat/bmv.c b/ffmpeg1/libavformat/bmv.c deleted file mode 100644 index ce157e8..0000000 --- a/ffmpeg1/libavformat/bmv.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Discworld II BMV demuxer - * Copyright (c) 2011 Konstantin Shishkov. - * - * 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 - */ - -#include "libavutil/channel_layout.h" -#include "avformat.h" -#include "internal.h" - -enum BMVFlags { - BMV_NOP = 0, - BMV_END, - BMV_DELTA, - BMV_INTRA, - - BMV_AUDIO = 0x20, -}; - -typedef struct BMVContext { - uint8_t *packet; - int size; - int get_next; - int64_t audio_pos; -} BMVContext; - -static int bmv_read_header(AVFormatContext *s) -{ - AVStream *st, *ast; - BMVContext *c = s->priv_data; - - st = avformat_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = AV_CODEC_ID_BMV_VIDEO; - st->codec->width = 640; - st->codec->height = 429; - st->codec->pix_fmt = AV_PIX_FMT_PAL8; - avpriv_set_pts_info(st, 16, 1, 12); - ast = avformat_new_stream(s, 0); - if (!ast) - return AVERROR(ENOMEM); - ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; - ast->codec->codec_id = AV_CODEC_ID_BMV_AUDIO; - ast->codec->channels = 2; - ast->codec->channel_layout = AV_CH_LAYOUT_STEREO; - ast->codec->sample_rate = 22050; - avpriv_set_pts_info(ast, 16, 1, 22050); - - c->get_next = 1; - c->audio_pos = 0; - return 0; -} - -static int bmv_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - BMVContext *c = s->priv_data; - int type; - void *tmp; - - while (c->get_next) { - if (s->pb->eof_reached) - return AVERROR_EOF; - type = avio_r8(s->pb); - if (type == BMV_NOP) - continue; - if (type == BMV_END) - return AVERROR_EOF; - c->size = avio_rl24(s->pb); - if (!c->size) - return AVERROR_INVALIDDATA; - tmp = av_realloc(c->packet, c->size + 1); - if (!tmp) - return AVERROR(ENOMEM); - c->packet = tmp; - c->packet[0] = type; - if (avio_read(s->pb, c->packet + 1, c->size) != c->size) - return AVERROR(EIO); - if (type & BMV_AUDIO) { - int audio_size = c->packet[1] * 65 + 1; - if (audio_size >= c->size) { - av_log(s, AV_LOG_ERROR, "Reported audio size %d is bigger than packet size (%d)\n", - audio_size, c->size); - return AVERROR_INVALIDDATA; - } - if (av_new_packet(pkt, audio_size) < 0) - return AVERROR(ENOMEM); - memcpy(pkt->data, c->packet + 1, pkt->size); - pkt->stream_index = 1; - pkt->pts = c->audio_pos; - pkt->duration = c->packet[1] * 32; - c->audio_pos += pkt->duration; - c->get_next = 0; - return pkt->size; - } else - break; - } - if (av_new_packet(pkt, c->size + 1) < 0) - return AVERROR(ENOMEM); - pkt->stream_index = 0; - c->get_next = 1; - memcpy(pkt->data, c->packet, pkt->size); - return pkt->size; -} - -static int bmv_read_close(AVFormatContext *s) -{ - BMVContext *c = s->priv_data; - - av_freep(&c->packet); - - return 0; -} - -AVInputFormat ff_bmv_demuxer = { - .name = "bmv", - .long_name = NULL_IF_CONFIG_SMALL("Discworld II BMV"), - .priv_data_size = sizeof(BMVContext), - .read_header = bmv_read_header, - .read_packet = bmv_read_packet, - .read_close = bmv_read_close, - .extensions = "bmv", -}; diff --git a/ffmpeg1/libavformat/brstm.c b/ffmpeg1/libavformat/brstm.c deleted file mode 100644 index 7781b3c..0000000 --- a/ffmpeg1/libavformat/brstm.c +++ /dev/null @@ -1,297 +0,0 @@ -/* - * BRSTM demuxer - * Copyright (c) 2012 Paul B Mahol - * - * 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 "libavutil/intreadwrite.h" -#include "libavcodec/bytestream.h" -#include "avformat.h" -#include "internal.h" - -typedef struct BRSTMDemuxContext { - uint32_t block_size; - uint32_t block_count; - uint32_t current_block; - uint32_t samples_per_block; - uint32_t last_block_used_bytes; - uint8_t *table; - uint8_t *adpc; -} BRSTMDemuxContext; - -static int probe(AVProbeData *p) -{ - if (AV_RL32(p->buf) == MKTAG('R','S','T','M') && - (AV_RL16(p->buf + 4) == 0xFFFE || - AV_RL16(p->buf + 4) == 0xFEFF)) - return AVPROBE_SCORE_MAX / 3 * 2; - return 0; -} - -static int read_close(AVFormatContext *s) -{ - BRSTMDemuxContext *b = s->priv_data; - - av_freep(&b->table); - av_freep(&b->adpc); - - return 0; -} - -static int read_header(AVFormatContext *s) -{ - BRSTMDemuxContext *b = s->priv_data; - int bom, major, minor, codec, chunk; - int64_t pos, h1offset, toffset; - uint32_t size, start, asize; - AVStream *st; - int ret = AVERROR_EOF; - - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - - avio_skip(s->pb, 4); - - bom = avio_rb16(s->pb); - if (bom != 0xFEFF && bom != 0xFFFE) { - av_log(s, AV_LOG_ERROR, "invalid byte order: %X\n", bom); - return AVERROR_INVALIDDATA; - } - if (bom == 0xFFFE) { - avpriv_request_sample(s, "little endian byte order"); - return AVERROR_PATCHWELCOME; - } - - major = avio_r8(s->pb); - minor = avio_r8(s->pb); - avio_skip(s->pb, 4); // size of file - size = avio_rb16(s->pb); - if (size < 14) - return AVERROR_INVALIDDATA; - - avio_skip(s->pb, size - 14); - pos = avio_tell(s->pb); - if (avio_rl32(s->pb) != MKTAG('H','E','A','D')) - return AVERROR_INVALIDDATA; - size = avio_rb32(s->pb); - if (size < 256) - return AVERROR_INVALIDDATA; - avio_skip(s->pb, 4); // unknown - h1offset = avio_rb32(s->pb); - if (h1offset > size) - return AVERROR_INVALIDDATA; - avio_skip(s->pb, 12); - toffset = avio_rb32(s->pb) + 16LL; - if (toffset > size) - return AVERROR_INVALIDDATA; - - avio_skip(s->pb, pos + h1offset + 8 - avio_tell(s->pb)); - codec = avio_r8(s->pb); - - switch (codec) { - case 0: codec = AV_CODEC_ID_PCM_S8_PLANAR; break; - case 1: codec = AV_CODEC_ID_PCM_S16BE_PLANAR; break; - case 2: codec = AV_CODEC_ID_ADPCM_THP; break; - default: - avpriv_request_sample(s, "codec %d", codec); - return AVERROR_PATCHWELCOME; - } - - avio_skip(s->pb, 1); // loop flag - st->codec->codec_id = codec; - st->codec->channels = avio_r8(s->pb); - if (!st->codec->channels) - return AVERROR_INVALIDDATA; - - avio_skip(s->pb, 1); // padding - st->codec->sample_rate = avio_rb16(s->pb); - if (!st->codec->sample_rate) - return AVERROR_INVALIDDATA; - - avio_skip(s->pb, 2); // padding - avio_skip(s->pb, 4); // loop start sample - st->start_time = 0; - st->duration = avio_rb32(s->pb); - avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); - - start = avio_rb32(s->pb); - b->current_block = 0; - b->block_count = avio_rb32(s->pb); - if (b->block_count > UINT16_MAX) { - av_log(s, AV_LOG_WARNING, "too many blocks: %u\n", b->block_count); - return AVERROR_INVALIDDATA; - } - - b->block_size = avio_rb32(s->pb); - if (b->block_size > UINT16_MAX / st->codec->channels) - return AVERROR_INVALIDDATA; - b->block_size *= st->codec->channels; - - b->samples_per_block = avio_rb32(s->pb); - b->last_block_used_bytes = avio_rb32(s->pb); - if (b->last_block_used_bytes > UINT16_MAX / st->codec->channels) - return AVERROR_INVALIDDATA; - b->last_block_used_bytes *= st->codec->channels; - - avio_skip(s->pb, 4); // last block samples - avio_skip(s->pb, 4); // last block size - - if (codec == AV_CODEC_ID_ADPCM_THP) { - int ch; - - avio_skip(s->pb, pos + toffset - avio_tell(s->pb)); - toffset = avio_rb32(s->pb) + 16LL; - if (toffset > size) - return AVERROR_INVALIDDATA; - - avio_skip(s->pb, pos + toffset - avio_tell(s->pb)); - b->table = av_mallocz(32 * st->codec->channels); - if (!b->table) - return AVERROR(ENOMEM); - - for (ch = 0; ch < st->codec->channels; ch++) { - if (avio_read(s->pb, b->table + ch * 32, 32) != 32) { - ret = AVERROR_INVALIDDATA; - goto fail; - } - avio_skip(s->pb, 24); - } - } - - if (size < (avio_tell(s->pb) - pos)) { - ret = AVERROR_INVALIDDATA; - goto fail; - } - avio_skip(s->pb, size - (avio_tell(s->pb) - pos)); - - while (!url_feof(s->pb)) { - chunk = avio_rl32(s->pb); - size = avio_rb32(s->pb); - if (size < 8) { - ret = AVERROR_INVALIDDATA; - goto fail; - } - size -= 8; - switch (chunk) { - case MKTAG('A','D','P','C'): - if (codec != AV_CODEC_ID_ADPCM_THP) - goto skip; - - asize = b->block_count * st->codec->channels * 4; - if (size < asize) { - ret = AVERROR_INVALIDDATA; - goto fail; - } - if (b->adpc) { - av_log(s, AV_LOG_WARNING, "skipping additonal ADPC chunk\n"); - goto skip; - } else { - b->adpc = av_mallocz(asize); - if (!b->adpc) { - ret = AVERROR(ENOMEM); - goto fail; - } - avio_read(s->pb, b->adpc, asize); - avio_skip(s->pb, size - asize); - } - break; - case MKTAG('D','A','T','A'): - if ((start < avio_tell(s->pb)) || - (!b->adpc && codec == AV_CODEC_ID_ADPCM_THP)) { - ret = AVERROR_INVALIDDATA; - goto fail; - } - avio_skip(s->pb, start - avio_tell(s->pb)); - - if (major != 1 || minor) - avpriv_request_sample(s, "Version %d.%d", major, minor); - - return 0; - default: - av_log(s, AV_LOG_WARNING, "skipping unknown chunk: %X\n", chunk); -skip: - avio_skip(s->pb, size); - } - } - -fail: - read_close(s); - - return ret; -} - -static int read_packet(AVFormatContext *s, AVPacket *pkt) -{ - AVCodecContext *codec = s->streams[0]->codec; - BRSTMDemuxContext *b = s->priv_data; - uint32_t samples, size; - int ret; - - if (url_feof(s->pb)) - return AVERROR_EOF; - b->current_block++; - if (b->current_block == b->block_count) { - size = b->last_block_used_bytes; - samples = size / (8 * codec->channels) * 14; - } else if (b->current_block < b->block_count) { - size = b->block_size; - samples = b->samples_per_block; - } else { - return AVERROR_EOF; - } - - if (codec->codec_id == AV_CODEC_ID_ADPCM_THP) { - uint8_t *dst; - - if (av_new_packet(pkt, 8 + (32 + 4) * codec->channels + size) < 0) - return AVERROR(ENOMEM); - dst = pkt->data; - bytestream_put_be32(&dst, size); - bytestream_put_be32(&dst, samples); - bytestream_put_buffer(&dst, b->table, 32 * codec->channels); - bytestream_put_buffer(&dst, b->adpc + 4 * codec->channels * - (b->current_block - 1), 4 * codec->channels); - - ret = avio_read(s->pb, dst, size); - if (ret != size) - av_free_packet(pkt); - pkt->duration = samples; - } else { - ret = av_get_packet(s->pb, pkt, size); - } - - pkt->stream_index = 0; - - if (ret != size) - ret = AVERROR(EIO); - - return ret; -} - -AVInputFormat ff_brstm_demuxer = { - .name = "brstm", - .long_name = NULL_IF_CONFIG_SMALL("BRSTM (Binary Revolution Stream)"), - .priv_data_size = sizeof(BRSTMDemuxContext), - .read_probe = probe, - .read_header = read_header, - .read_packet = read_packet, - .read_close = read_close, - .extensions = "brstm", -}; diff --git a/ffmpeg1/libavformat/c93.c b/ffmpeg1/libavformat/c93.c deleted file mode 100644 index 93a61be..0000000 --- a/ffmpeg1/libavformat/c93.c +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Interplay C93 demuxer - * Copyright (c) 2007 Anssi Hannula - * - * 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 "internal.h" -#include "voc.h" -#include "libavutil/intreadwrite.h" - -typedef struct { - uint16_t index; - uint8_t length; - uint8_t frames; -} C93BlockRecord; - -typedef struct { - VocDecContext voc; - - C93BlockRecord block_records[512]; - int current_block; - - uint32_t frame_offsets[32]; - int current_frame; - int next_pkt_is_audio; - - AVStream *audio; -} C93DemuxContext; - -static int probe(AVProbeData *p) -{ - int i; - int index = 1; - if (p->buf_size < 16) - return 0; - for (i = 0; i < 16; i += 4) { - if (AV_RL16(p->buf + i) != index || !p->buf[i + 2] || !p->buf[i + 3]) - return 0; - index += p->buf[i + 2]; - } - return AVPROBE_SCORE_MAX; -} - -static int read_header(AVFormatContext *s) -{ - AVStream *video; - AVIOContext *pb = s->pb; - C93DemuxContext *c93 = s->priv_data; - int i; - int framecount = 0; - - for (i = 0; i < 512; i++) { - c93->block_records[i].index = avio_rl16(pb); - c93->block_records[i].length = avio_r8(pb); - c93->block_records[i].frames = avio_r8(pb); - if (c93->block_records[i].frames > 32) { - av_log(s, AV_LOG_ERROR, "too many frames in block\n"); - return AVERROR_INVALIDDATA; - } - framecount += c93->block_records[i].frames; - } - - /* Audio streams are added if audio packets are found */ - s->ctx_flags |= AVFMTCTX_NOHEADER; - - video = avformat_new_stream(s, NULL); - if (!video) - return AVERROR(ENOMEM); - - video->codec->codec_type = AVMEDIA_TYPE_VIDEO; - video->codec->codec_id = AV_CODEC_ID_C93; - video->codec->width = 320; - video->codec->height = 192; - /* 4:3 320x200 with 8 empty lines */ - video->sample_aspect_ratio = (AVRational) { 5, 6 }; - avpriv_set_pts_info(video, 64, 2, 25); - video->nb_frames = framecount; - video->duration = framecount; - video->start_time = 0; - - c93->current_block = 0; - c93->current_frame = 0; - c93->next_pkt_is_audio = 0; - return 0; -} - -#define C93_HAS_PALETTE 0x01 -#define C93_FIRST_FRAME 0x02 - -static int read_packet(AVFormatContext *s, AVPacket *pkt) -{ - AVIOContext *pb = s->pb; - C93DemuxContext *c93 = s->priv_data; - C93BlockRecord *br = &c93->block_records[c93->current_block]; - int datasize; - int ret, i; - - if (c93->next_pkt_is_audio) { - c93->current_frame++; - c93->next_pkt_is_audio = 0; - datasize = avio_rl16(pb); - if (datasize > 42) { - if (!c93->audio) { - c93->audio = avformat_new_stream(s, NULL); - if (!c93->audio) - return AVERROR(ENOMEM); - c93->audio->codec->codec_type = AVMEDIA_TYPE_AUDIO; - } - avio_skip(pb, 26); /* VOC header */ - ret = ff_voc_get_packet(s, pkt, c93->audio, datasize - 26); - if (ret > 0) { - pkt->stream_index = 1; - pkt->flags |= AV_PKT_FLAG_KEY; - return ret; - } - } - } - if (c93->current_frame >= br->frames) { - if (c93->current_block >= 511 || !br[1].length) - return AVERROR_EOF; - br++; - c93->current_block++; - c93->current_frame = 0; - } - - if (c93->current_frame == 0) { - avio_seek(pb, br->index * 2048, SEEK_SET); - for (i = 0; i < 32; i++) { - c93->frame_offsets[i] = avio_rl32(pb); - } - } - - avio_seek(pb,br->index * 2048 + - c93->frame_offsets[c93->current_frame], SEEK_SET); - datasize = avio_rl16(pb); /* video frame size */ - - ret = av_new_packet(pkt, datasize + 768 + 1); - if (ret < 0) - return ret; - pkt->data[0] = 0; - pkt->size = datasize + 1; - - ret = avio_read(pb, pkt->data + 1, datasize); - if (ret < datasize) { - ret = AVERROR(EIO); - goto fail; - } - - datasize = avio_rl16(pb); /* palette size */ - if (datasize) { - if (datasize != 768) { - av_log(s, AV_LOG_ERROR, "invalid palette size %u\n", datasize); - ret = AVERROR_INVALIDDATA; - goto fail; - } - pkt->data[0] |= C93_HAS_PALETTE; - ret = avio_read(pb, pkt->data + pkt->size, datasize); - if (ret < datasize) { - ret = AVERROR(EIO); - goto fail; - } - pkt->size += 768; - } - pkt->stream_index = 0; - c93->next_pkt_is_audio = 1; - - /* only the first frame is guaranteed to not reference previous frames */ - if (c93->current_block == 0 && c93->current_frame == 0) { - pkt->flags |= AV_PKT_FLAG_KEY; - pkt->data[0] |= C93_FIRST_FRAME; - } - return 0; - - fail: - av_free_packet(pkt); - return ret; -} - -AVInputFormat ff_c93_demuxer = { - .name = "c93", - .long_name = NULL_IF_CONFIG_SMALL("Interplay C93"), - .priv_data_size = sizeof(C93DemuxContext), - .read_probe = probe, - .read_header = read_header, - .read_packet = read_packet, -}; diff --git a/ffmpeg1/libavformat/cache.c b/ffmpeg1/libavformat/cache.c deleted file mode 100644 index 35f81e8..0000000 --- a/ffmpeg1/libavformat/cache.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Input cache protocol. - * Copyright (c) 2011 Michael Niedermayer - * - * 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 - * - * Based on file.c by Fabrice Bellard - */ - -/** - * @TODO - * support non continuous caching - * support keeping files - * support filling with a background thread - */ - -#include "libavutil/avassert.h" -#include "libavutil/avstring.h" -#include "libavutil/file.h" -#include "avformat.h" -#include -#if HAVE_IO_H -#include -#endif -#if HAVE_UNISTD_H -#include -#endif -#include -#include -#include "os_support.h" -#include "url.h" - -typedef struct Context { - int fd; - int64_t end; - int64_t pos; - URLContext *inner; -} Context; - -static int cache_open(URLContext *h, const char *arg, int flags) -{ - char *buffername; - Context *c= h->priv_data; - - av_strstart(arg, "cache:", &arg); - - c->fd = av_tempfile("ffcache", &buffername, 0, h); - if (c->fd < 0){ - av_log(h, AV_LOG_ERROR, "Failed to create tempfile\n"); - return c->fd; - } - - unlink(buffername); - av_freep(&buffername); - - return ffurl_open(&c->inner, arg, flags, &h->interrupt_callback, NULL); -} - -static int cache_read(URLContext *h, unsigned char *buf, int size) -{ - Context *c= h->priv_data; - int r; - - if(c->posend){ - r = read(c->fd, buf, FFMIN(size, c->end - c->pos)); - if(r>0) - c->pos += r; - return (-1 == r)?AVERROR(errno):r; - }else{ - r = ffurl_read(c->inner, buf, size); - if(r > 0){ - int r2= write(c->fd, buf, r); - av_assert0(r2==r); // FIXME handle cache failure - c->pos += r; - c->end += r; - } - return r; - } -} - -static int64_t cache_seek(URLContext *h, int64_t pos, int whence) -{ - Context *c= h->priv_data; - - if (whence == AVSEEK_SIZE) { - pos= ffurl_seek(c->inner, pos, whence); - if(pos <= 0){ - pos= ffurl_seek(c->inner, -1, SEEK_END); - ffurl_seek(c->inner, c->end, SEEK_SET); - if(pos <= 0) - return c->end; - } - return pos; - } - - pos= lseek(c->fd, pos, whence); - if(pos<0){ - return pos; - }else if(pos <= c->end){ - c->pos= pos; - return pos; - }else{ - if(lseek(c->fd, c->pos, SEEK_SET) < 0) { - av_log(h, AV_LOG_ERROR, "Failure to seek in cache\n"); - } - return AVERROR(EPIPE); - } -} - -static int cache_close(URLContext *h) -{ - Context *c= h->priv_data; - close(c->fd); - ffurl_close(c->inner); - - return 0; -} - -URLProtocol ff_cache_protocol = { - .name = "cache", - .url_open = cache_open, - .url_read = cache_read, - .url_seek = cache_seek, - .url_close = cache_close, - .priv_data_size = sizeof(Context), -}; diff --git a/ffmpeg1/libavformat/caf.c b/ffmpeg1/libavformat/caf.c deleted file mode 100644 index c1ecc94..0000000 --- a/ffmpeg1/libavformat/caf.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * CAF common code - * Copyright (c) 2007 Justin Ruggles - * - * 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 - */ - -/** - * @file - * CAF common code - */ - -#include "avformat.h" -#include "internal.h" -#include "caf.h" - -/** - * Known codec tags for CAF - */ -const AVCodecTag ff_codec_caf_tags[] = { - { AV_CODEC_ID_AAC, MKTAG('a','a','c',' ') }, - { AV_CODEC_ID_AC3, MKTAG('a','c','-','3') }, - { AV_CODEC_ID_ADPCM_IMA_QT, MKTAG('i','m','a','4') }, - { AV_CODEC_ID_ADPCM_IMA_WAV, MKTAG('m','s', 0, 17 ) }, - { AV_CODEC_ID_ADPCM_MS, MKTAG('m','s', 0, 2 ) }, - { AV_CODEC_ID_ALAC, MKTAG('a','l','a','c') }, - { AV_CODEC_ID_AMR_NB, MKTAG('s','a','m','r') }, - /* FIXME: use DV demuxer, as done in MOV */ - /*{ AV_CODEC_ID_DVAUDIO, MKTAG('v','d','v','a') },*/ - /*{ AV_CODEC_ID_DVAUDIO, MKTAG('d','v','c','a') },*/ - { AV_CODEC_ID_GSM, MKTAG('a','g','s','m') }, - { AV_CODEC_ID_GSM_MS, MKTAG('m','s', 0, '1') }, - { AV_CODEC_ID_ILBC, MKTAG('i','l','b','c') }, - { AV_CODEC_ID_MACE3, MKTAG('M','A','C','3') }, - { AV_CODEC_ID_MACE6, MKTAG('M','A','C','6') }, - { AV_CODEC_ID_MP1, MKTAG('.','m','p','1') }, - { AV_CODEC_ID_MP2, MKTAG('.','m','p','2') }, - { AV_CODEC_ID_MP3, MKTAG('.','m','p','3') }, - { AV_CODEC_ID_MP3, MKTAG('m','s', 0 ,'U') }, - { AV_CODEC_ID_PCM_ALAW, MKTAG('a','l','a','w') }, - { AV_CODEC_ID_PCM_MULAW, MKTAG('u','l','a','w') }, - { AV_CODEC_ID_QCELP, MKTAG('Q','c','l','p') }, - { AV_CODEC_ID_QDM2, MKTAG('Q','D','M','2') }, - { AV_CODEC_ID_QDM2, MKTAG('Q','D','M','C') }, - /* currently unsupported codecs */ - /*{ AC-3 over S/PDIF MKTAG('c','a','c','3') },*/ - /*{ MPEG4CELP MKTAG('c','e','l','p') },*/ - /*{ MPEG4HVXC MKTAG('h','v','x','c') },*/ - /*{ MPEG4TwinVQ MKTAG('t','w','v','q') },*/ - { AV_CODEC_ID_NONE, 0 }, -}; - diff --git a/ffmpeg1/libavformat/caf.h b/ffmpeg1/libavformat/caf.h deleted file mode 100644 index 9c25f2c..0000000 --- a/ffmpeg1/libavformat/caf.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * CAF common code - * Copyright (c) 2007 Justin Ruggles - * - * 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 - */ - -/** - * @file - * CAF common code - */ - -#ifndef AVFORMAT_CAF_H -#define AVFORMAT_CAF_H - -#include "internal.h" - -extern const AVCodecTag ff_codec_caf_tags[]; - -#endif /* AVFORMAT_CAF_H */ diff --git a/ffmpeg1/libavformat/cafdec.c b/ffmpeg1/libavformat/cafdec.c deleted file mode 100644 index 337758e..0000000 --- a/ffmpeg1/libavformat/cafdec.c +++ /dev/null @@ -1,434 +0,0 @@ -/* - * Core Audio Format demuxer - * Copyright (c) 2007 Justin Ruggles - * Copyright (c) 2009 Peter Ross - * - * 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 - */ - -/** - * @file - * Core Audio Format demuxer - */ - -#include "avformat.h" -#include "internal.h" -#include "isom.h" -#include "mov_chan.h" -#include "libavutil/intreadwrite.h" -#include "libavutil/intfloat.h" -#include "libavutil/dict.h" -#include "caf.h" - -typedef struct { - int bytes_per_packet; ///< bytes in a packet, or 0 if variable - int frames_per_packet; ///< frames in a packet, or 0 if variable - int64_t num_bytes; ///< total number of bytes in stream - - int64_t packet_cnt; ///< packet counter - int64_t frame_cnt; ///< frame counter - - int64_t data_start; ///< data start position, in bytes - int64_t data_size; ///< raw data size, in bytes -} CaffContext; - -static int probe(AVProbeData *p) -{ - if (AV_RB32(p->buf) == MKBETAG('c','a','f','f') && AV_RB16(&p->buf[4]) == 1) - return AVPROBE_SCORE_MAX; - return 0; -} - -/** Read audio description chunk */ -static int read_desc_chunk(AVFormatContext *s) -{ - AVIOContext *pb = s->pb; - CaffContext *caf = s->priv_data; - AVStream *st; - int flags; - - /* new audio stream */ - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - - /* parse format description */ - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->sample_rate = av_int2double(avio_rb64(pb)); - st->codec->codec_tag = avio_rl32(pb); - flags = avio_rb32(pb); - caf->bytes_per_packet = avio_rb32(pb); - st->codec->block_align = caf->bytes_per_packet; - caf->frames_per_packet = avio_rb32(pb); - st->codec->channels = avio_rb32(pb); - st->codec->bits_per_coded_sample = avio_rb32(pb); - - /* calculate bit rate for constant size packets */ - if (caf->frames_per_packet > 0 && caf->bytes_per_packet > 0) { - st->codec->bit_rate = (uint64_t)st->codec->sample_rate * (uint64_t)caf->bytes_per_packet * 8 - / (uint64_t)caf->frames_per_packet; - } else { - st->codec->bit_rate = 0; - } - - /* determine codec */ - if (st->codec->codec_tag == MKTAG('l','p','c','m')) - st->codec->codec_id = ff_mov_get_lpcm_codec_id(st->codec->bits_per_coded_sample, (flags ^ 0x2) | 0x4); - else - st->codec->codec_id = ff_codec_get_id(ff_codec_caf_tags, st->codec->codec_tag); - return 0; -} - -/** Read magic cookie chunk */ -static int read_kuki_chunk(AVFormatContext *s, int64_t size) -{ - AVIOContext *pb = s->pb; - AVStream *st = s->streams[0]; - - if (size < 0 || size > INT_MAX - FF_INPUT_BUFFER_PADDING_SIZE) - return -1; - - if (st->codec->codec_id == AV_CODEC_ID_AAC) { - /* The magic cookie format for AAC is an mp4 esds atom. - The lavc AAC decoder requires the data from the codec specific - description as extradata input. */ - int strt, skip; - MOVAtom atom; - - strt = avio_tell(pb); - ff_mov_read_esds(s, pb, atom); - skip = size - (avio_tell(pb) - strt); - if (skip < 0 || !st->codec->extradata || - st->codec->codec_id != AV_CODEC_ID_AAC) { - av_log(s, AV_LOG_ERROR, "invalid AAC magic cookie\n"); - return AVERROR_INVALIDDATA; - } - avio_skip(pb, skip); - } else if (st->codec->codec_id == AV_CODEC_ID_ALAC) { -#define ALAC_PREAMBLE 12 -#define ALAC_HEADER 36 -#define ALAC_NEW_KUKI 24 - uint8_t preamble[12]; - if (size < ALAC_NEW_KUKI) { - av_log(s, AV_LOG_ERROR, "invalid ALAC magic cookie\n"); - avio_skip(pb, size); - return AVERROR_INVALIDDATA; - } - avio_read(pb, preamble, ALAC_PREAMBLE); - - st->codec->extradata = av_mallocz(ALAC_HEADER + FF_INPUT_BUFFER_PADDING_SIZE); - if (!st->codec->extradata) - return AVERROR(ENOMEM); - - /* For the old style cookie, we skip 12 bytes, then read 36 bytes. - * The new style cookie only contains the last 24 bytes of what was - * 36 bytes in the old style cookie, so we fabricate the first 12 bytes - * in that case to maintain compatibility. */ - if (!memcmp(&preamble[4], "frmaalac", 8)) { - if (size < ALAC_PREAMBLE + ALAC_HEADER) { - av_log(s, AV_LOG_ERROR, "invalid ALAC magic cookie\n"); - av_freep(&st->codec->extradata); - return AVERROR_INVALIDDATA; - } - avio_read(pb, st->codec->extradata, ALAC_HEADER); - avio_skip(pb, size - ALAC_PREAMBLE - ALAC_HEADER); - } else { - AV_WB32(st->codec->extradata, 36); - memcpy(&st->codec->extradata[4], "alac", 4); - AV_WB32(&st->codec->extradata[8], 0); - memcpy(&st->codec->extradata[12], preamble, 12); - avio_read(pb, &st->codec->extradata[24], ALAC_NEW_KUKI - 12); - avio_skip(pb, size - ALAC_NEW_KUKI); - } - st->codec->extradata_size = ALAC_HEADER; - } else { - st->codec->extradata = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!st->codec->extradata) - return AVERROR(ENOMEM); - avio_read(pb, st->codec->extradata, size); - st->codec->extradata_size = size; - } - - return 0; -} - -/** Read packet table chunk */ -static int read_pakt_chunk(AVFormatContext *s, int64_t size) -{ - AVIOContext *pb = s->pb; - AVStream *st = s->streams[0]; - CaffContext *caf = s->priv_data; - int64_t pos = 0, ccount, num_packets; - int i; - - ccount = avio_tell(pb); - - num_packets = avio_rb64(pb); - if (num_packets < 0 || INT32_MAX / sizeof(AVIndexEntry) < num_packets) - return AVERROR_INVALIDDATA; - - st->nb_frames = avio_rb64(pb); /* valid frames */ - st->nb_frames += avio_rb32(pb); /* priming frames */ - st->nb_frames += avio_rb32(pb); /* remainder frames */ - - st->duration = 0; - for (i = 0; i < num_packets; i++) { - av_add_index_entry(s->streams[0], pos, st->duration, 0, 0, AVINDEX_KEYFRAME); - pos += caf->bytes_per_packet ? caf->bytes_per_packet : ff_mp4_read_descr_len(pb); - st->duration += caf->frames_per_packet ? caf->frames_per_packet : ff_mp4_read_descr_len(pb); - } - - if (avio_tell(pb) - ccount > size) { - av_log(s, AV_LOG_ERROR, "error reading packet table\n"); - return AVERROR_INVALIDDATA; - } - avio_skip(pb, ccount + size - avio_tell(pb)); - - caf->num_bytes = pos; - return 0; -} - -/** Read information chunk */ -static void read_info_chunk(AVFormatContext *s, int64_t size) -{ - AVIOContext *pb = s->pb; - unsigned int i; - unsigned int nb_entries = avio_rb32(pb); - for (i = 0; i < nb_entries; i++) { - char key[32]; - char value[1024]; - avio_get_str(pb, INT_MAX, key, sizeof(key)); - avio_get_str(pb, INT_MAX, value, sizeof(value)); - av_dict_set(&s->metadata, key, value, 0); - } -} - -static int read_header(AVFormatContext *s) -{ - AVIOContext *pb = s->pb; - CaffContext *caf = s->priv_data; - AVStream *st; - uint32_t tag = 0; - int found_data, ret; - int64_t size, pos; - - avio_skip(pb, 8); /* magic, version, file flags */ - - /* audio description chunk */ - if (avio_rb32(pb) != MKBETAG('d','e','s','c')) { - av_log(s, AV_LOG_ERROR, "desc chunk not present\n"); - return AVERROR_INVALIDDATA; - } - size = avio_rb64(pb); - if (size != 32) - return AVERROR_INVALIDDATA; - - ret = read_desc_chunk(s); - if (ret) - return ret; - st = s->streams[0]; - - /* parse each chunk */ - found_data = 0; - while (!url_feof(pb)) { - - /* stop at data chunk if seeking is not supported or - data chunk size is unknown */ - if (found_data && (caf->data_size < 0 || !pb->seekable)) - break; - - tag = avio_rb32(pb); - size = avio_rb64(pb); - pos = avio_tell(pb); - if (url_feof(pb)) - break; - - switch (tag) { - case MKBETAG('d','a','t','a'): - avio_skip(pb, 4); /* edit count */ - caf->data_start = avio_tell(pb); - caf->data_size = size < 0 ? -1 : size - 4; - if (caf->data_size > 0 && pb->seekable) - avio_skip(pb, caf->data_size); - found_data = 1; - break; - - case MKBETAG('c','h','a','n'): - if ((ret = ff_mov_read_chan(s, s->pb, st, size)) < 0) - return ret; - break; - - /* magic cookie chunk */ - case MKBETAG('k','u','k','i'): - if (read_kuki_chunk(s, size)) - return AVERROR_INVALIDDATA; - break; - - /* packet table chunk */ - case MKBETAG('p','a','k','t'): - if (read_pakt_chunk(s, size)) - return AVERROR_INVALIDDATA; - break; - - case MKBETAG('i','n','f','o'): - read_info_chunk(s, size); - break; - - default: -#define _(x) ((x) >= ' ' ? (x) : ' ') - av_log(s, AV_LOG_WARNING, "skipping CAF chunk: %08X (%c%c%c%c), size %"PRId64"\n", - tag, _(tag>>24), _((tag>>16)&0xFF), _((tag>>8)&0xFF), _(tag&0xFF), size); -#undef _ - case MKBETAG('f','r','e','e'): - if (size < 0) - return AVERROR_INVALIDDATA; - break; - } - - if (size > 0) { - if (pos > INT64_MAX - size) - return AVERROR_INVALIDDATA; - avio_skip(pb, FFMAX(0, pos + size - avio_tell(pb))); - } - } - - if (!found_data) - return AVERROR_INVALIDDATA; - - if (caf->bytes_per_packet > 0 && caf->frames_per_packet > 0) { - if (caf->data_size > 0) - st->nb_frames = (caf->data_size / caf->bytes_per_packet) * caf->frames_per_packet; - } else if (st->nb_index_entries && st->duration > 0) { - st->codec->bit_rate = st->codec->sample_rate * caf->data_size * 8 / - st->duration; - } else { - av_log(s, AV_LOG_ERROR, "Missing packet table. It is required when " - "block size or frame size are variable.\n"); - return AVERROR_INVALIDDATA; - } - - avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); - st->start_time = 0; - - /* position the stream at the start of data */ - if (caf->data_size >= 0) - avio_seek(pb, caf->data_start, SEEK_SET); - - return 0; -} - -#define CAF_MAX_PKT_SIZE 4096 - -static int read_packet(AVFormatContext *s, AVPacket *pkt) -{ - AVIOContext *pb = s->pb; - AVStream *st = s->streams[0]; - CaffContext *caf = s->priv_data; - int res, pkt_size = 0, pkt_frames = 0; - int64_t left = CAF_MAX_PKT_SIZE; - - if (url_feof(pb)) - return AVERROR_EOF; - - /* don't read past end of data chunk */ - if (caf->data_size > 0) { - left = (caf->data_start + caf->data_size) - avio_tell(pb); - if (!left) - return AVERROR_EOF; - if (left < 0) - return AVERROR(EIO); - } - - pkt_frames = caf->frames_per_packet; - pkt_size = caf->bytes_per_packet; - - if (pkt_size > 0 && pkt_frames == 1) { - pkt_size = (CAF_MAX_PKT_SIZE / pkt_size) * pkt_size; - pkt_size = FFMIN(pkt_size, left); - pkt_frames = pkt_size / caf->bytes_per_packet; - } else if (st->nb_index_entries) { - if (caf->packet_cnt < st->nb_index_entries - 1) { - pkt_size = st->index_entries[caf->packet_cnt + 1].pos - st->index_entries[caf->packet_cnt].pos; - pkt_frames = st->index_entries[caf->packet_cnt + 1].timestamp - st->index_entries[caf->packet_cnt].timestamp; - } else if (caf->packet_cnt == st->nb_index_entries - 1) { - pkt_size = caf->num_bytes - st->index_entries[caf->packet_cnt].pos; - pkt_frames = st->duration - st->index_entries[caf->packet_cnt].timestamp; - } else { - return AVERROR(EIO); - } - } - - if (pkt_size == 0 || pkt_frames == 0 || pkt_size > left) - return AVERROR(EIO); - - res = av_get_packet(pb, pkt, pkt_size); - if (res < 0) - return res; - - pkt->size = res; - pkt->stream_index = 0; - pkt->dts = pkt->pts = caf->frame_cnt; - - caf->packet_cnt++; - caf->frame_cnt += pkt_frames; - - return 0; -} - -static int read_seek(AVFormatContext *s, int stream_index, - int64_t timestamp, int flags) -{ - AVStream *st = s->streams[0]; - CaffContext *caf = s->priv_data; - int64_t pos, packet_cnt, frame_cnt; - - timestamp = FFMAX(timestamp, 0); - - if (caf->frames_per_packet > 0 && caf->bytes_per_packet > 0) { - /* calculate new byte position based on target frame position */ - pos = caf->bytes_per_packet * (timestamp / caf->frames_per_packet); - if (caf->data_size > 0) - pos = FFMIN(pos, caf->data_size); - packet_cnt = pos / caf->bytes_per_packet; - frame_cnt = caf->frames_per_packet * packet_cnt; - } else if (st->nb_index_entries) { - packet_cnt = av_index_search_timestamp(st, timestamp, flags); - frame_cnt = st->index_entries[packet_cnt].timestamp; - pos = st->index_entries[packet_cnt].pos; - } else { - return -1; - } - - if (avio_seek(s->pb, pos + caf->data_start, SEEK_SET) < 0) - return -1; - - caf->packet_cnt = packet_cnt; - caf->frame_cnt = frame_cnt; - - return 0; -} - -AVInputFormat ff_caf_demuxer = { - .name = "caf", - .long_name = NULL_IF_CONFIG_SMALL("Apple CAF (Core Audio Format)"), - .priv_data_size = sizeof(CaffContext), - .read_probe = probe, - .read_header = read_header, - .read_packet = read_packet, - .read_seek = read_seek, - .codec_tag = (const AVCodecTag* const []){ ff_codec_caf_tags, 0 }, -}; diff --git a/ffmpeg1/libavformat/cafenc.c b/ffmpeg1/libavformat/cafenc.c deleted file mode 100644 index 11bb055..0000000 --- a/ffmpeg1/libavformat/cafenc.c +++ /dev/null @@ -1,279 +0,0 @@ -/* - * Core Audio Format muxer - * Copyright (c) 2011 Carl Eugen Hoyos - * - * 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 "caf.h" -#include "isom.h" -#include "avio_internal.h" -#include "libavutil/intfloat.h" -#include "libavutil/dict.h" - -typedef struct { - int64_t data; - uint8_t *pkt_sizes; - int size_buffer_size; - int size_entries_used; - int packets; -} CAFContext; - -static uint32_t codec_flags(enum AVCodecID codec_id) { - switch (codec_id) { - case AV_CODEC_ID_PCM_F32BE: - case AV_CODEC_ID_PCM_F64BE: - return 1; //< kCAFLinearPCMFormatFlagIsFloat - case AV_CODEC_ID_PCM_S16LE: - case AV_CODEC_ID_PCM_S24LE: - case AV_CODEC_ID_PCM_S32LE: - return 2; //< kCAFLinearPCMFormatFlagIsLittleEndian - case AV_CODEC_ID_PCM_F32LE: - case AV_CODEC_ID_PCM_F64LE: - return 3; //< kCAFLinearPCMFormatFlagIsFloat | kCAFLinearPCMFormatFlagIsLittleEndian - default: - return 0; - } -} - -static uint32_t samples_per_packet(enum AVCodecID codec_id, int channels) { - switch (codec_id) { - case AV_CODEC_ID_PCM_S8: - case AV_CODEC_ID_PCM_S16LE: - case AV_CODEC_ID_PCM_S16BE: - case AV_CODEC_ID_PCM_S24LE: - case AV_CODEC_ID_PCM_S24BE: - case AV_CODEC_ID_PCM_S32LE: - case AV_CODEC_ID_PCM_S32BE: - case AV_CODEC_ID_PCM_F32LE: - case AV_CODEC_ID_PCM_F32BE: - case AV_CODEC_ID_PCM_F64LE: - case AV_CODEC_ID_PCM_F64BE: - case AV_CODEC_ID_PCM_ALAW: - case AV_CODEC_ID_PCM_MULAW: - return 1; - case AV_CODEC_ID_MACE3: - case AV_CODEC_ID_MACE6: - return 6; - case AV_CODEC_ID_ADPCM_IMA_QT: - return 64; - case AV_CODEC_ID_AMR_NB: - case AV_CODEC_ID_GSM: - case AV_CODEC_ID_ILBC: - case AV_CODEC_ID_QCELP: - return 160; - case AV_CODEC_ID_GSM_MS: - return 320; - case AV_CODEC_ID_MP1: - return 384; - case AV_CODEC_ID_MP2: - case AV_CODEC_ID_MP3: - return 1152; - case AV_CODEC_ID_AC3: - return 1536; - case AV_CODEC_ID_ALAC: - case AV_CODEC_ID_QDM2: - return 4096; - case AV_CODEC_ID_ADPCM_IMA_WAV: - return (1024 - 4 * channels) * 8 / (4 * channels) + 1; - case AV_CODEC_ID_ADPCM_MS: - return (1024 - 7 * channels) * 2 / channels + 2; - default: - return 0; - } -} - -static int caf_write_header(AVFormatContext *s) -{ - AVIOContext *pb = s->pb; - AVCodecContext *enc = s->streams[0]->codec; - CAFContext *caf = s->priv_data; - AVDictionaryEntry *t = NULL; - unsigned int codec_tag = ff_codec_get_tag(ff_codec_caf_tags, enc->codec_id); - int64_t chunk_size = 0; - - switch (enc->codec_id) { - case AV_CODEC_ID_AAC: - case AV_CODEC_ID_AC3: - av_log(s, AV_LOG_ERROR, "muxing codec currently unsupported\n"); - return AVERROR_PATCHWELCOME; - } - - switch (enc->codec_id) { - case AV_CODEC_ID_PCM_S8: - case AV_CODEC_ID_PCM_S16LE: - case AV_CODEC_ID_PCM_S16BE: - case AV_CODEC_ID_PCM_S24LE: - case AV_CODEC_ID_PCM_S24BE: - case AV_CODEC_ID_PCM_S32LE: - case AV_CODEC_ID_PCM_S32BE: - case AV_CODEC_ID_PCM_F32LE: - case AV_CODEC_ID_PCM_F32BE: - case AV_CODEC_ID_PCM_F64LE: - case AV_CODEC_ID_PCM_F64BE: - case AV_CODEC_ID_PCM_ALAW: - case AV_CODEC_ID_PCM_MULAW: - codec_tag = MKTAG('l','p','c','m'); - } - - if (!codec_tag) { - av_log(s, AV_LOG_ERROR, "unsupported codec\n"); - return AVERROR_INVALIDDATA; - } - - if (!enc->block_align && !pb->seekable) { - av_log(s, AV_LOG_ERROR, "Muxing variable packet size not supported on non seekable output\n"); - return AVERROR_INVALIDDATA; - } - - ffio_wfourcc(pb, "caff"); //< mFileType - avio_wb16(pb, 1); //< mFileVersion - avio_wb16(pb, 0); //< mFileFlags - - ffio_wfourcc(pb, "desc"); //< Audio Description chunk - avio_wb64(pb, 32); //< mChunkSize - avio_wb64(pb, av_double2int(enc->sample_rate)); //< mSampleRate - avio_wl32(pb, codec_tag); //< mFormatID - avio_wb32(pb, codec_flags(enc->codec_id)); //< mFormatFlags - avio_wb32(pb, enc->block_align); //< mBytesPerPacket - avio_wb32(pb, samples_per_packet(enc->codec_id, enc->channels)); //< mFramesPerPacket - avio_wb32(pb, enc->channels); //< mChannelsPerFrame - avio_wb32(pb, av_get_bits_per_sample(enc->codec_id)); //< mBitsPerChannel - - if (enc->channel_layout) { - ffio_wfourcc(pb, "chan"); - avio_wb64(pb, 12); - ff_mov_write_chan(pb, enc->channel_layout); - } - - if (enc->codec_id == AV_CODEC_ID_ALAC) { - ffio_wfourcc(pb, "kuki"); - avio_wb64(pb, 12 + enc->extradata_size); - avio_write(pb, "\0\0\0\14frmaalac", 12); - avio_write(pb, enc->extradata, enc->extradata_size); - } else if (enc->codec_id == AV_CODEC_ID_AMR_NB) { - ffio_wfourcc(pb, "kuki"); - avio_wb64(pb, 29); - avio_write(pb, "\0\0\0\14frmasamr", 12); - avio_wb32(pb, 0x11); /* size */ - avio_write(pb, "samrFFMP", 8); - avio_w8(pb, 0); /* decoder version */ - - avio_wb16(pb, 0x81FF); /* Mode set (all modes for AMR_NB) */ - avio_w8(pb, 0x00); /* Mode change period (no restriction) */ - avio_w8(pb, 0x01); /* Frames per sample */ - } else if (enc->codec_id == AV_CODEC_ID_QDM2) { - ffio_wfourcc(pb, "kuki"); - avio_wb64(pb, enc->extradata_size); - avio_write(pb, enc->extradata, enc->extradata_size); - } - - if (av_dict_count(s->metadata)) { - ffio_wfourcc(pb, "info"); //< Information chunk - while ((t = av_dict_get(s->metadata, "", t, AV_DICT_IGNORE_SUFFIX))) { - chunk_size += strlen(t->key) + strlen(t->value) + 2; - } - avio_wb64(pb, chunk_size + 4); - avio_wb32(pb, av_dict_count(s->metadata)); - t = NULL; - while ((t = av_dict_get(s->metadata, "", t, AV_DICT_IGNORE_SUFFIX))) { - avio_put_str(pb, t->key); - avio_put_str(pb, t->value); - } - } - - ffio_wfourcc(pb, "data"); //< Audio Data chunk - caf->data = avio_tell(pb); - avio_wb64(pb, -1); //< mChunkSize - avio_wb32(pb, 0); //< mEditCount - - avio_flush(pb); - return 0; -} - -static int caf_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - CAFContext *caf = s->priv_data; - - avio_write(s->pb, pkt->data, pkt->size); - if (!s->streams[0]->codec->block_align) { - void *pkt_sizes = caf->pkt_sizes; - int i, alloc_size = caf->size_entries_used + 5; - if (alloc_size < 0) { - caf->pkt_sizes = NULL; - } else { - caf->pkt_sizes = av_fast_realloc(caf->pkt_sizes, - &caf->size_buffer_size, - alloc_size); - } - if (!caf->pkt_sizes) { - av_free(pkt_sizes); - return AVERROR(ENOMEM); - } - for (i = 4; i > 0; i--) { - unsigned top = pkt->size >> i * 7; - if (top) - caf->pkt_sizes[caf->size_entries_used++] = 128 | top; - } - caf->pkt_sizes[caf->size_entries_used++] = pkt->size & 127; - caf->packets++; - } - return 0; -} - -static int caf_write_trailer(AVFormatContext *s) -{ - CAFContext *caf = s->priv_data; - AVIOContext *pb = s->pb; - AVCodecContext *enc = s->streams[0]->codec; - - if (pb->seekable) { - int64_t file_size = avio_tell(pb); - - avio_seek(pb, caf->data, SEEK_SET); - avio_wb64(pb, file_size - caf->data - 8); - avio_seek(pb, file_size, SEEK_SET); - if (!enc->block_align) { - ffio_wfourcc(pb, "pakt"); - avio_wb64(pb, caf->size_entries_used + 24); - avio_wb64(pb, caf->packets); ///< mNumberPackets - avio_wb64(pb, caf->packets * samples_per_packet(enc->codec_id, enc->channels)); ///< mNumberValidFrames - avio_wb32(pb, 0); ///< mPrimingFrames - avio_wb32(pb, 0); ///< mRemainderFrames - avio_write(pb, caf->pkt_sizes, caf->size_entries_used); - caf->size_buffer_size = 0; - } - avio_flush(pb); - } - av_freep(&caf->pkt_sizes); - return 0; -} - -AVOutputFormat ff_caf_muxer = { - .name = "caf", - .long_name = NULL_IF_CONFIG_SMALL("Apple CAF (Core Audio Format)"), - .mime_type = "audio/x-caf", - .extensions = "caf", - .priv_data_size = sizeof(CAFContext), - .audio_codec = AV_CODEC_ID_PCM_S16BE, - .video_codec = AV_CODEC_ID_NONE, - .write_header = caf_write_header, - .write_packet = caf_write_packet, - .write_trailer = caf_write_trailer, - .codec_tag = (const AVCodecTag* const []){ff_codec_caf_tags, 0}, -}; diff --git a/ffmpeg1/libavformat/cavsvideodec.c b/ffmpeg1/libavformat/cavsvideodec.c deleted file mode 100644 index c035128..0000000 --- a/ffmpeg1/libavformat/cavsvideodec.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * RAW Chinese AVS video demuxer - * Copyright (c) 2009 Stefan Gehrer - * - * 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 "rawdec.h" - -#define CAVS_SEQ_START_CODE 0x000001b0 -#define CAVS_PIC_I_START_CODE 0x000001b3 -#define CAVS_UNDEF_START_CODE 0x000001b4 -#define CAVS_PIC_PB_START_CODE 0x000001b6 -#define CAVS_VIDEO_EDIT_CODE 0x000001b7 -#define CAVS_PROFILE_JIZHUN 0x20 - -static int cavsvideo_probe(AVProbeData *p) -{ - uint32_t code= -1; - int pic=0, seq=0, slice_pos = 0; - int i; - - for(i=0; ibuf_size; i++){ - code = (code<<8) + p->buf[i]; - if ((code & 0xffffff00) == 0x100) { - if(code < CAVS_SEQ_START_CODE) { - /* slices have to be consecutive */ - if(code < slice_pos) - return 0; - slice_pos = code; - } else { - slice_pos = 0; - } - if (code == CAVS_SEQ_START_CODE) { - seq++; - /* check for the only currently supported profile */ - if(p->buf[i+1] != CAVS_PROFILE_JIZHUN) - return 0; - } else if ((code == CAVS_PIC_I_START_CODE) || - (code == CAVS_PIC_PB_START_CODE)) { - pic++; - } else if ((code == CAVS_UNDEF_START_CODE) || - (code > CAVS_VIDEO_EDIT_CODE)) { - return 0; - } - } - } - if(seq && seq*9<=pic*10) - return AVPROBE_SCORE_MAX/2; - return 0; -} - -FF_DEF_RAWVIDEO_DEMUXER(cavsvideo, "raw Chinese AVS (Audio Video Standard)", cavsvideo_probe, NULL, AV_CODEC_ID_CAVS) diff --git a/ffmpeg1/libavformat/cdg.c b/ffmpeg1/libavformat/cdg.c deleted file mode 100644 index 2d40d3d..0000000 --- a/ffmpeg1/libavformat/cdg.c +++ /dev/null @@ -1,79 +0,0 @@ -/* - * CD Graphics Demuxer - * Copyright (c) 2009 Michael Tison - * - * 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 "internal.h" - -#define CDG_PACKET_SIZE 24 -#define CDG_COMMAND 0x09 -#define CDG_MASK 0x3F - -static int read_header(AVFormatContext *s) -{ - AVStream *vst; - int ret; - - vst = avformat_new_stream(s, NULL); - if (!vst) - return AVERROR(ENOMEM); - - vst->codec->codec_type = AVMEDIA_TYPE_VIDEO; - vst->codec->codec_id = AV_CODEC_ID_CDGRAPHICS; - - /// 75 sectors/sec * 4 packets/sector = 300 packets/sec - avpriv_set_pts_info(vst, 32, 1, 300); - - ret = avio_size(s->pb); - if (ret > 0) - vst->duration = (ret * vst->time_base.den) / (CDG_PACKET_SIZE * 300); - - return 0; -} - -static int read_packet(AVFormatContext *s, AVPacket *pkt) -{ - int ret; - - while (1) { - ret = av_get_packet(s->pb, pkt, CDG_PACKET_SIZE); - if (ret < 1 || (pkt->data[0] & CDG_MASK) == CDG_COMMAND) - break; - av_free_packet(pkt); - } - - pkt->stream_index = 0; - pkt->dts= - pkt->pts= pkt->pos / CDG_PACKET_SIZE; - - if(ret>5 && (pkt->data[0]&0x3F) == 9 && (pkt->data[1]&0x3F)==1 && !(pkt->data[2+2+1] & 0x0F)){ - pkt->flags = AV_PKT_FLAG_KEY; - } - return ret; -} - -AVInputFormat ff_cdg_demuxer = { - .name = "cdg", - .long_name = NULL_IF_CONFIG_SMALL("CD Graphics"), - .read_header = read_header, - .read_packet = read_packet, - .flags = AVFMT_GENERIC_INDEX, - .extensions = "cdg", -}; diff --git a/ffmpeg1/libavformat/cdxl.c b/ffmpeg1/libavformat/cdxl.c deleted file mode 100644 index 185b745..0000000 --- a/ffmpeg1/libavformat/cdxl.c +++ /dev/null @@ -1,231 +0,0 @@ -/* - * CDXL demuxer - * Copyright (c) 2011-2012 Paul B Mahol - * - * 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 "libavutil/channel_layout.h" -#include "libavutil/intreadwrite.h" -#include "libavutil/parseutils.h" -#include "libavutil/opt.h" -#include "avformat.h" -#include "internal.h" - -#define CDXL_HEADER_SIZE 32 - -typedef struct CDXLDemuxContext { - AVClass *class; - int sample_rate; - char *framerate; - AVRational fps; - int read_chunk; - uint8_t header[CDXL_HEADER_SIZE]; - int video_stream_index; - int audio_stream_index; -} CDXLDemuxContext; - -static int cdxl_read_probe(AVProbeData *p) -{ - int score = AVPROBE_SCORE_MAX / 2 + 10; - - if (p->buf_size < CDXL_HEADER_SIZE) - return 0; - - /* reserved bytes should always be set to 0 */ - if (AV_RN64(&p->buf[24]) || AV_RN16(&p->buf[10])) - return 0; - - /* check type */ - if (p->buf[0] != 1) - return 0; - - /* check palette size */ - if (AV_RB16(&p->buf[20]) > 512) - return 0; - - /* check number of planes */ - if (p->buf[18] || !p->buf[19]) - return 0; - - /* check widh and height */ - if (!AV_RN16(&p->buf[14]) || !AV_RN16(&p->buf[16])) - return 0; - - /* chunk size */ - if (AV_RB32(&p->buf[2]) < AV_RB16(&p->buf[22]) + AV_RB16(&p->buf[20]) + CDXL_HEADER_SIZE) - return 0; - - /* previous chunk size */ - if (AV_RN32(&p->buf[6])) - score /= 2; - - /* current frame number, usually starts from 1 */ - if (AV_RB16(&p->buf[12]) != 1) - score /= 2; - - return score; -} - -static int cdxl_read_header(AVFormatContext *s) -{ - CDXLDemuxContext *cdxl = s->priv_data; - int ret; - - if (cdxl->framerate && (ret = av_parse_video_rate(&cdxl->fps, cdxl->framerate)) < 0) { - av_log(s, AV_LOG_ERROR, - "Could not parse framerate: %s.\n", cdxl->framerate); - return ret; - } - - cdxl->read_chunk = 0; - cdxl->video_stream_index = -1; - cdxl->audio_stream_index = -1; - - s->ctx_flags |= AVFMTCTX_NOHEADER; - - return 0; -} - -static int cdxl_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - CDXLDemuxContext *cdxl = s->priv_data; - AVIOContext *pb = s->pb; - uint32_t current_size, video_size, image_size; - uint16_t audio_size, palette_size, width, height; - int64_t pos; - int ret; - - if (url_feof(pb)) - return AVERROR_EOF; - - pos = avio_tell(pb); - if (!cdxl->read_chunk && - avio_read(pb, cdxl->header, CDXL_HEADER_SIZE) != CDXL_HEADER_SIZE) - return AVERROR_EOF; - if (cdxl->header[0] != 1) { - av_log(s, AV_LOG_ERROR, "non-standard cdxl file\n"); - return AVERROR_INVALIDDATA; - } - - current_size = AV_RB32(&cdxl->header[2]); - width = AV_RB16(&cdxl->header[14]); - height = AV_RB16(&cdxl->header[16]); - palette_size = AV_RB16(&cdxl->header[20]); - audio_size = AV_RB16(&cdxl->header[22]); - image_size = FFALIGN(width, 16) * height * cdxl->header[19] / 8; - video_size = palette_size + image_size; - - if (palette_size > 512) - return AVERROR_INVALIDDATA; - if (current_size < (uint64_t)audio_size + video_size + CDXL_HEADER_SIZE) - return AVERROR_INVALIDDATA; - - if (cdxl->read_chunk && audio_size) { - if (cdxl->audio_stream_index == -1) { - AVStream *st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_tag = 0; - st->codec->codec_id = AV_CODEC_ID_PCM_S8; - if (cdxl->header[1] & 0x10) { - st->codec->channels = 2; - st->codec->channel_layout = AV_CH_LAYOUT_STEREO; - } else { - st->codec->channels = 1; - st->codec->channel_layout = AV_CH_LAYOUT_MONO; - } - st->codec->sample_rate = cdxl->sample_rate; - st->start_time = 0; - cdxl->audio_stream_index = st->index; - avpriv_set_pts_info(st, 64, 1, cdxl->sample_rate); - } - - ret = av_get_packet(pb, pkt, audio_size); - if (ret < 0) - return ret; - pkt->stream_index = cdxl->audio_stream_index; - pkt->pos = pos; - pkt->duration = audio_size; - cdxl->read_chunk = 0; - } else { - if (cdxl->video_stream_index == -1) { - AVStream *st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_tag = 0; - st->codec->codec_id = AV_CODEC_ID_CDXL; - st->codec->width = width; - st->codec->height = height; - st->start_time = 0; - cdxl->video_stream_index = st->index; - if (cdxl->framerate) - avpriv_set_pts_info(st, 64, cdxl->fps.den, cdxl->fps.num); - else - avpriv_set_pts_info(st, 64, 1, cdxl->sample_rate); - } - - if (av_new_packet(pkt, video_size + CDXL_HEADER_SIZE) < 0) - return AVERROR(ENOMEM); - memcpy(pkt->data, cdxl->header, CDXL_HEADER_SIZE); - ret = avio_read(pb, pkt->data + CDXL_HEADER_SIZE, video_size); - if (ret < 0) { - av_free_packet(pkt); - return ret; - } - av_shrink_packet(pkt, CDXL_HEADER_SIZE + ret); - pkt->stream_index = cdxl->video_stream_index; - pkt->flags |= AV_PKT_FLAG_KEY; - pkt->pos = pos; - pkt->duration = cdxl->framerate ? 1 : audio_size ? audio_size : 220; - cdxl->read_chunk = audio_size; - } - - if (!cdxl->read_chunk) - avio_skip(pb, current_size - audio_size - video_size - CDXL_HEADER_SIZE); - return ret; -} - -#define OFFSET(x) offsetof(CDXLDemuxContext, x) -static const AVOption cdxl_options[] = { - { "sample_rate", "", OFFSET(sample_rate), AV_OPT_TYPE_INT, { .i64 = 11025 }, 1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM }, - { "framerate", "", OFFSET(framerate), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, AV_OPT_FLAG_DECODING_PARAM }, - { NULL }, -}; - -static const AVClass cdxl_demuxer_class = { - .class_name = "CDXL demuxer", - .item_name = av_default_item_name, - .option = cdxl_options, - .version = LIBAVUTIL_VERSION_INT, -}; - -AVInputFormat ff_cdxl_demuxer = { - .name = "cdxl", - .long_name = NULL_IF_CONFIG_SMALL("Commodore CDXL video"), - .priv_data_size = sizeof(CDXLDemuxContext), - .read_probe = cdxl_read_probe, - .read_header = cdxl_read_header, - .read_packet = cdxl_read_packet, - .extensions = "cdxl,xl", - .flags = AVFMT_GENERIC_INDEX, - .priv_class = &cdxl_demuxer_class, -}; diff --git a/ffmpeg1/libavformat/concat.c b/ffmpeg1/libavformat/concat.c deleted file mode 100644 index f97354c..0000000 --- a/ffmpeg1/libavformat/concat.c +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Concat URL protocol - * Copyright (c) 2006 Steve Lhomme - * Copyright (c) 2007 Wolfram Gloger - * Copyright (c) 2010 Michele Orrù - * - * 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 "libavutil/avstring.h" -#include "libavutil/mem.h" -#include "url.h" - -#define AV_CAT_SEPARATOR "|" - -struct concat_nodes { - URLContext *uc; ///< node's URLContext - int64_t size; ///< url filesize -}; - -struct concat_data { - struct concat_nodes *nodes; ///< list of nodes to concat - size_t length; ///< number of cat'ed nodes - size_t current; ///< index of currently read node -}; - -static av_cold int concat_close(URLContext *h) -{ - int err = 0; - size_t i; - struct concat_data *data = h->priv_data; - struct concat_nodes *nodes = data->nodes; - - for (i = 0; i != data->length; i++) - err |= ffurl_close(nodes[i].uc); - - av_freep(&data->nodes); - - return err < 0 ? -1 : 0; -} - -static av_cold int concat_open(URLContext *h, const char *uri, int flags) -{ - char *node_uri = NULL, *tmp_uri; - int err = 0; - int64_t size; - size_t len, i; - URLContext *uc; - struct concat_data *data = h->priv_data; - struct concat_nodes *nodes; - - av_strstart(uri, "concat:", &uri); - - for (i = 0, len = 1; uri[i]; i++) - if (uri[i] == *AV_CAT_SEPARATOR) - /* integer overflow */ - if (++len == UINT_MAX / sizeof(*nodes)) { - av_freep(&h->priv_data); - return AVERROR(ENAMETOOLONG); - } - - if (!(nodes = av_malloc(sizeof(*nodes) * len))) { - return AVERROR(ENOMEM); - } else - data->nodes = nodes; - - /* handle input */ - if (!*uri) - err = AVERROR(ENOENT); - for (i = 0; *uri; i++) { - /* parsing uri */ - len = strcspn(uri, AV_CAT_SEPARATOR); - if (!(tmp_uri = av_realloc(node_uri, len+1))) { - err = AVERROR(ENOMEM); - break; - } else - node_uri = tmp_uri; - av_strlcpy(node_uri, uri, len+1); - uri += len + strspn(uri+len, AV_CAT_SEPARATOR); - - /* creating URLContext */ - if ((err = ffurl_open(&uc, node_uri, flags, - &h->interrupt_callback, NULL)) < 0) - break; - - /* creating size */ - if ((size = ffurl_size(uc)) < 0) { - ffurl_close(uc); - err = AVERROR(ENOSYS); - break; - } - - /* assembling */ - nodes[i].uc = uc; - nodes[i].size = size; - } - av_free(node_uri); - data->length = i; - - if (err < 0) - concat_close(h); - else if (!(nodes = av_realloc(nodes, data->length * sizeof(*nodes)))) { - concat_close(h); - err = AVERROR(ENOMEM); - } else - data->nodes = nodes; - return err; -} - -static int concat_read(URLContext *h, unsigned char *buf, int size) -{ - int result, total = 0; - struct concat_data *data = h->priv_data; - struct concat_nodes *nodes = data->nodes; - size_t i = data->current; - - while (size > 0) { - result = ffurl_read(nodes[i].uc, buf, size); - if (result < 0) - return total ? total : result; - if (!result) - if (i + 1 == data->length || - ffurl_seek(nodes[++i].uc, 0, SEEK_SET) < 0) - break; - total += result; - buf += result; - size -= result; - } - data->current = i; - return total; -} - -static int64_t concat_seek(URLContext *h, int64_t pos, int whence) -{ - int64_t result; - struct concat_data *data = h->priv_data; - struct concat_nodes *nodes = data->nodes; - size_t i; - - switch (whence) { - case SEEK_END: - for (i = data->length - 1; - i && pos < -nodes[i].size; - i--) - pos += nodes[i].size; - break; - case SEEK_CUR: - /* get the absolute position */ - for (i = 0; i != data->current; i++) - pos += nodes[i].size; - pos += ffurl_seek(nodes[i].uc, 0, SEEK_CUR); - whence = SEEK_SET; - /* fall through with the absolute position */ - case SEEK_SET: - for (i = 0; i != data->length - 1 && pos >= nodes[i].size; i++) - pos -= nodes[i].size; - break; - default: - return AVERROR(EINVAL); - } - - result = ffurl_seek(nodes[i].uc, pos, whence); - if (result >= 0) { - data->current = i; - while (i) - result += nodes[--i].size; - } - return result; -} - -URLProtocol ff_concat_protocol = { - .name = "concat", - .url_open = concat_open, - .url_read = concat_read, - .url_seek = concat_seek, - .url_close = concat_close, - .priv_data_size = sizeof(struct concat_data), -}; diff --git a/ffmpeg1/libavformat/concatdec.c b/ffmpeg1/libavformat/concatdec.c deleted file mode 100644 index 5359ad1..0000000 --- a/ffmpeg1/libavformat/concatdec.c +++ /dev/null @@ -1,405 +0,0 @@ -/* - * Copyright (c) 2012 Nicolas George - * - * 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 "libavutil/avstring.h" -#include "libavutil/opt.h" -#include "libavutil/parseutils.h" -#include "avformat.h" -#include "internal.h" - -typedef struct { - char *url; - int64_t start_time; - int64_t duration; -} ConcatFile; - -typedef struct { - AVClass *class; - ConcatFile *files; - ConcatFile *cur_file; - unsigned nb_files; - AVFormatContext *avf; - int safe; - int seekable; -} ConcatContext; - -static int concat_probe(AVProbeData *probe) -{ - return memcmp(probe->buf, "ffconcat version 1.0", 20) ? - 0 : AVPROBE_SCORE_MAX; -} - -static char *get_keyword(uint8_t **cursor) -{ - char *ret = *cursor += strspn(*cursor, SPACE_CHARS); - *cursor += strcspn(*cursor, SPACE_CHARS); - if (**cursor) { - *((*cursor)++) = 0; - *cursor += strspn(*cursor, SPACE_CHARS); - } - return ret; -} - -static int safe_filename(const char *f) -{ - const char *start = f; - - for (; *f; f++) { - /* A-Za-z0-9_- */ - if (!((unsigned)((*f | 32) - 'a') < 26 || - (unsigned)(*f - '0') < 10 || *f == '_' || *f == '-')) { - if (f == start) - return 0; - else if (*f == '/') - start = f + 1; - else if (*f != '.') - return 0; - } - } - return 1; -} - -#define FAIL(retcode) do { ret = (retcode); goto fail; } while(0) - -static int add_file(AVFormatContext *avf, char *filename, ConcatFile **rfile, - unsigned *nb_files_alloc) -{ - ConcatContext *cat = avf->priv_data; - ConcatFile *file; - char *url = NULL; - size_t url_len; - int ret; - - if (cat->safe > 0 && !safe_filename(filename)) { - av_log(avf, AV_LOG_ERROR, "Unsafe file name '%s'\n", filename); - FAIL(AVERROR(EPERM)); - } - url_len = strlen(avf->filename) + strlen(filename) + 16; - if (!(url = av_malloc(url_len))) - FAIL(AVERROR(ENOMEM)); - ff_make_absolute_url(url, url_len, avf->filename, filename); - av_freep(&filename); - - if (cat->nb_files >= *nb_files_alloc) { - size_t n = FFMAX(*nb_files_alloc * 2, 16); - ConcatFile *new_files; - if (n <= cat->nb_files || n > SIZE_MAX / sizeof(*cat->files) || - !(new_files = av_realloc(cat->files, n * sizeof(*cat->files)))) - FAIL(AVERROR(ENOMEM)); - cat->files = new_files; - *nb_files_alloc = n; - } - - file = &cat->files[cat->nb_files++]; - memset(file, 0, sizeof(*file)); - *rfile = file; - - file->url = url; - file->start_time = AV_NOPTS_VALUE; - file->duration = AV_NOPTS_VALUE; - - return 0; - -fail: - av_free(url); - av_free(filename); - return ret; -} - -static int open_file(AVFormatContext *avf, unsigned fileno) -{ - ConcatContext *cat = avf->priv_data; - ConcatFile *file = &cat->files[fileno]; - int ret; - - if (cat->avf) - avformat_close_input(&cat->avf); - if ((ret = avformat_open_input(&cat->avf, file->url, NULL, NULL)) < 0 || - (ret = avformat_find_stream_info(cat->avf, NULL)) < 0) { - av_log(avf, AV_LOG_ERROR, "Impossible to open '%s'\n", file->url); - return ret; - } - cat->cur_file = file; - if (file->start_time == AV_NOPTS_VALUE) - file->start_time = !fileno ? 0 : - cat->files[fileno - 1].start_time + - cat->files[fileno - 1].duration; - return 0; -} - -static int concat_read_close(AVFormatContext *avf) -{ - ConcatContext *cat = avf->priv_data; - unsigned i; - - if (cat->avf) - avformat_close_input(&cat->avf); - for (i = 0; i < cat->nb_files; i++) - av_freep(&cat->files[i].url); - av_freep(&cat->files); - return 0; -} - -static int concat_read_header(AVFormatContext *avf) -{ - ConcatContext *cat = avf->priv_data; - uint8_t buf[4096]; - uint8_t *cursor, *keyword; - int ret, line = 0, i; - unsigned nb_files_alloc = 0; - ConcatFile *file = NULL; - AVStream *st, *source_st; - int64_t time = 0; - - while (1) { - if ((ret = ff_get_line(avf->pb, buf, sizeof(buf))) <= 0) - break; - line++; - cursor = buf; - keyword = get_keyword(&cursor); - if (!*keyword || *keyword == '#') - continue; - - if (!strcmp(keyword, "file")) { - char *filename = av_get_token((const char **)&cursor, SPACE_CHARS); - if (!filename) { - av_log(avf, AV_LOG_ERROR, "Line %d: filename required\n", line); - FAIL(AVERROR_INVALIDDATA); - } - if ((ret = add_file(avf, filename, &file, &nb_files_alloc)) < 0) - FAIL(ret); - } else if (!strcmp(keyword, "duration")) { - char *dur_str = get_keyword(&cursor); - int64_t dur; - if (!file) { - av_log(avf, AV_LOG_ERROR, "Line %d: duration without file\n", - line); - FAIL(AVERROR_INVALIDDATA); - } - if ((ret = av_parse_time(&dur, dur_str, 1)) < 0) { - av_log(avf, AV_LOG_ERROR, "Line %d: invalid duration '%s'\n", - line, dur_str); - FAIL(ret); - } - file->duration = dur; - } else if (!strcmp(keyword, "ffconcat")) { - char *ver_kw = get_keyword(&cursor); - char *ver_val = get_keyword(&cursor); - if (strcmp(ver_kw, "version") || strcmp(ver_val, "1.0")) { - av_log(avf, AV_LOG_ERROR, "Line %d: invalid version\n", line); - FAIL(AVERROR_INVALIDDATA); - } - if (cat->safe < 0) - cat->safe = 1; - } else { - av_log(avf, AV_LOG_ERROR, "Line %d: unknown keyword '%s'\n", - line, keyword); - FAIL(AVERROR_INVALIDDATA); - } - } - if (ret < 0) - FAIL(ret); - - for (i = 0; i < cat->nb_files; i++) { - if (cat->files[i].start_time == AV_NOPTS_VALUE) - cat->files[i].start_time = time; - else - time = cat->files[i].start_time; - if (cat->files[i].duration == AV_NOPTS_VALUE) - break; - time += cat->files[i].duration; - } - if (i == cat->nb_files) { - avf->duration = time; - cat->seekable = 1; - } - - if ((ret = open_file(avf, 0)) < 0) - FAIL(ret); - for (i = 0; i < cat->avf->nb_streams; i++) { - if (!(st = avformat_new_stream(avf, NULL))) - FAIL(AVERROR(ENOMEM)); - source_st = cat->avf->streams[i]; - if ((ret = avcodec_copy_context(st->codec, source_st->codec)) < 0) - FAIL(ret); - st->r_frame_rate = source_st->r_frame_rate; - st->avg_frame_rate = source_st->avg_frame_rate; - st->time_base = source_st->time_base; - st->sample_aspect_ratio = source_st->sample_aspect_ratio; - } - - return 0; - -fail: - concat_read_close(avf); - return ret; -} - -static int open_next_file(AVFormatContext *avf) -{ - ConcatContext *cat = avf->priv_data; - unsigned fileno = cat->cur_file - cat->files; - - if (cat->cur_file->duration == AV_NOPTS_VALUE) - cat->cur_file->duration = cat->avf->duration; - - if (++fileno >= cat->nb_files) - return AVERROR_EOF; - return open_file(avf, fileno); -} - -static int concat_read_packet(AVFormatContext *avf, AVPacket *pkt) -{ - ConcatContext *cat = avf->priv_data; - int ret; - int64_t delta; - - while (1) { - if ((ret = av_read_frame(cat->avf, pkt)) != AVERROR_EOF || - (ret = open_next_file(avf)) < 0) - break; - } - delta = av_rescale_q(cat->cur_file->start_time - cat->avf->start_time, - AV_TIME_BASE_Q, - cat->avf->streams[pkt->stream_index]->time_base); - if (pkt->pts != AV_NOPTS_VALUE) - pkt->pts += delta; - if (pkt->dts != AV_NOPTS_VALUE) - pkt->dts += delta; - return ret; -} - -static void rescale_interval(AVRational tb_in, AVRational tb_out, - int64_t *min_ts, int64_t *ts, int64_t *max_ts) -{ - *ts = av_rescale_q (* ts, tb_in, tb_out); - *min_ts = av_rescale_q_rnd(*min_ts, tb_in, tb_out, - AV_ROUND_UP | AV_ROUND_PASS_MINMAX); - *max_ts = av_rescale_q_rnd(*max_ts, tb_in, tb_out, - AV_ROUND_DOWN | AV_ROUND_PASS_MINMAX); -} - -static int try_seek(AVFormatContext *avf, int stream, - int64_t min_ts, int64_t ts, int64_t max_ts, int flags) -{ - ConcatContext *cat = avf->priv_data; - int64_t t0 = cat->cur_file->start_time - cat->avf->start_time; - - ts -= t0; - min_ts = min_ts == INT64_MIN ? INT64_MIN : min_ts - t0; - max_ts = max_ts == INT64_MAX ? INT64_MAX : max_ts - t0; - if (stream >= 0) { - if (stream >= cat->avf->nb_streams) - return AVERROR(EIO); - rescale_interval(AV_TIME_BASE_Q, cat->avf->streams[stream]->time_base, - &min_ts, &ts, &max_ts); - } - return avformat_seek_file(cat->avf, stream, min_ts, ts, max_ts, flags); -} - -static int real_seek(AVFormatContext *avf, int stream, - int64_t min_ts, int64_t ts, int64_t max_ts, int flags) -{ - ConcatContext *cat = avf->priv_data; - int ret, left, right; - - if (stream >= 0) { - if (stream >= avf->nb_streams) - return AVERROR(EINVAL); - rescale_interval(avf->streams[stream]->time_base, AV_TIME_BASE_Q, - &min_ts, &ts, &max_ts); - } - - left = 0; - right = cat->nb_files; - while (right - left > 1) { - int mid = (left + right) / 2; - if (ts < cat->files[mid].start_time) - right = mid; - else - left = mid; - } - - if ((ret = open_file(avf, left)) < 0) - return ret; - - ret = try_seek(avf, stream, min_ts, ts, max_ts, flags); - if (ret < 0 && !(flags & AVSEEK_FLAG_BACKWARD) && - left < cat->nb_files - 1 && - cat->files[left + 1].start_time < max_ts) { - if ((ret = open_file(avf, left + 1)) < 0) - return ret; - ret = try_seek(avf, stream, min_ts, ts, max_ts, flags); - } - return ret; -} - -static int concat_seek(AVFormatContext *avf, int stream, - int64_t min_ts, int64_t ts, int64_t max_ts, int flags) -{ - ConcatContext *cat = avf->priv_data; - ConcatFile *cur_file_saved = cat->cur_file; - AVFormatContext *cur_avf_saved = cat->avf; - int ret; - - if (!cat->seekable) - return AVERROR(ESPIPE); /* XXX: can we use it? */ - if (flags & (AVSEEK_FLAG_BYTE | AVSEEK_FLAG_FRAME)) - return AVERROR(ENOSYS); - cat->avf = NULL; - if ((ret = real_seek(avf, stream, min_ts, ts, max_ts, flags)) < 0) { - if (cat->avf) - avformat_close_input(&cat->avf); - cat->avf = cur_avf_saved; - cat->cur_file = cur_file_saved; - } else { - avformat_close_input(&cur_avf_saved); - } - return ret; -} - -#define OFFSET(x) offsetof(ConcatContext, x) -#define DEC AV_OPT_FLAG_DECODING_PARAM - -static const AVOption options[] = { - { "safe", "enable safe mode", - OFFSET(safe), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, DEC }, - { NULL } -}; - -static const AVClass concat_class = { - .class_name = "concat demuxer", - .item_name = av_default_item_name, - .option = options, - .version = LIBAVUTIL_VERSION_INT, -}; - - -AVInputFormat ff_concat_demuxer = { - .name = "concat", - .long_name = NULL_IF_CONFIG_SMALL("Virtual concatenation script"), - .priv_data_size = sizeof(ConcatContext), - .read_probe = concat_probe, - .read_header = concat_read_header, - .read_packet = concat_read_packet, - .read_close = concat_read_close, - .read_seek2 = concat_seek, - .priv_class = &concat_class, -}; diff --git a/ffmpeg1/libavformat/crcenc.c b/ffmpeg1/libavformat/crcenc.c deleted file mode 100644 index ac06380..0000000 --- a/ffmpeg1/libavformat/crcenc.c +++ /dev/null @@ -1,67 +0,0 @@ -/* - * CRC encoder (for codec/format testing) - * Copyright (c) 2002 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 "libavutil/adler32.h" -#include "avformat.h" - -typedef struct CRCState { - uint32_t crcval; -} CRCState; - -static int crc_write_header(struct AVFormatContext *s) -{ - CRCState *crc = s->priv_data; - - /* init CRC */ - crc->crcval = 1; - - return 0; -} - -static int crc_write_packet(struct AVFormatContext *s, AVPacket *pkt) -{ - CRCState *crc = s->priv_data; - crc->crcval = av_adler32_update(crc->crcval, pkt->data, pkt->size); - return 0; -} - -static int crc_write_trailer(struct AVFormatContext *s) -{ - CRCState *crc = s->priv_data; - char buf[64]; - - snprintf(buf, sizeof(buf), "CRC=0x%08x\n", crc->crcval); - avio_write(s->pb, buf, strlen(buf)); - - return 0; -} - -AVOutputFormat ff_crc_muxer = { - .name = "crc", - .long_name = NULL_IF_CONFIG_SMALL("CRC testing"), - .priv_data_size = sizeof(CRCState), - .audio_codec = AV_CODEC_ID_PCM_S16LE, - .video_codec = AV_CODEC_ID_RAWVIDEO, - .write_header = crc_write_header, - .write_packet = crc_write_packet, - .write_trailer = crc_write_trailer, - .flags = AVFMT_NOTIMESTAMPS, -}; diff --git a/ffmpeg1/libavformat/crypto.c b/ffmpeg1/libavformat/crypto.c deleted file mode 100644 index 5d518be..0000000 --- a/ffmpeg1/libavformat/crypto.c +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Decryption protocol handler - * Copyright (c) 2011 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 - */ - -#include "avformat.h" -#include "libavutil/aes.h" -#include "libavutil/avstring.h" -#include "libavutil/opt.h" -#include "internal.h" -#include "url.h" - -#define MAX_BUFFER_BLOCKS 150 -#define BLOCKSIZE 16 - -typedef struct { - const AVClass *class; - URLContext *hd; - uint8_t inbuffer [BLOCKSIZE*MAX_BUFFER_BLOCKS], - outbuffer[BLOCKSIZE*MAX_BUFFER_BLOCKS]; - uint8_t *outptr; - int indata, indata_used, outdata; - int eof; - uint8_t *key; - int keylen; - uint8_t *iv; - int ivlen; - struct AVAES *aes; -} CryptoContext; - -#define OFFSET(x) offsetof(CryptoContext, x) -#define D AV_OPT_FLAG_DECODING_PARAM -static const AVOption options[] = { - {"key", "AES decryption key", OFFSET(key), AV_OPT_TYPE_BINARY, .flags = D }, - {"iv", "AES decryption initialization vector", OFFSET(iv), AV_OPT_TYPE_BINARY, .flags = D }, - { NULL } -}; - -static const AVClass crypto_class = { - .class_name = "crypto", - .item_name = av_default_item_name, - .option = options, - .version = LIBAVUTIL_VERSION_INT, -}; - -static int crypto_open2(URLContext *h, const char *uri, int flags, AVDictionary **options) -{ - const char *nested_url; - int ret = 0; - CryptoContext *c = h->priv_data; - - if (!av_strstart(uri, "crypto+", &nested_url) && - !av_strstart(uri, "crypto:", &nested_url)) { - av_log(h, AV_LOG_ERROR, "Unsupported url %s\n", uri); - ret = AVERROR(EINVAL); - goto err; - } - - if (c->keylen < BLOCKSIZE || c->ivlen < BLOCKSIZE) { - av_log(h, AV_LOG_ERROR, "Key or IV not set\n"); - ret = AVERROR(EINVAL); - goto err; - } - if (flags & AVIO_FLAG_WRITE) { - av_log(h, AV_LOG_ERROR, "Only decryption is supported currently\n"); - ret = AVERROR(ENOSYS); - goto err; - } - if ((ret = ffurl_open(&c->hd, nested_url, AVIO_FLAG_READ, - &h->interrupt_callback, options)) < 0) { - av_log(h, AV_LOG_ERROR, "Unable to open input\n"); - goto err; - } - c->aes = av_aes_alloc(); - if (!c->aes) { - ret = AVERROR(ENOMEM); - goto err; - } - - av_aes_init(c->aes, c->key, 128, 1); - - h->is_streamed = 1; - -err: - return ret; -} - -static int crypto_read(URLContext *h, uint8_t *buf, int size) -{ - CryptoContext *c = h->priv_data; - int blocks; -retry: - if (c->outdata > 0) { - size = FFMIN(size, c->outdata); - memcpy(buf, c->outptr, size); - c->outptr += size; - c->outdata -= size; - return size; - } - // We avoid using the last block until we've found EOF, - // since we'll remove PKCS7 padding at the end. So make - // sure we've got at least 2 blocks, so we can decrypt - // at least one. - while (c->indata - c->indata_used < 2*BLOCKSIZE) { - int n = ffurl_read(c->hd, c->inbuffer + c->indata, - sizeof(c->inbuffer) - c->indata); - if (n <= 0) { - c->eof = 1; - break; - } - c->indata += n; - } - blocks = (c->indata - c->indata_used) / BLOCKSIZE; - if (!blocks) - return AVERROR_EOF; - if (!c->eof) - blocks--; - av_aes_crypt(c->aes, c->outbuffer, c->inbuffer + c->indata_used, blocks, - c->iv, 1); - c->outdata = BLOCKSIZE * blocks; - c->outptr = c->outbuffer; - c->indata_used += BLOCKSIZE * blocks; - if (c->indata_used >= sizeof(c->inbuffer)/2) { - memmove(c->inbuffer, c->inbuffer + c->indata_used, - c->indata - c->indata_used); - c->indata -= c->indata_used; - c->indata_used = 0; - } - if (c->eof) { - // Remove PKCS7 padding at the end - int padding = c->outbuffer[c->outdata - 1]; - c->outdata -= padding; - } - goto retry; -} - -static int crypto_close(URLContext *h) -{ - CryptoContext *c = h->priv_data; - if (c->hd) - ffurl_close(c->hd); - av_freep(&c->aes); - return 0; -} - -URLProtocol ff_crypto_protocol = { - .name = "crypto", - .url_open2 = crypto_open2, - .url_read = crypto_read, - .url_close = crypto_close, - .priv_data_size = sizeof(CryptoContext), - .priv_data_class = &crypto_class, - .flags = URL_PROTOCOL_FLAG_NESTED_SCHEME, -}; diff --git a/ffmpeg1/libavformat/cutils.c b/ffmpeg1/libavformat/cutils.c deleted file mode 100644 index 0458a2d..0000000 --- a/ffmpeg1/libavformat/cutils.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * various simple utilities for libavformat - * Copyright (c) 2000, 2001, 2002 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 "internal.h" - -#define ISLEAP(y) (((y) % 4 == 0) && (((y) % 100) != 0 || ((y) % 400) == 0)) -#define LEAPS_COUNT(y) ((y)/4 - (y)/100 + (y)/400) - -/* This is our own gmtime_r. It differs from its POSIX counterpart in a - couple of places, though. */ -struct tm *ff_brktimegm(time_t secs, struct tm *tm) -{ - int days, y, ny, m; - int md[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; - - days = secs / 86400; - secs %= 86400; - tm->tm_hour = secs / 3600; - tm->tm_min = (secs % 3600) / 60; - tm->tm_sec = secs % 60; - - /* oh well, may be someone some day will invent a formula for this stuff */ - y = 1970; /* start "guessing" */ - while (days > 365) { - ny = (y + days/366); - days -= (ny - y) * 365 + LEAPS_COUNT(ny - 1) - LEAPS_COUNT(y - 1); - y = ny; - } - if (days==365 && !ISLEAP(y)) { days=0; y++; } - md[1] = ISLEAP(y)?29:28; - for (m=0; days >= md[m]; m++) - days -= md[m]; - - tm->tm_year = y; /* unlike gmtime_r we store complete year here */ - tm->tm_mon = m+1; /* unlike gmtime_r tm_mon is from 1 to 12 */ - tm->tm_mday = days+1; - - return tm; -} diff --git a/ffmpeg1/libavformat/data_uri.c b/ffmpeg1/libavformat/data_uri.c deleted file mode 100644 index 1598b99..0000000 --- a/ffmpeg1/libavformat/data_uri.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (c) 2012 Nicolas George - * - * 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 -#include "libavutil/avstring.h" -#include "libavutil/base64.h" -#include "url.h" - -typedef struct { - const uint8_t *data; - void *tofree; - size_t size; - size_t pos; -} DataContext; - -static av_cold int data_open(URLContext *h, const char *uri, int flags) -{ - DataContext *dc = h->priv_data; - const char *data, *opt, *next; - char *ddata; - int ret, base64 = 0; - size_t in_size; - - /* data:content/type[;base64],payload */ - - av_strstart(uri, "data:", &uri); - data = strchr(uri, ','); - if (!data) { - av_log(h, AV_LOG_ERROR, "No ',' delimiter in URI\n"); - return AVERROR(EINVAL); - } - opt = uri; - while (opt < data) { - next = av_x_if_null(memchr(opt, ';', data - opt), data); - if (opt == uri) { - if (!memchr(opt, '/', next - opt)) { /* basic validity check */ - av_log(h, AV_LOG_ERROR, "Invalid content-type '%.*s'\n", - (int)(next - opt), opt); - return AVERROR(EINVAL); - } - av_log(h, AV_LOG_VERBOSE, "Content-type: %.*s\n", - (int)(next - opt), opt); - } else { - if (!av_strncasecmp(opt, "base64", next - opt)) { - base64 = 1; - } else { - av_log(h, AV_LOG_VERBOSE, "Ignoring option '%.*s'\n", - (int)(next - opt), opt); - } - } - opt = next + 1; - } - - data++; - in_size = strlen(data); - if (base64) { - size_t out_size = 3 * (in_size / 4) + 1; - - if (out_size > INT_MAX || !(ddata = av_malloc(out_size))) - return AVERROR(ENOMEM); - if ((ret = av_base64_decode(ddata, data, out_size)) < 0) { - av_free(ddata); - av_log(h, AV_LOG_ERROR, "Invalid base64 in URI\n"); - return ret; - } - dc->data = dc->tofree = ddata; - dc->size = ret; - } else { - dc->data = data; - dc->size = in_size; - } - return 0; -} - -static av_cold int data_close(URLContext *h) -{ - DataContext *dc = h->priv_data; - - av_freep(&dc->tofree); - return 0; -} - -static int data_read(URLContext *h, unsigned char *buf, int size) -{ - DataContext *dc = h->priv_data; - - if (dc->pos >= dc->size) - return AVERROR_EOF; - size = FFMIN(size, dc->size - dc->pos); - memcpy(buf, dc->data + dc->pos, size); - dc->pos += size; - return size; -} - -URLProtocol ff_data_protocol = { - .name = "data", - .url_open = data_open, - .url_close = data_close, - .url_read = data_read, - .priv_data_size = sizeof(DataContext), -}; diff --git a/ffmpeg1/libavformat/daud.c b/ffmpeg1/libavformat/daud.c deleted file mode 100644 index fb62ab1..0000000 --- a/ffmpeg1/libavformat/daud.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * D-Cinema audio demuxer - * Copyright (c) 2005 Reimar Döffinger - * - * 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 "libavutil/channel_layout.h" -#include "avformat.h" - -static int daud_header(AVFormatContext *s) { - AVStream *st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = AV_CODEC_ID_PCM_S24DAUD; - st->codec->codec_tag = MKTAG('d', 'a', 'u', 'd'); - st->codec->channels = 6; - st->codec->channel_layout = AV_CH_LAYOUT_5POINT1; - st->codec->sample_rate = 96000; - st->codec->bit_rate = 3 * 6 * 96000 * 8; - st->codec->block_align = 3 * 6; - st->codec->bits_per_coded_sample = 24; - return 0; -} - -static int daud_packet(AVFormatContext *s, AVPacket *pkt) { - AVIOContext *pb = s->pb; - int ret, size; - if (url_feof(pb)) - return AVERROR(EIO); - size = avio_rb16(pb); - avio_rb16(pb); // unknown - ret = av_get_packet(pb, pkt, size); - pkt->stream_index = 0; - return ret; -} - -static int daud_write_header(struct AVFormatContext *s) -{ - AVCodecContext *codec = s->streams[0]->codec; - if (codec->channels!=6 || codec->sample_rate!=96000) - return -1; - return 0; -} - -static int daud_write_packet(struct AVFormatContext *s, AVPacket *pkt) -{ - if (pkt->size > 65535) { - av_log(s, AV_LOG_ERROR, - "Packet size too large for s302m. (%d > 65535)\n", pkt->size); - return -1; - } - avio_wb16(s->pb, pkt->size); - avio_wb16(s->pb, 0x8010); // unknown - avio_write(s->pb, pkt->data, pkt->size); - avio_flush(s->pb); - return 0; -} - -#if CONFIG_DAUD_DEMUXER -AVInputFormat ff_daud_demuxer = { - .name = "daud", - .long_name = NULL_IF_CONFIG_SMALL("D-Cinema audio"), - .read_header = daud_header, - .read_packet = daud_packet, - .extensions = "302,daud", -}; -#endif - -#if CONFIG_DAUD_MUXER -AVOutputFormat ff_daud_muxer = { - .name = "daud", - .long_name = NULL_IF_CONFIG_SMALL("D-Cinema audio"), - .extensions = "302", - .audio_codec = AV_CODEC_ID_PCM_S24DAUD, - .video_codec = AV_CODEC_ID_NONE, - .write_header = daud_write_header, - .write_packet = daud_write_packet, - .flags = AVFMT_NOTIMESTAMPS, -}; -#endif diff --git a/ffmpeg1/libavformat/dfa.c b/ffmpeg1/libavformat/dfa.c deleted file mode 100644 index 8cf2f24..0000000 --- a/ffmpeg1/libavformat/dfa.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Chronomaster DFA Format Demuxer - * Copyright (c) 2011 Konstantin Shishkov - * - * 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 "libavutil/intreadwrite.h" -#include "avformat.h" -#include "internal.h" - -static int dfa_probe(AVProbeData *p) -{ - if (p->buf_size < 4 || AV_RL32(p->buf) != MKTAG('D', 'F', 'I', 'A')) - return 0; - - return AVPROBE_SCORE_MAX; -} - -static int dfa_read_header(AVFormatContext *s) -{ - AVIOContext *pb = s->pb; - AVStream *st; - int frames; - uint32_t mspf; - - if (avio_rl32(pb) != MKTAG('D', 'F', 'I', 'A')) { - av_log(s, AV_LOG_ERROR, "Invalid magic for DFA\n"); - return AVERROR_INVALIDDATA; - } - avio_skip(pb, 2); // unused - frames = avio_rl16(pb); - - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = AV_CODEC_ID_DFA; - st->codec->width = avio_rl16(pb); - st->codec->height = avio_rl16(pb); - mspf = avio_rl32(pb); - if (!mspf) { - av_log(s, AV_LOG_WARNING, "Zero FPS reported, defaulting to 10\n"); - mspf = 100; - } - avpriv_set_pts_info(st, 24, mspf, 1000); - avio_skip(pb, 128 - 16); // padding - st->duration = frames; - - return 0; -} - -static int dfa_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - AVIOContext *pb = s->pb; - uint32_t frame_size; - int ret, first = 1; - - if (pb->eof_reached) - return AVERROR_EOF; - - if (av_get_packet(pb, pkt, 12) != 12) - return AVERROR(EIO); - while (!pb->eof_reached) { - if (!first) { - ret = av_append_packet(pb, pkt, 12); - if (ret < 0) { - av_free_packet(pkt); - return ret; - } - } else - first = 0; - frame_size = AV_RL32(pkt->data + pkt->size - 8); - if (frame_size > INT_MAX - 4) { - av_log(s, AV_LOG_ERROR, "Too large chunk size: %d\n", frame_size); - return AVERROR(EIO); - } - if (AV_RL32(pkt->data + pkt->size - 12) == MKTAG('E', 'O', 'F', 'R')) { - if (frame_size) { - av_log(s, AV_LOG_WARNING, "skipping %d bytes of end-of-frame marker chunk\n", - frame_size); - avio_skip(pb, frame_size); - } - return 0; - } - ret = av_append_packet(pb, pkt, frame_size); - if (ret < 0) { - av_free_packet(pkt); - return ret; - } - } - - return 0; -} - -AVInputFormat ff_dfa_demuxer = { - .name = "dfa", - .long_name = NULL_IF_CONFIG_SMALL("Chronomaster DFA"), - .read_probe = dfa_probe, - .read_header = dfa_read_header, - .read_packet = dfa_read_packet, - .flags = AVFMT_GENERIC_INDEX, -}; diff --git a/ffmpeg1/libavformat/diracdec.c b/ffmpeg1/libavformat/diracdec.c deleted file mode 100644 index 6636ead..0000000 --- a/ffmpeg1/libavformat/diracdec.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - * RAW Dirac demuxer - * Copyright (c) 2007 Marco Gerards - * - * 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 "libavutil/intreadwrite.h" -#include "avformat.h" -#include "rawdec.h" - -static int dirac_probe(AVProbeData *p) -{ - if (AV_RL32(p->buf) == MKTAG('B', 'B', 'C', 'D')) - return AVPROBE_SCORE_MAX; - else - return 0; -} - -FF_DEF_RAWVIDEO_DEMUXER(dirac, "raw Dirac", dirac_probe, NULL, AV_CODEC_ID_DIRAC) diff --git a/ffmpeg1/libavformat/dnxhddec.c b/ffmpeg1/libavformat/dnxhddec.c deleted file mode 100644 index 7b55400..0000000 --- a/ffmpeg1/libavformat/dnxhddec.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * RAW DNxHD (SMPTE VC-3) demuxer - * Copyright (c) 2008 Baptiste Coudurier - * Copyright (c) 2009 Reimar Döffinger - * - * 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 "libavutil/intreadwrite.h" -#include "avformat.h" -#include "rawdec.h" - -static int dnxhd_probe(AVProbeData *p) -{ - static const uint8_t header[] = {0x00,0x00,0x02,0x80,0x01}; - int w, h, compression_id; - if (p->buf_size < 0x2c) - return 0; - if (memcmp(p->buf, header, 5)) - return 0; - h = AV_RB16(p->buf + 0x18); - w = AV_RB16(p->buf + 0x1a); - if (!w || !h) - return 0; - compression_id = AV_RB32(p->buf + 0x28); - if (compression_id < 1235 || compression_id > 1253) - return 0; - return AVPROBE_SCORE_MAX; -} - -FF_DEF_RAWVIDEO_DEMUXER(dnxhd, "raw DNxHD (SMPTE VC-3)", dnxhd_probe, NULL, AV_CODEC_ID_DNXHD) diff --git a/ffmpeg1/libavformat/dsicin.c b/ffmpeg1/libavformat/dsicin.c deleted file mode 100644 index b8ca57c..0000000 --- a/ffmpeg1/libavformat/dsicin.c +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Delphine Software International CIN File Demuxer - * Copyright (c) 2006 Gregory Montoir (cyx@users.sourceforge.net) - * - * 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 - */ - -/** - * @file - * Delphine Software International CIN file demuxer - */ - -#include "libavutil/channel_layout.h" -#include "libavutil/intreadwrite.h" -#include "avformat.h" -#include "internal.h" -#include "avio_internal.h" - - -typedef struct CinFileHeader { - int video_frame_size; - int video_frame_width; - int video_frame_height; - int audio_frequency; - int audio_bits; - int audio_stereo; - int audio_frame_size; -} CinFileHeader; - -typedef struct CinFrameHeader { - int audio_frame_type; - int video_frame_type; - int pal_colors_count; - int audio_frame_size; - int video_frame_size; -} CinFrameHeader; - -typedef struct CinDemuxContext { - int audio_stream_index; - int video_stream_index; - CinFileHeader file_header; - int64_t audio_stream_pts; - int64_t video_stream_pts; - CinFrameHeader frame_header; - int audio_buffer_size; -} CinDemuxContext; - - -static int cin_probe(AVProbeData *p) -{ - /* header starts with this special marker */ - if (AV_RL32(&p->buf[0]) != 0x55AA0000) - return 0; - - /* for accuracy, check some header field values */ - if (AV_RL32(&p->buf[12]) != 22050 || p->buf[16] != 16 || p->buf[17] != 0) - return 0; - - return AVPROBE_SCORE_MAX; -} - -static int cin_read_file_header(CinDemuxContext *cin, AVIOContext *pb) { - CinFileHeader *hdr = &cin->file_header; - - if (avio_rl32(pb) != 0x55AA0000) - return AVERROR_INVALIDDATA; - - hdr->video_frame_size = avio_rl32(pb); - hdr->video_frame_width = avio_rl16(pb); - hdr->video_frame_height = avio_rl16(pb); - hdr->audio_frequency = avio_rl32(pb); - hdr->audio_bits = avio_r8(pb); - hdr->audio_stereo = avio_r8(pb); - hdr->audio_frame_size = avio_rl16(pb); - - if (hdr->audio_frequency != 22050 || hdr->audio_bits != 16 || hdr->audio_stereo != 0) - return AVERROR_INVALIDDATA; - - return 0; -} - -static int cin_read_header(AVFormatContext *s) -{ - int rc; - CinDemuxContext *cin = s->priv_data; - CinFileHeader *hdr = &cin->file_header; - AVIOContext *pb = s->pb; - AVStream *st; - - rc = cin_read_file_header(cin, pb); - if (rc) - return rc; - - cin->video_stream_pts = 0; - cin->audio_stream_pts = 0; - cin->audio_buffer_size = 0; - - /* initialize the video decoder stream */ - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - - avpriv_set_pts_info(st, 32, 1, 12); - cin->video_stream_index = st->index; - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = AV_CODEC_ID_DSICINVIDEO; - st->codec->codec_tag = 0; /* no fourcc */ - st->codec->width = hdr->video_frame_width; - st->codec->height = hdr->video_frame_height; - - /* initialize the audio decoder stream */ - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - - avpriv_set_pts_info(st, 32, 1, 22050); - cin->audio_stream_index = st->index; - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = AV_CODEC_ID_DSICINAUDIO; - st->codec->codec_tag = 0; /* no tag */ - st->codec->channels = 1; - st->codec->channel_layout = AV_CH_LAYOUT_MONO; - st->codec->sample_rate = 22050; - st->codec->bits_per_coded_sample = 8; - st->codec->bit_rate = st->codec->sample_rate * st->codec->bits_per_coded_sample * st->codec->channels; - - return 0; -} - -static int cin_read_frame_header(CinDemuxContext *cin, AVIOContext *pb) { - CinFrameHeader *hdr = &cin->frame_header; - - hdr->video_frame_type = avio_r8(pb); - hdr->audio_frame_type = avio_r8(pb); - hdr->pal_colors_count = avio_rl16(pb); - hdr->video_frame_size = avio_rl32(pb); - hdr->audio_frame_size = avio_rl32(pb); - - if (url_feof(pb) || pb->error) - return AVERROR(EIO); - - if (avio_rl32(pb) != 0xAA55AA55) - return AVERROR_INVALIDDATA; - - return 0; -} - -static int cin_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - CinDemuxContext *cin = s->priv_data; - AVIOContext *pb = s->pb; - CinFrameHeader *hdr = &cin->frame_header; - int rc, palette_type, pkt_size; - int ret; - - if (cin->audio_buffer_size == 0) { - rc = cin_read_frame_header(cin, pb); - if (rc) - return rc; - - if ((int16_t)hdr->pal_colors_count < 0) { - hdr->pal_colors_count = -(int16_t)hdr->pal_colors_count; - palette_type = 1; - } else { - palette_type = 0; - } - - /* palette and video packet */ - pkt_size = (palette_type + 3) * hdr->pal_colors_count + hdr->video_frame_size; - - pkt_size = ffio_limit(pb, pkt_size); - - ret = av_new_packet(pkt, 4 + pkt_size); - if (ret < 0) - return ret; - - pkt->stream_index = cin->video_stream_index; - pkt->pts = cin->video_stream_pts++; - - pkt->data[0] = palette_type; - pkt->data[1] = hdr->pal_colors_count & 0xFF; - pkt->data[2] = hdr->pal_colors_count >> 8; - pkt->data[3] = hdr->video_frame_type; - - ret = avio_read(pb, &pkt->data[4], pkt_size); - if (ret < 0) { - av_free_packet(pkt); - return ret; - } - if (ret < pkt_size) - av_shrink_packet(pkt, 4 + ret); - - /* sound buffer will be processed on next read_packet() call */ - cin->audio_buffer_size = hdr->audio_frame_size; - return 0; - } - - /* audio packet */ - ret = av_get_packet(pb, pkt, cin->audio_buffer_size); - if (ret < 0) - return ret; - - pkt->stream_index = cin->audio_stream_index; - pkt->pts = cin->audio_stream_pts; - pkt->duration = cin->audio_buffer_size - (pkt->pts == 0); - cin->audio_stream_pts += pkt->duration; - cin->audio_buffer_size = 0; - return 0; -} - -AVInputFormat ff_dsicin_demuxer = { - .name = "dsicin", - .long_name = NULL_IF_CONFIG_SMALL("Delphine Software International CIN"), - .priv_data_size = sizeof(CinDemuxContext), - .read_probe = cin_probe, - .read_header = cin_read_header, - .read_packet = cin_read_packet, -}; diff --git a/ffmpeg1/libavformat/dtsdec.c b/ffmpeg1/libavformat/dtsdec.c deleted file mode 100644 index 5c05758..0000000 --- a/ffmpeg1/libavformat/dtsdec.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * RAW DTS demuxer - * Copyright (c) 2008 Benjamin Larsson - * - * 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 "libavcodec/bytestream.h" -#include "avformat.h" -#include "rawdec.h" - -#define DCA_MARKER_14B_BE 0x1FFFE800 -#define DCA_MARKER_14B_LE 0xFF1F00E8 -#define DCA_MARKER_RAW_BE 0x7FFE8001 -#define DCA_MARKER_RAW_LE 0xFE7F0180 - -static int dts_probe(AVProbeData *p) -{ - const uint8_t *buf, *bufp; - uint32_t state = -1; - int markers[3] = {0}; - int sum, max; - - buf = p->buf; - - for(; buf < (p->buf+p->buf_size)-2; buf+=2) { - bufp = buf; - state = (state << 16) | bytestream_get_be16(&bufp); - - /* regular bitstream */ - if (state == DCA_MARKER_RAW_BE || state == DCA_MARKER_RAW_LE) - markers[0]++; - - /* 14 bits big-endian bitstream */ - if (state == DCA_MARKER_14B_BE) - if ((bytestream_get_be16(&bufp) & 0xFFF0) == 0x07F0) - markers[1]++; - - /* 14 bits little-endian bitstream */ - if (state == DCA_MARKER_14B_LE) - if ((bytestream_get_be16(&bufp) & 0xF0FF) == 0xF007) - markers[2]++; - } - sum = markers[0] + markers[1] + markers[2]; - max = markers[1] > markers[0]; - max = markers[2] > markers[max] ? 2 : max; - if (markers[max] > 3 && p->buf_size / markers[max] < 32*1024 && - markers[max] * 4 > sum * 3) - return AVPROBE_SCORE_MAX/2+1; - - return 0; -} - -AVInputFormat ff_dts_demuxer = { - .name = "dts", - .long_name = NULL_IF_CONFIG_SMALL("raw DTS"), - .read_probe = dts_probe, - .read_header = ff_raw_audio_read_header, - .read_packet = ff_raw_read_partial_packet, - .flags = AVFMT_GENERIC_INDEX, - .extensions = "dts", - .raw_codec_id = AV_CODEC_ID_DTS, -}; diff --git a/ffmpeg1/libavformat/dtshddec.c b/ffmpeg1/libavformat/dtshddec.c deleted file mode 100644 index 55c4ca6..0000000 --- a/ffmpeg1/libavformat/dtshddec.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Raw DTS-HD demuxer - * Copyright (c) 2012 Paul B Mahol - * - * 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 "libavutil/intreadwrite.h" -#include "libavutil/dict.h" -#include "avformat.h" - -#define AUPR_HDR 0x415550522D484452 -#define AUPRINFO 0x41555052494E464F -#define BITSHVTB 0x4249545348565442 -#define BLACKOUT 0x424C41434B4F5554 -#define BRANCHPT 0x4252414E43485054 -#define BUILDVER 0x4255494C44564552 -#define CORESSMD 0x434F524553534D44 -#define DTSHDHDR 0x4454534844484452 -#define EXTSS_MD 0x45585453535f4d44 -#define FILEINFO 0x46494C45494E464F -#define NAVI_TBL 0x4E4156492D54424C -#define STRMDATA 0x5354524D44415441 -#define TIMECODE 0x54494D45434F4445 - -typedef struct DTSHDDemuxContext { - uint64_t data_end; -} DTSHDDemuxContext; - -static int dtshd_probe(AVProbeData *p) -{ - if (AV_RB64(p->buf) == DTSHDHDR) - return AVPROBE_SCORE_MAX; - return 0; -} - -static int dtshd_read_header(AVFormatContext *s) -{ - DTSHDDemuxContext *dtshd = s->priv_data; - AVIOContext *pb = s->pb; - uint64_t chunk_type, chunk_size; - AVStream *st; - int ret; - char *value; - - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = AV_CODEC_ID_DTS; - st->need_parsing = AVSTREAM_PARSE_FULL_RAW; - - while (!url_feof(pb)) { - chunk_type = avio_rb64(pb); - chunk_size = avio_rb64(pb); - - if (chunk_size < 4) { - av_log(s, AV_LOG_ERROR, "chunk size too small\n"); - return AVERROR_INVALIDDATA; - } - if (chunk_size > ((uint64_t)1 << 61)) { - av_log(s, AV_LOG_ERROR, "chunk size too big\n"); - return AVERROR_INVALIDDATA; - } - - switch (chunk_type) { - case STRMDATA: - dtshd->data_end = chunk_size + avio_tell(pb); - if (dtshd->data_end <= chunk_size) - return AVERROR_INVALIDDATA; - return 0; - break; - case FILEINFO: - if (chunk_size > INT_MAX) - goto skip; - value = av_malloc(chunk_size); - if (!value) - goto skip; - avio_read(pb, value, chunk_size); - value[chunk_size - 1] = 0; - av_dict_set(&s->metadata, "fileinfo", value, - AV_DICT_DONT_STRDUP_VAL); - break; - default: -skip: - ret = avio_skip(pb, chunk_size); - if (ret < 0) - return ret; - }; - } - - return AVERROR_EOF; -} - -static int raw_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - DTSHDDemuxContext *dtshd = s->priv_data; - int64_t size, left; - int ret; - - left = dtshd->data_end - avio_tell(s->pb); - size = FFMIN(left, 1024); - if (size <= 0) - return AVERROR_EOF; - - ret = av_get_packet(s->pb, pkt, size); - if (ret < 0) - return ret; - - pkt->stream_index = 0; - - return ret; -} - -AVInputFormat ff_dtshd_demuxer = { - .name = "dtshd", - .long_name = NULL_IF_CONFIG_SMALL("raw DTS-HD"), - .priv_data_size = sizeof(DTSHDDemuxContext), - .read_probe = dtshd_probe, - .read_header = dtshd_read_header, - .read_packet = raw_read_packet, - .flags = AVFMT_GENERIC_INDEX, - .extensions = "dtshd", - .raw_codec_id = AV_CODEC_ID_DTS, -}; diff --git a/ffmpeg1/libavformat/dv.c b/ffmpeg1/libavformat/dv.c deleted file mode 100644 index a04735a..0000000 --- a/ffmpeg1/libavformat/dv.c +++ /dev/null @@ -1,614 +0,0 @@ -/* - * General DV muxer/demuxer - * Copyright (c) 2003 Roman Shaposhnik - * - * Many thanks to Dan Dennedy for providing wealth - * of DV technical info. - * - * Raw DV format - * Copyright (c) 2002 Fabrice Bellard - * - * 50 Mbps (DVCPRO50) and 100 Mbps (DVCPRO HD) support - * Copyright (c) 2006 Daniel Maas - * Funded by BBC Research & Development - * - * 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 -#include "avformat.h" -#include "internal.h" -#include "libavcodec/dv_profile.h" -#include "libavcodec/dvdata.h" -#include "libavutil/channel_layout.h" -#include "libavutil/intreadwrite.h" -#include "libavutil/mathematics.h" -#include "libavutil/timecode.h" -#include "dv.h" -#include "libavutil/avassert.h" - -struct DVDemuxContext { - const DVprofile* sys; /* Current DV profile. E.g.: 525/60, 625/50 */ - AVFormatContext* fctx; - AVStream* vst; - AVStream* ast[4]; - AVPacket audio_pkt[4]; - uint8_t audio_buf[4][8192]; - int ach; - int frames; - uint64_t abytes; -}; - -static inline uint16_t dv_audio_12to16(uint16_t sample) -{ - uint16_t shift, result; - - sample = (sample < 0x800) ? sample : sample | 0xf000; - shift = (sample & 0xf00) >> 8; - - if (shift < 0x2 || shift > 0xd) { - result = sample; - } else if (shift < 0x8) { - shift--; - result = (sample - (256 * shift)) << shift; - } else { - shift = 0xe - shift; - result = ((sample + ((256 * shift) + 1)) << shift) - 1; - } - - return result; -} - -/* - * This is the dumbest implementation of all -- it simply looks at - * a fixed offset and if pack isn't there -- fails. We might want - * to have a fallback mechanism for complete search of missing packs. - */ -static const uint8_t* dv_extract_pack(uint8_t* frame, enum dv_pack_type t) -{ - int offs; - - switch (t) { - case dv_audio_source: - offs = (80*6 + 80*16*3 + 3); - break; - case dv_audio_control: - offs = (80*6 + 80*16*4 + 3); - break; - case dv_video_control: - offs = (80*5 + 48 + 5); - break; - case dv_timecode: - offs = (80*1 + 3 + 3); - break; - default: - return NULL; - } - - return frame[offs] == t ? &frame[offs] : NULL; -} - -static const int dv_audio_frequency[3] = { - 48000, 44100, 32000, -}; - -/* - * There's a couple of assumptions being made here: - * 1. By default we silence erroneous (0x8000/16bit 0x800/12bit) audio samples. - * We can pass them upwards when libavcodec will be ready to deal with them. - * 2. We don't do software emphasis. - * 3. Audio is always returned as 16bit linear samples: 12bit nonlinear samples - * are converted into 16bit linear ones. - */ -static int dv_extract_audio(uint8_t* frame, uint8_t* ppcm[4], - const DVprofile *sys) -{ - int size, chan, i, j, d, of, smpls, freq, quant, half_ch; - uint16_t lc, rc; - const uint8_t* as_pack; - uint8_t *pcm, ipcm; - - as_pack = dv_extract_pack(frame, dv_audio_source); - if (!as_pack) /* No audio ? */ - return 0; - - smpls = as_pack[1] & 0x3f; /* samples in this frame - min. samples */ - freq = (as_pack[4] >> 3) & 0x07; /* 0 - 48kHz, 1 - 44,1kHz, 2 - 32kHz */ - quant = as_pack[4] & 0x07; /* 0 - 16bit linear, 1 - 12bit nonlinear */ - - if (quant > 1) - return -1; /* unsupported quantization */ - - if (freq >= FF_ARRAY_ELEMS(dv_audio_frequency)) - return AVERROR_INVALIDDATA; - - size = (sys->audio_min_samples[freq] + smpls) * 4; /* 2ch, 2bytes */ - half_ch = sys->difseg_size / 2; - - /* We work with 720p frames split in half, thus even frames have - * channels 0,1 and odd 2,3. */ - ipcm = (sys->height == 720 && !(frame[1] & 0x0C)) ? 2 : 0; - - if (ipcm + sys->n_difchan > (quant == 1 ? 2 : 4)) { - av_log(NULL, AV_LOG_ERROR, "too many dv pcm frames\n"); - return AVERROR_INVALIDDATA; - } - - /* for each DIF channel */ - for (chan = 0; chan < sys->n_difchan; chan++) { - av_assert0(ipcm<4); - pcm = ppcm[ipcm++]; - if (!pcm) - break; - - /* for each DIF segment */ - for (i = 0; i < sys->difseg_size; i++) { - frame += 6 * 80; /* skip DIF segment header */ - if (quant == 1 && i == half_ch) { - /* next stereo channel (12bit mode only) */ - av_assert0(ipcm<4); - pcm = ppcm[ipcm++]; - if (!pcm) - break; - } - - /* for each AV sequence */ - for (j = 0; j < 9; j++) { - for (d = 8; d < 80; d += 2) { - if (quant == 0) { /* 16bit quantization */ - of = sys->audio_shuffle[i][j] + (d - 8) / 2 * sys->audio_stride; - if (of*2 >= size) - continue; - - pcm[of*2] = frame[d+1]; // FIXME: maybe we have to admit - pcm[of*2+1] = frame[d]; // that DV is a big-endian PCM - if (pcm[of*2+1] == 0x80 && pcm[of*2] == 0x00) - pcm[of*2+1] = 0; - } else { /* 12bit quantization */ - lc = ((uint16_t)frame[d] << 4) | - ((uint16_t)frame[d+2] >> 4); - rc = ((uint16_t)frame[d+1] << 4) | - ((uint16_t)frame[d+2] & 0x0f); - lc = (lc == 0x800 ? 0 : dv_audio_12to16(lc)); - rc = (rc == 0x800 ? 0 : dv_audio_12to16(rc)); - - of = sys->audio_shuffle[i%half_ch][j] + (d - 8) / 3 * sys->audio_stride; - if (of*2 >= size) - continue; - - pcm[of*2] = lc & 0xff; // FIXME: maybe we have to admit - pcm[of*2+1] = lc >> 8; // that DV is a big-endian PCM - of = sys->audio_shuffle[i%half_ch+half_ch][j] + - (d - 8) / 3 * sys->audio_stride; - pcm[of*2] = rc & 0xff; // FIXME: maybe we have to admit - pcm[of*2+1] = rc >> 8; // that DV is a big-endian PCM - ++d; - } - } - - frame += 16 * 80; /* 15 Video DIFs + 1 Audio DIF */ - } - } - } - - return size; -} - -static int dv_extract_audio_info(DVDemuxContext* c, uint8_t* frame) -{ - const uint8_t* as_pack; - int freq, stype, smpls, quant, i, ach; - - as_pack = dv_extract_pack(frame, dv_audio_source); - if (!as_pack || !c->sys) { /* No audio ? */ - c->ach = 0; - return 0; - } - - smpls = as_pack[1] & 0x3f; /* samples in this frame - min. samples */ - freq = (as_pack[4] >> 3) & 0x07; /* 0 - 48kHz, 1 - 44,1kHz, 2 - 32kHz */ - stype = (as_pack[3] & 0x1f); /* 0 - 2CH, 2 - 4CH, 3 - 8CH */ - quant = as_pack[4] & 0x07; /* 0 - 16bit linear, 1 - 12bit nonlinear */ - - if (freq >= FF_ARRAY_ELEMS(dv_audio_frequency)) { - av_log(c->fctx, AV_LOG_ERROR, - "Unrecognized audio sample rate index (%d)\n", freq); - return 0; - } - - if (stype > 3) { - av_log(c->fctx, AV_LOG_ERROR, "stype %d is invalid\n", stype); - c->ach = 0; - return 0; - } - - /* note: ach counts PAIRS of channels (i.e. stereo channels) */ - ach = ((int[4]){ 1, 0, 2, 4})[stype]; - if (ach == 1 && quant && freq == 2) - ach = 2; - - /* Dynamic handling of the audio streams in DV */ - for (i = 0; i < ach; i++) { - if (!c->ast[i]) { - c->ast[i] = avformat_new_stream(c->fctx, NULL); - if (!c->ast[i]) - break; - avpriv_set_pts_info(c->ast[i], 64, 1, 30000); - c->ast[i]->codec->codec_type = AVMEDIA_TYPE_AUDIO; - c->ast[i]->codec->codec_id = AV_CODEC_ID_PCM_S16LE; - - av_init_packet(&c->audio_pkt[i]); - c->audio_pkt[i].size = 0; - c->audio_pkt[i].data = c->audio_buf[i]; - c->audio_pkt[i].stream_index = c->ast[i]->index; - c->audio_pkt[i].flags |= AV_PKT_FLAG_KEY; - } - c->ast[i]->codec->sample_rate = dv_audio_frequency[freq]; - c->ast[i]->codec->channels = 2; - c->ast[i]->codec->channel_layout = AV_CH_LAYOUT_STEREO; - c->ast[i]->codec->bit_rate = 2 * dv_audio_frequency[freq] * 16; - c->ast[i]->start_time = 0; - } - c->ach = i; - - return (c->sys->audio_min_samples[freq] + smpls) * 4; /* 2ch, 2bytes */; -} - -static int dv_extract_video_info(DVDemuxContext *c, uint8_t* frame) -{ - const uint8_t* vsc_pack; - AVCodecContext* avctx; - int apt, is16_9; - int size = 0; - - if (c->sys) { - avctx = c->vst->codec; - - avpriv_set_pts_info(c->vst, 64, c->sys->time_base.num, - c->sys->time_base.den); - avctx->time_base= c->sys->time_base; - - /* finding out SAR is a little bit messy */ - vsc_pack = dv_extract_pack(frame, dv_video_control); - apt = frame[4] & 0x07; - is16_9 = (vsc_pack && ((vsc_pack[2] & 0x07) == 0x02 || - (!apt && (vsc_pack[2] & 0x07) == 0x07))); - c->vst->sample_aspect_ratio = c->sys->sar[is16_9]; - avctx->bit_rate = av_rescale_q(c->sys->frame_size, (AVRational){8,1}, - c->sys->time_base); - size = c->sys->frame_size; - } - return size; -} - -static int dv_extract_timecode(DVDemuxContext* c, uint8_t* frame, char *tc) -{ - const uint8_t *tc_pack; - - // For PAL systems, drop frame bit is replaced by an arbitrary - // bit so its value should not be considered. Drop frame timecode - // is only relevant for NTSC systems. - int prevent_df = c->sys->ltc_divisor == 25 || c->sys->ltc_divisor == 50; - - tc_pack = dv_extract_pack(frame, dv_timecode); - if (!tc_pack) - return 0; - av_timecode_make_smpte_tc_string(tc, AV_RB32(tc_pack + 1), prevent_df); - return 1; -} - -/* - * The following 3 functions constitute our interface to the world - */ - -DVDemuxContext* avpriv_dv_init_demux(AVFormatContext *s) -{ - DVDemuxContext *c; - - c = av_mallocz(sizeof(DVDemuxContext)); - if (!c) - return NULL; - - c->vst = avformat_new_stream(s, NULL); - if (!c->vst) { - av_free(c); - return NULL; - } - - c->fctx = s; - c->vst->codec->codec_type = AVMEDIA_TYPE_VIDEO; - c->vst->codec->codec_id = AV_CODEC_ID_DVVIDEO; - c->vst->codec->bit_rate = 25000000; - c->vst->start_time = 0; - - return c; -} - -int avpriv_dv_get_packet(DVDemuxContext *c, AVPacket *pkt) -{ - int size = -1; - int i; - - for (i = 0; i < c->ach; i++) { - if (c->ast[i] && c->audio_pkt[i].size) { - *pkt = c->audio_pkt[i]; - c->audio_pkt[i].size = 0; - size = pkt->size; - break; - } - } - - return size; -} - -int avpriv_dv_produce_packet(DVDemuxContext *c, AVPacket *pkt, - uint8_t* buf, int buf_size, int64_t pos) -{ - int size, i; - uint8_t *ppcm[4] = {0}; - - if (buf_size < DV_PROFILE_BYTES || - !(c->sys = avpriv_dv_frame_profile(c->sys, buf, buf_size)) || - buf_size < c->sys->frame_size) { - return -1; /* Broken frame, or not enough data */ - } - - /* Queueing audio packet */ - /* FIXME: in case of no audio/bad audio we have to do something */ - size = dv_extract_audio_info(c, buf); - for (i = 0; i < c->ach; i++) { - c->audio_pkt[i].pos = pos; - c->audio_pkt[i].size = size; - c->audio_pkt[i].pts = c->abytes * 30000 * 8 / c->ast[i]->codec->bit_rate; - ppcm[i] = c->audio_buf[i]; - } - if (c->ach) - dv_extract_audio(buf, ppcm, c->sys); - - /* We work with 720p frames split in half, thus even frames have - * channels 0,1 and odd 2,3. */ - if (c->sys->height == 720) { - if (buf[1] & 0x0C) { - c->audio_pkt[2].size = c->audio_pkt[3].size = 0; - } else { - c->audio_pkt[0].size = c->audio_pkt[1].size = 0; - c->abytes += size; - } - } else { - c->abytes += size; - } - - /* Now it's time to return video packet */ - size = dv_extract_video_info(c, buf); - av_init_packet(pkt); - pkt->data = buf; - pkt->pos = pos; - pkt->size = size; - pkt->flags |= AV_PKT_FLAG_KEY; - pkt->stream_index = c->vst->index; - pkt->pts = c->frames; - - c->frames++; - - return size; -} - -static int64_t dv_frame_offset(AVFormatContext *s, DVDemuxContext *c, - int64_t timestamp, int flags) -{ - // FIXME: sys may be wrong if last dv_read_packet() failed (buffer is junk) - const DVprofile* sys = avpriv_dv_codec_profile(c->vst->codec); - int64_t offset; - int64_t size = avio_size(s->pb) - s->data_offset; - int64_t max_offset = ((size-1) / sys->frame_size) * sys->frame_size; - - offset = sys->frame_size * timestamp; - - if (size >= 0 && offset > max_offset) offset = max_offset; - else if (offset < 0) offset = 0; - - return offset + s->data_offset; -} - -void ff_dv_offset_reset(DVDemuxContext *c, int64_t frame_offset) -{ - c->frames= frame_offset; - if (c->ach) { - if (c->sys) { - c->abytes= av_rescale_q(c->frames, c->sys->time_base, - (AVRational){8, c->ast[0]->codec->bit_rate}); - }else - av_log(c->fctx, AV_LOG_ERROR, "cannot adjust audio bytes\n"); - } - c->audio_pkt[0].size = c->audio_pkt[1].size = 0; - c->audio_pkt[2].size = c->audio_pkt[3].size = 0; -} - -/************************************************************ - * Implementation of the easiest DV storage of all -- raw DV. - ************************************************************/ - -typedef struct RawDVContext { - DVDemuxContext* dv_demux; - uint8_t buf[DV_MAX_FRAME_SIZE]; -} RawDVContext; - -static int dv_read_timecode(AVFormatContext *s) { - int ret; - char timecode[AV_TIMECODE_STR_SIZE]; - int64_t pos = avio_tell(s->pb); - - // Read 3 DIF blocks: Header block and 2 Subcode blocks. - int partial_frame_size = 3 * 80; - uint8_t *partial_frame = av_mallocz(sizeof(*partial_frame) * - partial_frame_size); - - RawDVContext *c = s->priv_data; - ret = avio_read(s->pb, partial_frame, partial_frame_size); - if (ret < 0) - goto finish; - - if (ret < partial_frame_size) { - ret = -1; - goto finish; - } - - ret = dv_extract_timecode(c->dv_demux, partial_frame, timecode); - if (ret) - av_dict_set(&s->metadata, "timecode", timecode, 0); - else - av_log(s, AV_LOG_ERROR, "Detected timecode is invalid\n"); - -finish: - av_free(partial_frame); - avio_seek(s->pb, pos, SEEK_SET); - return ret; -} - -static int dv_read_header(AVFormatContext *s) -{ - unsigned state, marker_pos = 0; - RawDVContext *c = s->priv_data; - - c->dv_demux = avpriv_dv_init_demux(s); - if (!c->dv_demux) - return -1; - - state = avio_rb32(s->pb); - while ((state & 0xffffff7f) != 0x1f07003f) { - if (url_feof(s->pb)) { - av_log(s, AV_LOG_ERROR, "Cannot find DV header.\n"); - return -1; - } - if (state == 0x003f0700 || state == 0xff3f0700) - marker_pos = avio_tell(s->pb); - if (state == 0xff3f0701 && avio_tell(s->pb) - marker_pos == 80) { - avio_seek(s->pb, -163, SEEK_CUR); - state = avio_rb32(s->pb); - break; - } - state = (state << 8) | avio_r8(s->pb); - } - AV_WB32(c->buf, state); - - if (avio_read(s->pb, c->buf + 4, DV_PROFILE_BYTES - 4) != DV_PROFILE_BYTES - 4 || - avio_seek(s->pb, -DV_PROFILE_BYTES, SEEK_CUR) < 0) - return AVERROR(EIO); - - c->dv_demux->sys = avpriv_dv_frame_profile(c->dv_demux->sys, c->buf, DV_PROFILE_BYTES); - if (!c->dv_demux->sys) { - av_log(s, AV_LOG_ERROR, "Can't determine profile of DV input stream.\n"); - return -1; - } - - s->bit_rate = av_rescale_q(c->dv_demux->sys->frame_size, (AVRational){8,1}, - c->dv_demux->sys->time_base); - - if (s->pb->seekable) - dv_read_timecode(s); - - return 0; -} - - -static int dv_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - int size; - RawDVContext *c = s->priv_data; - - size = avpriv_dv_get_packet(c->dv_demux, pkt); - - if (size < 0) { - int64_t pos = avio_tell(s->pb); - if (!c->dv_demux->sys) - return AVERROR(EIO); - size = c->dv_demux->sys->frame_size; - if (avio_read(s->pb, c->buf, size) <= 0) - return AVERROR(EIO); - - size = avpriv_dv_produce_packet(c->dv_demux, pkt, c->buf, size, pos); - } - - return size; -} - -static int dv_read_seek(AVFormatContext *s, int stream_index, - int64_t timestamp, int flags) -{ - RawDVContext *r = s->priv_data; - DVDemuxContext *c = r->dv_demux; - int64_t offset = dv_frame_offset(s, c, timestamp, flags); - - if (avio_seek(s->pb, offset, SEEK_SET) < 0) - return -1; - - ff_dv_offset_reset(c, offset / c->sys->frame_size); - return 0; -} - -static int dv_read_close(AVFormatContext *s) -{ - RawDVContext *c = s->priv_data; - av_free(c->dv_demux); - return 0; -} - -static int dv_probe(AVProbeData *p) -{ - unsigned state, marker_pos = 0; - int i; - int matches = 0; - int secondary_matches = 0; - - if (p->buf_size < 5) - return 0; - - state = AV_RB32(p->buf); - for (i = 4; i < p->buf_size; i++) { - if ((state & 0xffffff7f) == 0x1f07003f) - matches++; - // any section header, also with seq/chan num != 0, - // should appear around every 12000 bytes, at least 10 per frame - if ((state & 0xff07ff7f) == 0x1f07003f) - secondary_matches++; - if (state == 0x003f0700 || state == 0xff3f0700) - marker_pos = i; - if (state == 0xff3f0701 && i - marker_pos == 80) - matches++; - state = (state << 8) | p->buf[i]; - } - - if (matches && p->buf_size / matches < 1024*1024) { - if (matches > 4 || (secondary_matches >= 10 && p->buf_size / secondary_matches < 24000)) - return AVPROBE_SCORE_MAX*3/4; // not max to avoid dv in mov to match - return AVPROBE_SCORE_MAX/4; - } - return 0; -} - -#if CONFIG_DV_DEMUXER -AVInputFormat ff_dv_demuxer = { - .name = "dv", - .long_name = NULL_IF_CONFIG_SMALL("DV (Digital Video)"), - .priv_data_size = sizeof(RawDVContext), - .read_probe = dv_probe, - .read_header = dv_read_header, - .read_packet = dv_read_packet, - .read_close = dv_read_close, - .read_seek = dv_read_seek, - .extensions = "dv,dif", -}; -#endif diff --git a/ffmpeg1/libavformat/dv.h b/ffmpeg1/libavformat/dv.h deleted file mode 100644 index 160c6ab..0000000 --- a/ffmpeg1/libavformat/dv.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * General DV muxer/demuxer - * Copyright (c) 2003 Roman Shaposhnik - * - * Many thanks to Dan Dennedy for providing wealth - * of DV technical info. - * - * Raw DV format - * Copyright (c) 2002 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 AVFORMAT_DV_H -#define AVFORMAT_DV_H - -#include "avformat.h" - -typedef struct DVDemuxContext DVDemuxContext; -DVDemuxContext* avpriv_dv_init_demux(AVFormatContext* s); -int avpriv_dv_get_packet(DVDemuxContext*, AVPacket *); -int avpriv_dv_produce_packet(DVDemuxContext*, AVPacket*, uint8_t*, int, int64_t); -void ff_dv_offset_reset(DVDemuxContext *c, int64_t frame_offset); - -typedef struct DVMuxContext DVMuxContext; - -#endif /* AVFORMAT_DV_H */ diff --git a/ffmpeg1/libavformat/dvenc.c b/ffmpeg1/libavformat/dvenc.c deleted file mode 100644 index 0b3811e..0000000 --- a/ffmpeg1/libavformat/dvenc.c +++ /dev/null @@ -1,420 +0,0 @@ -/* - * General DV muxer/demuxer - * Copyright (c) 2003 Roman Shaposhnik - * - * Many thanks to Dan Dennedy for providing wealth - * of DV technical info. - * - * Raw DV format - * Copyright (c) 2002 Fabrice Bellard - * - * 50 Mbps (DVCPRO50) support - * Copyright (c) 2006 Daniel Maas - * - * 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 -#include - -#include "avformat.h" -#include "internal.h" -#include "libavcodec/dv_profile.h" -#include "libavcodec/dvdata.h" -#include "dv.h" -#include "libavutil/fifo.h" -#include "libavutil/mathematics.h" -#include "libavutil/intreadwrite.h" -#include "libavutil/opt.h" -#include "libavutil/timecode.h" - -#define MAX_AUDIO_FRAME_SIZE 192000 // 1 second of 48khz 32bit audio - -struct DVMuxContext { - AVClass *av_class; - const DVprofile* sys; /* current DV profile, e.g.: 525/60, 625/50 */ - int n_ast; /* number of stereo audio streams (up to 2) */ - AVStream *ast[2]; /* stereo audio streams */ - AVFifoBuffer *audio_data[2]; /* FIFO for storing excessive amounts of PCM */ - int frames; /* current frame number */ - int64_t start_time; /* recording start time */ - int has_audio; /* frame under construction has audio */ - int has_video; /* frame under construction has video */ - uint8_t frame_buf[DV_MAX_FRAME_SIZE]; /* frame under construction */ - AVTimecode tc; /* timecode context */ -}; - -static const int dv_aaux_packs_dist[12][9] = { - { 0xff, 0xff, 0xff, 0x50, 0x51, 0x52, 0x53, 0xff, 0xff }, - { 0x50, 0x51, 0x52, 0x53, 0xff, 0xff, 0xff, 0xff, 0xff }, - { 0xff, 0xff, 0xff, 0x50, 0x51, 0x52, 0x53, 0xff, 0xff }, - { 0x50, 0x51, 0x52, 0x53, 0xff, 0xff, 0xff, 0xff, 0xff }, - { 0xff, 0xff, 0xff, 0x50, 0x51, 0x52, 0x53, 0xff, 0xff }, - { 0x50, 0x51, 0x52, 0x53, 0xff, 0xff, 0xff, 0xff, 0xff }, - { 0xff, 0xff, 0xff, 0x50, 0x51, 0x52, 0x53, 0xff, 0xff }, - { 0x50, 0x51, 0x52, 0x53, 0xff, 0xff, 0xff, 0xff, 0xff }, - { 0xff, 0xff, 0xff, 0x50, 0x51, 0x52, 0x53, 0xff, 0xff }, - { 0x50, 0x51, 0x52, 0x53, 0xff, 0xff, 0xff, 0xff, 0xff }, - { 0xff, 0xff, 0xff, 0x50, 0x51, 0x52, 0x53, 0xff, 0xff }, - { 0x50, 0x51, 0x52, 0x53, 0xff, 0xff, 0xff, 0xff, 0xff }, -}; - -static int dv_audio_frame_size(const DVprofile* sys, int frame) -{ - return sys->audio_samples_dist[frame % (sizeof(sys->audio_samples_dist) / - sizeof(sys->audio_samples_dist[0]))]; -} - -static int dv_write_pack(enum dv_pack_type pack_id, DVMuxContext *c, uint8_t* buf, ...) -{ - struct tm tc; - time_t ct; - uint32_t timecode; - va_list ap; - - buf[0] = (uint8_t)pack_id; - switch (pack_id) { - case dv_timecode: - timecode = av_timecode_get_smpte_from_framenum(&c->tc, c->frames); - timecode |= 1<<23 | 1<<15 | 1<<7 | 1<<6; // biphase and binary group flags - AV_WB32(buf + 1, timecode); - break; - case dv_audio_source: /* AAUX source pack */ - va_start(ap, buf); - buf[1] = (1 << 7) | /* locked mode -- SMPTE only supports locked mode */ - (1 << 6) | /* reserved -- always 1 */ - (dv_audio_frame_size(c->sys, c->frames) - - c->sys->audio_min_samples[0]); - /* # of samples */ - buf[2] = (0 << 7) | /* multi-stereo */ - (0 << 5) | /* #of audio channels per block: 0 -- 1 channel */ - (0 << 4) | /* pair bit: 0 -- one pair of channels */ - !!va_arg(ap, int); /* audio mode */ - buf[3] = (1 << 7) | /* res */ - (1 << 6) | /* multi-language flag */ - (c->sys->dsf << 5) | /* system: 60fields/50fields */ - (c->sys->n_difchan & 2); /* definition: 0 -- 25Mbps, 2 -- 50Mbps */ - buf[4] = (1 << 7) | /* emphasis: 1 -- off */ - (0 << 6) | /* emphasis time constant: 0 -- reserved */ - (0 << 3) | /* frequency: 0 -- 48kHz, 1 -- 44,1kHz, 2 -- 32kHz */ - 0; /* quantization: 0 -- 16bit linear, 1 -- 12bit nonlinear */ - va_end(ap); - break; - case dv_audio_control: - buf[1] = (0 << 6) | /* copy protection: 0 -- unrestricted */ - (1 << 4) | /* input source: 1 -- digital input */ - (3 << 2) | /* compression: 3 -- no information */ - 0; /* misc. info/SMPTE emphasis off */ - buf[2] = (1 << 7) | /* recording start point: 1 -- no */ - (1 << 6) | /* recording end point: 1 -- no */ - (1 << 3) | /* recording mode: 1 -- original */ - 7; - buf[3] = (1 << 7) | /* direction: 1 -- forward */ - (c->sys->pix_fmt == AV_PIX_FMT_YUV420P ? 0x20 : /* speed */ - c->sys->ltc_divisor * 4); - buf[4] = (1 << 7) | /* reserved -- always 1 */ - 0x7f; /* genre category */ - break; - case dv_audio_recdate: - case dv_video_recdate: /* VAUX recording date */ - ct = c->start_time + av_rescale_rnd(c->frames, c->sys->time_base.num, - c->sys->time_base.den, AV_ROUND_DOWN); - ff_brktimegm(ct, &tc); - buf[1] = 0xff; /* ds, tm, tens of time zone, units of time zone */ - /* 0xff is very likely to be "unknown" */ - buf[2] = (3 << 6) | /* reserved -- always 1 */ - ((tc.tm_mday / 10) << 4) | /* Tens of day */ - (tc.tm_mday % 10); /* Units of day */ - buf[3] = /* we set high 4 bits to 0, shouldn't we set them to week? */ - ((tc.tm_mon / 10) << 4) | /* Tens of month */ - (tc.tm_mon % 10); /* Units of month */ - buf[4] = (((tc.tm_year % 100) / 10) << 4) | /* Tens of year */ - (tc.tm_year % 10); /* Units of year */ - break; - case dv_audio_rectime: /* AAUX recording time */ - case dv_video_rectime: /* VAUX recording time */ - ct = c->start_time + av_rescale_rnd(c->frames, c->sys->time_base.num, - c->sys->time_base.den, AV_ROUND_DOWN); - ff_brktimegm(ct, &tc); - buf[1] = (3 << 6) | /* reserved -- always 1 */ - 0x3f; /* tens of frame, units of frame: 0x3f - "unknown" ? */ - buf[2] = (1 << 7) | /* reserved -- always 1 */ - ((tc.tm_sec / 10) << 4) | /* Tens of seconds */ - (tc.tm_sec % 10); /* Units of seconds */ - buf[3] = (1 << 7) | /* reserved -- always 1 */ - ((tc.tm_min / 10) << 4) | /* Tens of minutes */ - (tc.tm_min % 10); /* Units of minutes */ - buf[4] = (3 << 6) | /* reserved -- always 1 */ - ((tc.tm_hour / 10) << 4) | /* Tens of hours */ - (tc.tm_hour % 10); /* Units of hours */ - break; - default: - buf[1] = buf[2] = buf[3] = buf[4] = 0xff; - } - return 5; -} - -static void dv_inject_audio(DVMuxContext *c, int channel, uint8_t* frame_ptr) -{ - int i, j, d, of, size; - size = 4 * dv_audio_frame_size(c->sys, c->frames); - frame_ptr += channel * c->sys->difseg_size * 150 * 80; - for (i = 0; i < c->sys->difseg_size; i++) { - frame_ptr += 6 * 80; /* skip DIF segment header */ - for (j = 0; j < 9; j++) { - dv_write_pack(dv_aaux_packs_dist[i][j], c, &frame_ptr[3], i >= c->sys->difseg_size/2); - for (d = 8; d < 80; d+=2) { - of = c->sys->audio_shuffle[i][j] + (d - 8)/2 * c->sys->audio_stride; - if (of*2 >= size) - continue; - - frame_ptr[d] = *av_fifo_peek2(c->audio_data[channel], of*2+1); // FIXME: maybe we have to admit - frame_ptr[d+1] = *av_fifo_peek2(c->audio_data[channel], of*2); // that DV is a big-endian PCM - } - frame_ptr += 16 * 80; /* 15 Video DIFs + 1 Audio DIF */ - } - } -} - -static void dv_inject_metadata(DVMuxContext *c, uint8_t* frame) -{ - int j, k; - uint8_t* buf; - - for (buf = frame; buf < frame + c->sys->frame_size; buf += 150 * 80) { - /* DV subcode: 2nd and 3d DIFs */ - for (j = 80; j < 80 * 3; j += 80) { - for (k = 6; k < 6 * 8; k += 8) - dv_write_pack(dv_timecode, c, &buf[j+k]); - - if (((long)(buf-frame)/(c->sys->frame_size/(c->sys->difseg_size*c->sys->n_difchan))%c->sys->difseg_size) > 5) { /* FIXME: is this really needed ? */ - dv_write_pack(dv_video_recdate, c, &buf[j+14]); - dv_write_pack(dv_video_rectime, c, &buf[j+22]); - dv_write_pack(dv_video_recdate, c, &buf[j+38]); - dv_write_pack(dv_video_rectime, c, &buf[j+46]); - } - } - - /* DV VAUX: 4th, 5th and 6th 3DIFs */ - for (j = 80*3 + 3; j < 80*6; j += 80) { - dv_write_pack(dv_video_recdate, c, &buf[j+5*2]); - dv_write_pack(dv_video_rectime, c, &buf[j+5*3]); - dv_write_pack(dv_video_recdate, c, &buf[j+5*11]); - dv_write_pack(dv_video_rectime, c, &buf[j+5*12]); - } - } -} - -/* - * The following 3 functions constitute our interface to the world - */ - -static int dv_assemble_frame(DVMuxContext *c, AVStream* st, - uint8_t* data, int data_size, uint8_t** frame) -{ - int i, reqasize; - - *frame = &c->frame_buf[0]; - reqasize = 4 * dv_audio_frame_size(c->sys, c->frames); - - switch (st->codec->codec_type) { - case AVMEDIA_TYPE_VIDEO: - /* FIXME: we have to have more sensible approach than this one */ - if (c->has_video) - av_log(st->codec, AV_LOG_ERROR, "Can't process DV frame #%d. Insufficient audio data or severe sync problem.\n", c->frames); - - memcpy(*frame, data, c->sys->frame_size); - c->has_video = 1; - break; - case AVMEDIA_TYPE_AUDIO: - for (i = 0; i < c->n_ast && st != c->ast[i]; i++); - - /* FIXME: we have to have more sensible approach than this one */ - if (av_fifo_size(c->audio_data[i]) + data_size >= 100*MAX_AUDIO_FRAME_SIZE) - av_log(st->codec, AV_LOG_ERROR, "Can't process DV frame #%d. Insufficient video data or severe sync problem.\n", c->frames); - av_fifo_generic_write(c->audio_data[i], data, data_size, NULL); - - /* Let us see if we've got enough audio for one DV frame. */ - c->has_audio |= ((reqasize <= av_fifo_size(c->audio_data[i])) << i); - - break; - default: - break; - } - - /* Let us see if we have enough data to construct one DV frame. */ - if (c->has_video == 1 && c->has_audio + 1 == 1 << c->n_ast) { - dv_inject_metadata(c, *frame); - c->has_audio = 0; - for (i=0; i < c->n_ast; i++) { - dv_inject_audio(c, i, *frame); - av_fifo_drain(c->audio_data[i], reqasize); - c->has_audio |= ((reqasize <= av_fifo_size(c->audio_data[i])) << i); - } - - c->has_video = 0; - - c->frames++; - - return c->sys->frame_size; - } - - return 0; -} - -static DVMuxContext* dv_init_mux(AVFormatContext* s) -{ - DVMuxContext *c = s->priv_data; - AVStream *vst = NULL; - AVDictionaryEntry *t; - int i; - - /* we support at most 1 video and 2 audio streams */ - if (s->nb_streams > 3) - return NULL; - - c->n_ast = 0; - c->ast[0] = c->ast[1] = NULL; - - /* We have to sort out where audio and where video stream is */ - for (i=0; inb_streams; i++) { - switch (s->streams[i]->codec->codec_type) { - case AVMEDIA_TYPE_VIDEO: - if (vst) return NULL; - vst = s->streams[i]; - break; - case AVMEDIA_TYPE_AUDIO: - if (c->n_ast > 1) return NULL; - c->ast[c->n_ast++] = s->streams[i]; - break; - default: - goto bail_out; - } - } - - /* Some checks -- DV format is very picky about its incoming streams */ - if (!vst || vst->codec->codec_id != AV_CODEC_ID_DVVIDEO) - goto bail_out; - for (i=0; in_ast; i++) { - if (c->ast[i] && (c->ast[i]->codec->codec_id != AV_CODEC_ID_PCM_S16LE || - c->ast[i]->codec->sample_rate != 48000 || - c->ast[i]->codec->channels != 2)) - goto bail_out; - } - c->sys = avpriv_dv_codec_profile(vst->codec); - if (!c->sys) - goto bail_out; - - if ((c->n_ast > 1) && (c->sys->n_difchan < 2)) { - /* only 1 stereo pair is allowed in 25Mbps mode */ - goto bail_out; - } - - /* Ok, everything seems to be in working order */ - c->frames = 0; - c->has_audio = 0; - c->has_video = 0; - if (t = av_dict_get(s->metadata, "creation_time", NULL, 0)) - c->start_time = ff_iso8601_to_unix_time(t->value); - - for (i=0; i < c->n_ast; i++) { - if (c->ast[i] && !(c->audio_data[i]=av_fifo_alloc(100*MAX_AUDIO_FRAME_SIZE))) { - while (i > 0) { - i--; - av_fifo_free(c->audio_data[i]); - } - goto bail_out; - } - } - - return c; - -bail_out: - return NULL; -} - -static void dv_delete_mux(DVMuxContext *c) -{ - int i; - for (i=0; i < c->n_ast; i++) - av_fifo_free(c->audio_data[i]); -} - -static int dv_write_header(AVFormatContext *s) -{ - AVRational rate; - DVMuxContext *dvc = s->priv_data; - AVDictionaryEntry *tcr = av_dict_get(s->metadata, "timecode", NULL, 0); - - if (!dv_init_mux(s)) { - av_log(s, AV_LOG_ERROR, "Can't initialize DV format!\n" - "Make sure that you supply exactly two streams:\n" - " video: 25fps or 29.97fps, audio: 2ch/48kHz/PCM\n" - " (50Mbps allows an optional second audio stream)\n"); - return -1; - } - rate.num = dvc->sys->ltc_divisor; - rate.den = 1; - if (!tcr) { // no global timecode, look into the streams - int i; - for (i = 0; i < s->nb_streams; i++) { - tcr = av_dict_get(s->streams[i]->metadata, "timecode", NULL, 0); - if (tcr) - break; - } - } - if (tcr && av_timecode_init_from_string(&dvc->tc, rate, tcr->value, s) >= 0) - return 0; - return av_timecode_init(&dvc->tc, rate, 0, 0, s); -} - -static int dv_write_packet(struct AVFormatContext *s, AVPacket *pkt) -{ - uint8_t* frame; - int fsize; - - fsize = dv_assemble_frame(s->priv_data, s->streams[pkt->stream_index], - pkt->data, pkt->size, &frame); - if (fsize > 0) { - avio_write(s->pb, frame, fsize); - avio_flush(s->pb); - } - return 0; -} - -/* - * We might end up with some extra A/V data without matching counterpart. - * E.g. video data without enough audio to write the complete frame. - * Currently we simply drop the last frame. I don't know whether this - * is the best strategy of all - */ -static int dv_write_trailer(struct AVFormatContext *s) -{ - dv_delete_mux(s->priv_data); - return 0; -} - -AVOutputFormat ff_dv_muxer = { - .name = "dv", - .long_name = NULL_IF_CONFIG_SMALL("DV (Digital Video)"), - .extensions = "dv", - .priv_data_size = sizeof(DVMuxContext), - .audio_codec = AV_CODEC_ID_PCM_S16LE, - .video_codec = AV_CODEC_ID_DVVIDEO, - .write_header = dv_write_header, - .write_packet = dv_write_packet, - .write_trailer = dv_write_trailer, -}; diff --git a/ffmpeg1/libavformat/dxa.c b/ffmpeg1/libavformat/dxa.c deleted file mode 100644 index 22ee2a9..0000000 --- a/ffmpeg1/libavformat/dxa.c +++ /dev/null @@ -1,225 +0,0 @@ -/* - * DXA demuxer - * Copyright (c) 2007 Konstantin Shishkov - * - * 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 "libavutil/intreadwrite.h" -#include "avformat.h" -#include "internal.h" -#include "riff.h" - -#define DXA_EXTRA_SIZE 9 - -typedef struct{ - int frames; - int has_sound; - int bpc; - uint32_t bytes_left; - int64_t wavpos, vidpos; - int readvid; -}DXAContext; - -static int dxa_probe(AVProbeData *p) -{ - int w, h; - if (p->buf_size < 15) - return 0; - w = AV_RB16(p->buf + 11); - h = AV_RB16(p->buf + 13); - /* check file header */ - if (p->buf[0] == 'D' && p->buf[1] == 'E' && - p->buf[2] == 'X' && p->buf[3] == 'A' && - w && w <= 2048 && h && h <= 2048) - return AVPROBE_SCORE_MAX; - else - return 0; -} - -static int dxa_read_header(AVFormatContext *s) -{ - AVIOContext *pb = s->pb; - DXAContext *c = s->priv_data; - AVStream *st, *ast; - uint32_t tag; - int32_t fps; - int w, h; - int num, den; - int flags; - int ret; - - tag = avio_rl32(pb); - if (tag != MKTAG('D', 'E', 'X', 'A')) - return AVERROR_INVALIDDATA; - flags = avio_r8(pb); - c->frames = avio_rb16(pb); - if(!c->frames){ - av_log(s, AV_LOG_ERROR, "File contains no frames ???\n"); - return AVERROR_INVALIDDATA; - } - - fps = avio_rb32(pb); - if(fps > 0){ - den = 1000; - num = fps; - }else if (fps < 0){ - den = 100000; - num = -fps; - }else{ - den = 10; - num = 1; - } - w = avio_rb16(pb); - h = avio_rb16(pb); - c->has_sound = 0; - - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - - // Parse WAV data header - if(avio_rl32(pb) == MKTAG('W', 'A', 'V', 'E')){ - uint32_t size, fsize; - c->has_sound = 1; - size = avio_rb32(pb); - c->vidpos = avio_tell(pb) + size; - avio_skip(pb, 16); - fsize = avio_rl32(pb); - - ast = avformat_new_stream(s, NULL); - if (!ast) - return AVERROR(ENOMEM); - ret = ff_get_wav_header(pb, ast->codec, fsize); - if (ret < 0) - return ret; - if (ast->codec->sample_rate > 0) - avpriv_set_pts_info(ast, 64, 1, ast->codec->sample_rate); - // find 'data' chunk - while(avio_tell(pb) < c->vidpos && !url_feof(pb)){ - tag = avio_rl32(pb); - fsize = avio_rl32(pb); - if(tag == MKTAG('d', 'a', 't', 'a')) break; - avio_skip(pb, fsize); - } - c->bpc = (fsize + c->frames - 1) / c->frames; - if(ast->codec->block_align) - c->bpc = ((c->bpc + ast->codec->block_align - 1) / ast->codec->block_align) * ast->codec->block_align; - c->bytes_left = fsize; - c->wavpos = avio_tell(pb); - avio_seek(pb, c->vidpos, SEEK_SET); - } - - /* now we are ready: build format streams */ - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = AV_CODEC_ID_DXA; - st->codec->width = w; - st->codec->height = h; - av_reduce(&den, &num, den, num, (1UL<<31)-1); - avpriv_set_pts_info(st, 33, num, den); - /* flags & 0x80 means that image is interlaced, - * flags & 0x40 means that image has double height - * either way set true height - */ - if(flags & 0xC0){ - st->codec->height >>= 1; - } - c->readvid = !c->has_sound; - c->vidpos = avio_tell(pb); - s->start_time = 0; - s->duration = (int64_t)c->frames * AV_TIME_BASE * num / den; - av_log(s, AV_LOG_DEBUG, "%d frame(s)\n",c->frames); - - return 0; -} - -static int dxa_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - DXAContext *c = s->priv_data; - int ret; - uint32_t size; - uint8_t buf[DXA_EXTRA_SIZE], pal[768+4]; - int pal_size = 0; - - if(!c->readvid && c->has_sound && c->bytes_left){ - c->readvid = 1; - avio_seek(s->pb, c->wavpos, SEEK_SET); - size = FFMIN(c->bytes_left, c->bpc); - ret = av_get_packet(s->pb, pkt, size); - pkt->stream_index = 1; - if(ret != size) - return AVERROR(EIO); - c->bytes_left -= size; - c->wavpos = avio_tell(s->pb); - return 0; - } - avio_seek(s->pb, c->vidpos, SEEK_SET); - while(!url_feof(s->pb) && c->frames){ - avio_read(s->pb, buf, 4); - switch(AV_RL32(buf)){ - case MKTAG('N', 'U', 'L', 'L'): - if(av_new_packet(pkt, 4 + pal_size) < 0) - return AVERROR(ENOMEM); - pkt->stream_index = 0; - if(pal_size) memcpy(pkt->data, pal, pal_size); - memcpy(pkt->data + pal_size, buf, 4); - c->frames--; - c->vidpos = avio_tell(s->pb); - c->readvid = 0; - return 0; - case MKTAG('C', 'M', 'A', 'P'): - pal_size = 768+4; - memcpy(pal, buf, 4); - avio_read(s->pb, pal + 4, 768); - break; - case MKTAG('F', 'R', 'A', 'M'): - avio_read(s->pb, buf + 4, DXA_EXTRA_SIZE - 4); - size = AV_RB32(buf + 5); - if(size > 0xFFFFFF){ - av_log(s, AV_LOG_ERROR, "Frame size is too big: %d\n", size); - return AVERROR_INVALIDDATA; - } - if(av_new_packet(pkt, size + DXA_EXTRA_SIZE + pal_size) < 0) - return AVERROR(ENOMEM); - memcpy(pkt->data + pal_size, buf, DXA_EXTRA_SIZE); - ret = avio_read(s->pb, pkt->data + DXA_EXTRA_SIZE + pal_size, size); - if(ret != size){ - av_free_packet(pkt); - return AVERROR(EIO); - } - if(pal_size) memcpy(pkt->data, pal, pal_size); - pkt->stream_index = 0; - c->frames--; - c->vidpos = avio_tell(s->pb); - c->readvid = 0; - return 0; - default: - av_log(s, AV_LOG_ERROR, "Unknown tag %c%c%c%c\n", buf[0], buf[1], buf[2], buf[3]); - return AVERROR_INVALIDDATA; - } - } - return AVERROR_EOF; -} - -AVInputFormat ff_dxa_demuxer = { - .name = "dxa", - .long_name = NULL_IF_CONFIG_SMALL("DXA"), - .priv_data_size = sizeof(DXAContext), - .read_probe = dxa_probe, - .read_header = dxa_read_header, - .read_packet = dxa_read_packet, -}; diff --git a/ffmpeg1/libavformat/eacdata.c b/ffmpeg1/libavformat/eacdata.c deleted file mode 100644 index 57e5145..0000000 --- a/ffmpeg1/libavformat/eacdata.c +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Electronic Arts .cdata file Demuxer - * Copyright (c) 2007 Peter Ross - * - * 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 - */ - -/** - * @file - * Electronic Arts cdata Format Demuxer - * by Peter Ross (pross@xvid.org) - * - * Technical details here: - * http://wiki.multimedia.cx/index.php?title=EA_Command_And_Conquer_3_Audio_Codec - */ - -#include "avformat.h" -#include "internal.h" - -typedef struct { - unsigned int channels; - unsigned int audio_pts; -} CdataDemuxContext; - -static int cdata_probe(AVProbeData *p) -{ - const uint8_t *b = p->buf; - - if (b[0] == 0x04 && (b[1] == 0x00 || b[1] == 0x04 || b[1] == 0x0C || b[1] == 0x14)) - return AVPROBE_SCORE_MAX/8; - return 0; -} - -static int cdata_read_header(AVFormatContext *s) -{ - CdataDemuxContext *cdata = s->priv_data; - AVIOContext *pb = s->pb; - unsigned int sample_rate, header; - AVStream *st; - int64_t channel_layout = 0; - - header = avio_rb16(pb); - switch (header) { - case 0x0400: cdata->channels = 1; break; - case 0x0404: cdata->channels = 2; break; - case 0x040C: cdata->channels = 4; channel_layout = AV_CH_LAYOUT_QUAD; break; - case 0x0414: cdata->channels = 6; channel_layout = AV_CH_LAYOUT_5POINT1_BACK; break; - default: - av_log(s, AV_LOG_INFO, "unknown header 0x%04x\n", header); - return -1; - }; - - sample_rate = avio_rb16(pb); - avio_skip(pb, (avio_r8(pb) & 0x20) ? 15 : 11); - - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_tag = 0; /* no fourcc */ - st->codec->codec_id = AV_CODEC_ID_ADPCM_EA_XAS; - st->codec->channels = cdata->channels; - st->codec->channel_layout = channel_layout; - st->codec->sample_rate = sample_rate; - avpriv_set_pts_info(st, 64, 1, sample_rate); - - cdata->audio_pts = 0; - return 0; -} - -static int cdata_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - CdataDemuxContext *cdata = s->priv_data; - int packet_size = 76*cdata->channels; - - int ret = av_get_packet(s->pb, pkt, packet_size); - if (ret < 0) - return ret; - pkt->pts = cdata->audio_pts++; - return 0; -} - -AVInputFormat ff_ea_cdata_demuxer = { - .name = "ea_cdata", - .long_name = NULL_IF_CONFIG_SMALL("Electronic Arts cdata"), - .priv_data_size = sizeof(CdataDemuxContext), - .read_probe = cdata_probe, - .read_header = cdata_read_header, - .read_packet = cdata_read_packet, - .extensions = "cdata", -}; diff --git a/ffmpeg1/libavformat/electronicarts.c b/ffmpeg1/libavformat/electronicarts.c deleted file mode 100644 index cf7a271..0000000 --- a/ffmpeg1/libavformat/electronicarts.c +++ /dev/null @@ -1,636 +0,0 @@ -/* Electronic Arts Multimedia File Demuxer - * Copyright (c) 2004 The ffmpeg Project - * Copyright (c) 2006-2008 Peter Ross - * - * 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 - */ - -/** - * @file - * Electronic Arts Multimedia file demuxer (WVE/UV2/etc.) - * by Robin Kay (komadori at gekkou.co.uk) - */ - -#include "libavutil/intreadwrite.h" -#include "avformat.h" -#include "internal.h" - -#define SCHl_TAG MKTAG('S', 'C', 'H', 'l') -#define SEAD_TAG MKTAG('S', 'E', 'A', 'D') /* Sxxx header */ -#define SNDC_TAG MKTAG('S', 'N', 'D', 'C') /* Sxxx data */ -#define SEND_TAG MKTAG('S', 'E', 'N', 'D') /* Sxxx end */ -#define SHEN_TAG MKTAG('S', 'H', 'E', 'N') /* SxEN header */ -#define SDEN_TAG MKTAG('S', 'D', 'E', 'N') /* SxEN data */ -#define SEEN_TAG MKTAG('S', 'E', 'E', 'N') /* SxEN end */ -#define ISNh_TAG MKTAG('1', 'S', 'N', 'h') /* 1SNx header */ -#define EACS_TAG MKTAG('E', 'A', 'C', 'S') -#define ISNd_TAG MKTAG('1', 'S', 'N', 'd') /* 1SNx data */ -#define ISNe_TAG MKTAG('1', 'S', 'N', 'e') /* 1SNx end */ -#define PT00_TAG MKTAG('P', 'T', 0x0, 0x0) -#define GSTR_TAG MKTAG('G', 'S', 'T', 'R') -#define SCDl_TAG MKTAG('S', 'C', 'D', 'l') -#define SCEl_TAG MKTAG('S', 'C', 'E', 'l') -#define kVGT_TAG MKTAG('k', 'V', 'G', 'T') /* TGV i-frame */ -#define fVGT_TAG MKTAG('f', 'V', 'G', 'T') /* TGV p-frame */ -#define mTCD_TAG MKTAG('m', 'T', 'C', 'D') /* MDEC */ -#define MADk_TAG MKTAG('M', 'A', 'D', 'k') /* MAD i-frame */ -#define MADm_TAG MKTAG('M', 'A', 'D', 'm') /* MAD p-frame */ -#define MADe_TAG MKTAG('M', 'A', 'D', 'e') /* MAD lqp-frame */ -#define MPCh_TAG MKTAG('M', 'P', 'C', 'h') /* MPEG2 */ -#define TGQs_TAG MKTAG('T', 'G', 'Q', 's') /* TGQ i-frame (appears in .TGQ files) */ -#define pQGT_TAG MKTAG('p', 'Q', 'G', 'T') /* TGQ i-frame (appears in .UV files) */ -#define pIQT_TAG MKTAG('p', 'I', 'Q', 'T') /* TQI/UV2 i-frame (.UV2/.WVE) */ -#define MVhd_TAG MKTAG('M', 'V', 'h', 'd') -#define MV0K_TAG MKTAG('M', 'V', '0', 'K') -#define MV0F_TAG MKTAG('M', 'V', '0', 'F') -#define MVIh_TAG MKTAG('M', 'V', 'I', 'h') /* CMV header */ -#define MVIf_TAG MKTAG('M', 'V', 'I', 'f') /* CMV i-frame */ - -typedef struct EaDemuxContext { - int big_endian; - - enum AVCodecID video_codec; - AVRational time_base; - int width, height; - int nb_frames; - int video_stream_index; - - enum AVCodecID audio_codec; - int audio_stream_index; - - int bytes; - int sample_rate; - int num_channels; - int num_samples; -} EaDemuxContext; - -static uint32_t read_arbitary(AVIOContext *pb) { - uint8_t size, byte; - int i; - uint32_t word; - - size = avio_r8(pb); - - word = 0; - for (i = 0; i < size; i++) { - byte = avio_r8(pb); - word <<= 8; - word |= byte; - } - - return word; -} - -/* - * Process PT/GSTR sound header - * return 1 if success, 0 if invalid format, otherwise AVERROR_xxx - */ -static int process_audio_header_elements(AVFormatContext *s) -{ - int inHeader = 1; - EaDemuxContext *ea = s->priv_data; - AVIOContext *pb = s->pb; - int compression_type = -1, revision = -1, revision2 = -1; - - ea->bytes = 2; - ea->sample_rate = -1; - ea->num_channels = 1; - - while (!url_feof(pb) && inHeader) { - int inSubheader; - uint8_t byte; - byte = avio_r8(pb); - - switch (byte) { - case 0xFD: - av_log (s, AV_LOG_DEBUG, "entered audio subheader\n"); - inSubheader = 1; - while (!url_feof(pb) && inSubheader) { - uint8_t subbyte; - subbyte = avio_r8(pb); - - switch (subbyte) { - case 0x80: - revision = read_arbitary(pb); - av_log (s, AV_LOG_DEBUG, "revision (element 0x80) set to 0x%08x\n", revision); - break; - case 0x82: - ea->num_channels = read_arbitary(pb); - av_log (s, AV_LOG_DEBUG, "num_channels (element 0x82) set to 0x%08x\n", ea->num_channels); - break; - case 0x83: - compression_type = read_arbitary(pb); - av_log (s, AV_LOG_DEBUG, "compression_type (element 0x83) set to 0x%08x\n", compression_type); - break; - case 0x84: - ea->sample_rate = read_arbitary(pb); - av_log (s, AV_LOG_DEBUG, "sample_rate (element 0x84) set to %i\n", ea->sample_rate); - break; - case 0x85: - ea->num_samples = read_arbitary(pb); - av_log (s, AV_LOG_DEBUG, "num_samples (element 0x85) set to 0x%08x\n", ea->num_samples); - break; - case 0x8A: - av_log (s, AV_LOG_DEBUG, "element 0x%02x set to 0x%08x\n", subbyte, read_arbitary(pb)); - av_log (s, AV_LOG_DEBUG, "exited audio subheader\n"); - inSubheader = 0; - break; - case 0xA0: - revision2 = read_arbitary(pb); - av_log (s, AV_LOG_DEBUG, "revision2 (element 0xA0) set to 0x%08x\n", revision2); - break; - case 0xFF: - av_log (s, AV_LOG_DEBUG, "end of header block reached (within audio subheader)\n"); - inSubheader = 0; - inHeader = 0; - break; - default: - av_log (s, AV_LOG_DEBUG, "element 0x%02x set to 0x%08x\n", subbyte, read_arbitary(pb)); - break; - } - } - break; - case 0xFF: - av_log (s, AV_LOG_DEBUG, "end of header block reached\n"); - inHeader = 0; - break; - default: - av_log (s, AV_LOG_DEBUG, "header element 0x%02x set to 0x%08x\n", byte, read_arbitary(pb)); - break; - } - } - - switch (compression_type) { - case 0: ea->audio_codec = AV_CODEC_ID_PCM_S16LE; break; - case 7: ea->audio_codec = AV_CODEC_ID_ADPCM_EA; break; - case -1: - switch (revision) { - case 1: ea->audio_codec = AV_CODEC_ID_ADPCM_EA_R1; break; - case 2: ea->audio_codec = AV_CODEC_ID_ADPCM_EA_R2; break; - case 3: ea->audio_codec = AV_CODEC_ID_ADPCM_EA_R3; break; - case -1: break; - default: - avpriv_request_sample(s, "stream type; revision=%i", revision); - return 0; - } - switch (revision2) { - case 8: ea->audio_codec = AV_CODEC_ID_PCM_S16LE_PLANAR; break; - case 10: - switch (revision) { - case -1: - case 2: ea->audio_codec = AV_CODEC_ID_ADPCM_EA_R1; break; - case 3: ea->audio_codec = AV_CODEC_ID_ADPCM_EA_R2; break; - default: - avpriv_request_sample(s, "stream type; revision=%i, revision2=%i", revision, revision2); - return 0; - } - break; - case 16: ea->audio_codec = AV_CODEC_ID_MP3; break; - case -1: break; - default: - ea->audio_codec = AV_CODEC_ID_NONE; - avpriv_request_sample(s, "stream type; revision2=%i", revision2); - return 0; - } - break; - default: - avpriv_request_sample(s, "stream type; compression_type=%i", compression_type); - return 0; - } - - if (ea->sample_rate == -1) - ea->sample_rate = revision==3 ? 48000 : 22050; - - return 1; -} - -/* - * Process EACS sound header - * return 1 if success, 0 if invalid format, otherwise AVERROR_xxx - */ -static int process_audio_header_eacs(AVFormatContext *s) -{ - EaDemuxContext *ea = s->priv_data; - AVIOContext *pb = s->pb; - int compression_type; - - ea->sample_rate = ea->big_endian ? avio_rb32(pb) : avio_rl32(pb); - ea->bytes = avio_r8(pb); /* 1=8-bit, 2=16-bit */ - ea->num_channels = avio_r8(pb); - compression_type = avio_r8(pb); - avio_skip(pb, 13); - - switch (compression_type) { - case 0: - switch (ea->bytes) { - case 1: ea->audio_codec = AV_CODEC_ID_PCM_S8; break; - case 2: ea->audio_codec = AV_CODEC_ID_PCM_S16LE; break; - } - break; - case 1: ea->audio_codec = AV_CODEC_ID_PCM_MULAW; ea->bytes = 1; break; - case 2: ea->audio_codec = AV_CODEC_ID_ADPCM_IMA_EA_EACS; break; - default: - avpriv_request_sample(s, "stream type; audio compression_type=%i", compression_type); - } - - return 1; -} - -/* - * Process SEAD sound header - * return 1 if success, 0 if invalid format, otherwise AVERROR_xxx - */ -static int process_audio_header_sead(AVFormatContext *s) -{ - EaDemuxContext *ea = s->priv_data; - AVIOContext *pb = s->pb; - - ea->sample_rate = avio_rl32(pb); - ea->bytes = avio_rl32(pb); /* 1=8-bit, 2=16-bit */ - ea->num_channels = avio_rl32(pb); - ea->audio_codec = AV_CODEC_ID_ADPCM_IMA_EA_SEAD; - - return 1; -} - -static int process_video_header_mdec(AVFormatContext *s) -{ - EaDemuxContext *ea = s->priv_data; - AVIOContext *pb = s->pb; - avio_skip(pb, 4); - ea->width = avio_rl16(pb); - ea->height = avio_rl16(pb); - ea->time_base = (AVRational){1,15}; - ea->video_codec = AV_CODEC_ID_MDEC; - return 1; -} - -static int process_video_header_vp6(AVFormatContext *s) -{ - EaDemuxContext *ea = s->priv_data; - AVIOContext *pb = s->pb; - - avio_skip(pb, 8); - ea->nb_frames = avio_rl32(pb); - avio_skip(pb, 4); - ea->time_base.den = avio_rl32(pb); - ea->time_base.num = avio_rl32(pb); - ea->video_codec = AV_CODEC_ID_VP6; - - return 1; -} - -static int process_video_header_cmv(AVFormatContext *s) -{ - EaDemuxContext *ea = s->priv_data; - int fps; - - avio_skip(s->pb, 10); - fps = avio_rl16(s->pb); - if (fps) - ea->time_base = (AVRational){1, fps}; - ea->video_codec = AV_CODEC_ID_CMV; - - return 0; -} - -/* - * Process EA file header - * Returns 1 if the EA file is valid and successfully opened, 0 otherwise - */ -static int process_ea_header(AVFormatContext *s) { - uint32_t blockid, size = 0; - EaDemuxContext *ea = s->priv_data; - AVIOContext *pb = s->pb; - int i; - - for (i=0; i<5 && (!ea->audio_codec || !ea->video_codec); i++) { - unsigned int startpos = avio_tell(pb); - int err = 0; - - blockid = avio_rl32(pb); - size = avio_rl32(pb); - if (i == 0) - ea->big_endian = size > 0x000FFFFF; - if (ea->big_endian) - size = av_bswap32(size); - - switch (blockid) { - case ISNh_TAG: - if (avio_rl32(pb) != EACS_TAG) { - avpriv_request_sample(s, "unknown 1SNh headerid"); - return 0; - } - err = process_audio_header_eacs(s); - break; - - case SCHl_TAG : - case SHEN_TAG : - blockid = avio_rl32(pb); - if (blockid == GSTR_TAG) { - avio_skip(pb, 4); - } else if ((blockid & 0xFFFF)!=PT00_TAG) { - avpriv_request_sample(s, "unknown SCHl headerid"); - return 0; - } - err = process_audio_header_elements(s); - break; - - case SEAD_TAG: - err = process_audio_header_sead(s); - break; - - case MVIh_TAG : - err = process_video_header_cmv(s); - break; - - case kVGT_TAG: - ea->video_codec = AV_CODEC_ID_TGV; - break; - - case mTCD_TAG : - err = process_video_header_mdec(s); - break; - - case MPCh_TAG: - ea->video_codec = AV_CODEC_ID_MPEG2VIDEO; - break; - - case pQGT_TAG: - case TGQs_TAG: - ea->video_codec = AV_CODEC_ID_TGQ; - break; - - case pIQT_TAG: - ea->video_codec = AV_CODEC_ID_TQI; - break; - - case MADk_TAG : - ea->video_codec = AV_CODEC_ID_MAD; - break; - - case MVhd_TAG : - err = process_video_header_vp6(s); - break; - } - - if (err < 0) { - av_log(s, AV_LOG_ERROR, "error parsing header: %i\n", err); - return err; - } - - avio_seek(pb, startpos + size, SEEK_SET); - } - - avio_seek(pb, 0, SEEK_SET); - - return 1; -} - - -static int ea_probe(AVProbeData *p) -{ - switch (AV_RL32(&p->buf[0])) { - case ISNh_TAG: - case SCHl_TAG: - case SEAD_TAG: - case SHEN_TAG: - case kVGT_TAG: - case MADk_TAG: - case MPCh_TAG: - case MVhd_TAG: - case MVIh_TAG: - break; - default: - return 0; - } - if (AV_RL32(&p->buf[4]) > 0xfffff && AV_RB32(&p->buf[4]) > 0xfffff) - return 0; - return AVPROBE_SCORE_MAX; -} - -static int ea_read_header(AVFormatContext *s) -{ - EaDemuxContext *ea = s->priv_data; - AVStream *st; - - if (process_ea_header(s)<=0) - return AVERROR(EIO); - - if (ea->video_codec) { - /* initialize the video decoder stream */ - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - ea->video_stream_index = st->index; - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = ea->video_codec; - // parsing is necessary to make FFmpeg generate correct timestamps - if (st->codec->codec_id == AV_CODEC_ID_MPEG2VIDEO) - st->need_parsing = AVSTREAM_PARSE_HEADERS; - st->codec->codec_tag = 0; /* no fourcc */ - st->codec->width = ea->width; - st->codec->height = ea->height; - st->duration = st->nb_frames = ea->nb_frames; - if (ea->time_base.num) - avpriv_set_pts_info(st, 64, ea->time_base.num, ea->time_base.den); - st->r_frame_rate = - st->avg_frame_rate = av_inv_q(ea->time_base); - } - - if (ea->audio_codec) { - if (ea->num_channels <= 0) { - av_log(s, AV_LOG_WARNING, "Unsupported number of channels: %d\n", ea->num_channels); - ea->audio_codec = 0; - return 1; - } - if (ea->sample_rate <= 0) { - av_log(s, AV_LOG_ERROR, "Unsupported sample rate: %d\n", ea->sample_rate); - ea->audio_codec = 0; - return 1; - } - if (ea->bytes <= 0) { - av_log(s, AV_LOG_ERROR, "Invalid number of bytes per sample: %d\n", ea->bytes); - ea->audio_codec = AV_CODEC_ID_NONE; - return 1; - } - - /* initialize the audio decoder stream */ - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - avpriv_set_pts_info(st, 33, 1, ea->sample_rate); - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = ea->audio_codec; - st->codec->codec_tag = 0; /* no tag */ - st->codec->channels = ea->num_channels; - st->codec->sample_rate = ea->sample_rate; - st->codec->bits_per_coded_sample = ea->bytes * 8; - st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * - st->codec->bits_per_coded_sample / 4; - st->codec->block_align = st->codec->channels*st->codec->bits_per_coded_sample; - ea->audio_stream_index = st->index; - st->start_time = 0; - } - - return 1; -} - -static int ea_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - EaDemuxContext *ea = s->priv_data; - AVIOContext *pb = s->pb; - int ret = 0; - int packet_read = 0; - int partial_packet = 0; - unsigned int chunk_type, chunk_size; - int key = 0; - int av_uninit(num_samples); - - while (!packet_read || partial_packet) { - chunk_type = avio_rl32(pb); - chunk_size = ea->big_endian ? avio_rb32(pb) : avio_rl32(pb); - if (chunk_size <= 8) - return AVERROR_INVALIDDATA; - chunk_size -= 8; - - switch (chunk_type) { - /* audio data */ - case ISNh_TAG: - /* header chunk also contains data; skip over the header portion*/ - if (chunk_size < 32) - return AVERROR_INVALIDDATA; - avio_skip(pb, 32); - chunk_size -= 32; - case ISNd_TAG: - case SCDl_TAG: - case SNDC_TAG: - case SDEN_TAG: - if (!ea->audio_codec) { - avio_skip(pb, chunk_size); - break; - } else if (ea->audio_codec == AV_CODEC_ID_PCM_S16LE_PLANAR || - ea->audio_codec == AV_CODEC_ID_MP3) { - num_samples = avio_rl32(pb); - avio_skip(pb, 8); - chunk_size -= 12; - } - if (partial_packet) { - avpriv_request_sample(s, "video header followed by audio packet"); - av_free_packet(pkt); - partial_packet = 0; - } - ret = av_get_packet(pb, pkt, chunk_size); - if (ret < 0) - return ret; - pkt->stream_index = ea->audio_stream_index; - - switch (ea->audio_codec) { - case AV_CODEC_ID_ADPCM_EA: - case AV_CODEC_ID_ADPCM_EA_R1: - case AV_CODEC_ID_ADPCM_EA_R2: - case AV_CODEC_ID_ADPCM_IMA_EA_EACS: - if (pkt->size >= 4) - pkt->duration = AV_RL32(pkt->data); - break; - case AV_CODEC_ID_ADPCM_EA_R3: - if (pkt->size >= 4) - pkt->duration = AV_RB32(pkt->data); - break; - case AV_CODEC_ID_ADPCM_IMA_EA_SEAD: - pkt->duration = ret * 2 / ea->num_channels; - break; - case AV_CODEC_ID_PCM_S16LE_PLANAR: - case AV_CODEC_ID_MP3: - pkt->duration = num_samples; - break; - default: - pkt->duration = chunk_size / (ea->bytes * ea->num_channels); - } - - packet_read = 1; - break; - - /* ending tag */ - case 0: - case ISNe_TAG: - case SCEl_TAG: - case SEND_TAG: - case SEEN_TAG: - ret = AVERROR(EIO); - packet_read = 1; - break; - - case MVIh_TAG: - case kVGT_TAG: - case pQGT_TAG: - case TGQs_TAG: - case MADk_TAG: - key = AV_PKT_FLAG_KEY; - case MVIf_TAG: - case fVGT_TAG: - case MADm_TAG: - case MADe_TAG: - avio_seek(pb, -8, SEEK_CUR); // include chunk preamble - chunk_size += 8; - goto get_video_packet; - - case mTCD_TAG: - avio_skip(pb, 8); // skip ea dct header - chunk_size -= 8; - goto get_video_packet; - - case MV0K_TAG: - case MPCh_TAG: - case pIQT_TAG: - key = AV_PKT_FLAG_KEY; - case MV0F_TAG: -get_video_packet: - if (partial_packet) { - ret = av_append_packet(pb, pkt, chunk_size); - } else - ret = av_get_packet(pb, pkt, chunk_size); - if (ret < 0) { - packet_read = 1; - break; - } - partial_packet = chunk_type == MVIh_TAG; - pkt->stream_index = ea->video_stream_index; - pkt->flags |= key; - packet_read = 1; - break; - - default: - avio_skip(pb, chunk_size); - break; - } - } - - if (ret < 0 && partial_packet) - av_free_packet(pkt); - return ret; -} - -AVInputFormat ff_ea_demuxer = { - .name = "ea", - .long_name = NULL_IF_CONFIG_SMALL("Electronic Arts Multimedia"), - .priv_data_size = sizeof(EaDemuxContext), - .read_probe = ea_probe, - .read_header = ea_read_header, - .read_packet = ea_read_packet, -}; diff --git a/ffmpeg1/libavformat/epafdec.c b/ffmpeg1/libavformat/epafdec.c deleted file mode 100644 index c737892..0000000 --- a/ffmpeg1/libavformat/epafdec.c +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Ensoniq Paris Audio File demuxer - * Copyright (c) 2012 Paul B Mahol - * - * 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 "libavutil/intreadwrite.h" -#include "avformat.h" -#include "internal.h" -#include "pcm.h" - -static int epaf_probe(AVProbeData *p) -{ - if (((AV_RL32(p->buf) == MKTAG('f','a','p',' ') && - AV_RL32(p->buf + 8) == 1) || - (AV_RL32(p->buf) == MKTAG(' ','p','a','f') && - AV_RN32(p->buf + 8) == 0)) && - !AV_RN32(p->buf + 4) && AV_RN32(p->buf + 12) && - AV_RN32(p->buf + 20)) - return AVPROBE_SCORE_MAX / 4 * 3; - return 0; -} - -static int epaf_read_header(AVFormatContext *s) -{ - int le, sample_rate, codec, channels; - AVStream *st; - - avio_skip(s->pb, 4); - if (avio_rl32(s->pb)) - return AVERROR_INVALIDDATA; - - le = avio_rl32(s->pb); - if (le && le != 1) - return AVERROR_INVALIDDATA; - - if (le) { - sample_rate = avio_rl32(s->pb); - codec = avio_rl32(s->pb); - channels = avio_rl32(s->pb); - } else { - sample_rate = avio_rb32(s->pb); - codec = avio_rb32(s->pb); - channels = avio_rb32(s->pb); - } - - if (!channels || !sample_rate) - return AVERROR_INVALIDDATA; - - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->channels = channels; - st->codec->sample_rate = sample_rate; - switch (codec) { - case 0: - st->codec->codec_id = le ? AV_CODEC_ID_PCM_S16LE : AV_CODEC_ID_PCM_S16BE; - break; - case 2: - st->codec->codec_id = AV_CODEC_ID_PCM_S8; - break; - case 1: - avpriv_request_sample(s, "24-bit Paris PCM format"); - default: - return AVERROR_INVALIDDATA; - } - - st->codec->bits_per_coded_sample = av_get_bits_per_sample(st->codec->codec_id); - st->codec->block_align = st->codec->bits_per_coded_sample * st->codec->channels / 8; - - avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); - - if (avio_skip(s->pb, 2024) < 0) - return AVERROR_INVALIDDATA; - return 0; -} - -AVInputFormat ff_epaf_demuxer = { - .name = "epaf", - .long_name = NULL_IF_CONFIG_SMALL("Ensoniq Paris Audio File"), - .read_probe = epaf_probe, - .read_header = epaf_read_header, - .read_packet = ff_pcm_read_packet, - .read_seek = ff_pcm_read_seek, - .extensions = "paf,fap", - .flags = AVFMT_GENERIC_INDEX, -}; diff --git a/ffmpeg1/libavformat/ffm.h b/ffmpeg1/libavformat/ffm.h deleted file mode 100644 index b392b8d..0000000 --- a/ffmpeg1/libavformat/ffm.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * FFM (ffserver live feed) common header - * 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 AVFORMAT_FFM_H -#define AVFORMAT_FFM_H - -#include -#include "avformat.h" -#include "avio.h" - -/* The FFM file is made of blocks of fixed size */ -#define FFM_HEADER_SIZE 14 -#define FFM_PACKET_SIZE 4096 -#define PACKET_ID 0x666d - -/* each packet contains frames (which can span several packets */ -#define FRAME_HEADER_SIZE 16 -#define FLAG_KEY_FRAME 0x01 -#define FLAG_DTS 0x02 - -enum { - READ_HEADER, - READ_DATA, -}; - -typedef struct FFMContext { - /* only reading mode */ - int64_t write_index, file_size; - int read_state; - uint8_t header[FRAME_HEADER_SIZE+4]; - - /* read and write */ - int first_packet; /* true if first packet, needed to set the discontinuity tag */ - int packet_size; - int frame_offset; - int64_t dts; - uint8_t *packet_ptr, *packet_end; - uint8_t packet[FFM_PACKET_SIZE]; - int64_t start_time; -} FFMContext; - -#endif /* AVFORMAT_FFM_H */ diff --git a/ffmpeg1/libavformat/ffmdec.c b/ffmpeg1/libavformat/ffmdec.c deleted file mode 100644 index 02cf790..0000000 --- a/ffmpeg1/libavformat/ffmdec.c +++ /dev/null @@ -1,639 +0,0 @@ -/* - * FFM (ffserver live feed) demuxer - * 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 - */ - -#include "libavutil/intreadwrite.h" -#include "libavutil/intfloat.h" -#include "avformat.h" -#include "internal.h" -#include "ffm.h" -#include "avio_internal.h" - -static int ffm_is_avail_data(AVFormatContext *s, int size) -{ - FFMContext *ffm = s->priv_data; - int64_t pos, avail_size; - int len; - - len = ffm->packet_end - ffm->packet_ptr; - if (size <= len) - return 1; - pos = avio_tell(s->pb); - if (!ffm->write_index) { - if (pos == ffm->file_size) - return AVERROR_EOF; - avail_size = ffm->file_size - pos; - } else { - if (pos == ffm->write_index) { - /* exactly at the end of stream */ - return AVERROR(EAGAIN); - } else if (pos < ffm->write_index) { - avail_size = ffm->write_index - pos; - } else { - avail_size = (ffm->file_size - pos) + (ffm->write_index - FFM_PACKET_SIZE); - } - } - avail_size = (avail_size / ffm->packet_size) * (ffm->packet_size - FFM_HEADER_SIZE) + len; - if (size <= avail_size) - return 1; - else - return AVERROR(EAGAIN); -} - -static int ffm_resync(AVFormatContext *s, int state) -{ - av_log(s, AV_LOG_ERROR, "resyncing\n"); - while (state != PACKET_ID) { - if (url_feof(s->pb)) { - av_log(s, AV_LOG_ERROR, "cannot find FFM syncword\n"); - return -1; - } - state = (state << 8) | avio_r8(s->pb); - } - return 0; -} - -/* first is true if we read the frame header */ -static int ffm_read_data(AVFormatContext *s, - uint8_t *buf, int size, int header) -{ - FFMContext *ffm = s->priv_data; - AVIOContext *pb = s->pb; - int len, fill_size, size1, frame_offset, id; - - size1 = size; - while (size > 0) { - redo: - len = ffm->packet_end - ffm->packet_ptr; - if (len < 0) - return -1; - if (len > size) - len = size; - if (len == 0) { - if (avio_tell(pb) == ffm->file_size) - avio_seek(pb, ffm->packet_size, SEEK_SET); - retry_read: - if (pb->buffer_size != ffm->packet_size) { - int64_t tell = avio_tell(pb); - ffio_set_buf_size(pb, ffm->packet_size); - avio_seek(pb, tell, SEEK_SET); - } - id = avio_rb16(pb); /* PACKET_ID */ - if (id != PACKET_ID) - if (ffm_resync(s, id) < 0) - return -1; - fill_size = avio_rb16(pb); - ffm->dts = avio_rb64(pb); - frame_offset = avio_rb16(pb); - avio_read(pb, ffm->packet, ffm->packet_size - FFM_HEADER_SIZE); - ffm->packet_end = ffm->packet + (ffm->packet_size - FFM_HEADER_SIZE - fill_size); - if (ffm->packet_end < ffm->packet || frame_offset < 0) - return -1; - /* if first packet or resynchronization packet, we must - handle it specifically */ - if (ffm->first_packet || (frame_offset & 0x8000)) { - if (!frame_offset) { - /* This packet has no frame headers in it */ - if (avio_tell(pb) >= ffm->packet_size * 3LL) { - avio_seek(pb, -ffm->packet_size * 2LL, SEEK_CUR); - goto retry_read; - } - /* This is bad, we cannot find a valid frame header */ - return 0; - } - ffm->first_packet = 0; - if ((frame_offset & 0x7fff) < FFM_HEADER_SIZE) - return -1; - ffm->packet_ptr = ffm->packet + (frame_offset & 0x7fff) - FFM_HEADER_SIZE; - if (!header) - break; - } else { - ffm->packet_ptr = ffm->packet; - } - goto redo; - } - memcpy(buf, ffm->packet_ptr, len); - buf += len; - ffm->packet_ptr += len; - size -= len; - header = 0; - } - return size1 - size; -} - -/* ensure that acutal seeking happens between FFM_PACKET_SIZE - and file_size - FFM_PACKET_SIZE */ -static int64_t ffm_seek1(AVFormatContext *s, int64_t pos1) -{ - FFMContext *ffm = s->priv_data; - AVIOContext *pb = s->pb; - int64_t pos; - - pos = FFMIN(pos1, ffm->file_size - FFM_PACKET_SIZE); - pos = FFMAX(pos, FFM_PACKET_SIZE); - av_dlog(s, "seek to %"PRIx64" -> %"PRIx64"\n", pos1, pos); - return avio_seek(pb, pos, SEEK_SET); -} - -static int64_t get_dts(AVFormatContext *s, int64_t pos) -{ - AVIOContext *pb = s->pb; - int64_t dts; - - ffm_seek1(s, pos); - avio_skip(pb, 4); - dts = avio_rb64(pb); - av_dlog(s, "dts=%0.6f\n", dts / 1000000.0); - return dts; -} - -static void adjust_write_index(AVFormatContext *s) -{ - FFMContext *ffm = s->priv_data; - AVIOContext *pb = s->pb; - int64_t pts; - //int64_t orig_write_index = ffm->write_index; - int64_t pos_min, pos_max; - int64_t pts_start; - int64_t ptr = avio_tell(pb); - - - pos_min = 0; - pos_max = ffm->file_size - 2 * FFM_PACKET_SIZE; - - pts_start = get_dts(s, pos_min); - - pts = get_dts(s, pos_max); - - if (pts - 100000 > pts_start) - goto end; - - ffm->write_index = FFM_PACKET_SIZE; - - pts_start = get_dts(s, pos_min); - - pts = get_dts(s, pos_max); - - if (pts - 100000 <= pts_start) { - while (1) { - int64_t newpos; - int64_t newpts; - - newpos = ((pos_max + pos_min) / (2 * FFM_PACKET_SIZE)) * FFM_PACKET_SIZE; - - if (newpos == pos_min) - break; - - newpts = get_dts(s, newpos); - - if (newpts - 100000 <= pts) { - pos_max = newpos; - pts = newpts; - } else { - pos_min = newpos; - } - } - ffm->write_index += pos_max; - } - - end: - avio_seek(pb, ptr, SEEK_SET); -} - - -static int ffm_close(AVFormatContext *s) -{ - int i; - - for (i = 0; i < s->nb_streams; i++) - av_freep(&s->streams[i]->codec->rc_eq); - - return 0; -} - -static int ffm2_read_header(AVFormatContext *s) -{ - FFMContext *ffm = s->priv_data; - AVStream *st; - AVIOContext *pb = s->pb; - AVCodecContext *codec; - - ffm->packet_size = avio_rb32(pb); - if (ffm->packet_size != FFM_PACKET_SIZE) - goto fail; - ffm->write_index = avio_rb64(pb); - /* get also filesize */ - if (pb->seekable) { - ffm->file_size = avio_size(pb); - if (ffm->write_index && 0) - adjust_write_index(s); - } else { - ffm->file_size = (UINT64_C(1) << 63) - 1; - } - - while(!url_feof(pb)) { - unsigned id = avio_rb32(pb); - unsigned size = avio_rb32(pb); - int64_t next = avio_tell(pb) + size; - char rc_eq_buf[128]; - - if(!id) - break; - - switch(id) { - case MKBETAG('M', 'A', 'I', 'N'): - avio_rb32(pb); /* nb_streams */ - avio_rb32(pb); /* total bitrate */ - break; - case MKBETAG('C', 'O', 'M', 'M'): - st = avformat_new_stream(s, NULL); - if (!st) - goto fail; - - avpriv_set_pts_info(st, 64, 1, 1000000); - - codec = st->codec; - /* generic info */ - codec->codec_id = avio_rb32(pb); - codec->codec_type = avio_r8(pb); - codec->bit_rate = avio_rb32(pb); - codec->flags = avio_rb32(pb); - codec->flags2 = avio_rb32(pb); - codec->debug = avio_rb32(pb); - if (codec->flags & CODEC_FLAG_GLOBAL_HEADER) { - codec->extradata_size = avio_rb32(pb); - codec->extradata = av_malloc(codec->extradata_size); - if (!codec->extradata) - return AVERROR(ENOMEM); - avio_read(pb, codec->extradata, codec->extradata_size); - } - avio_seek(pb, next, SEEK_SET); - id = avio_rb32(pb); - size = avio_rb32(pb); - next = avio_tell(pb) + size; - switch(id) { - case MKBETAG('S', 'T', 'V', 'I'): - codec->time_base.num = avio_rb32(pb); - codec->time_base.den = avio_rb32(pb); - codec->width = avio_rb16(pb); - codec->height = avio_rb16(pb); - codec->gop_size = avio_rb16(pb); - codec->pix_fmt = avio_rb32(pb); - codec->qmin = avio_r8(pb); - codec->qmax = avio_r8(pb); - codec->max_qdiff = avio_r8(pb); - codec->qcompress = avio_rb16(pb) / 10000.0; - codec->qblur = avio_rb16(pb) / 10000.0; - codec->bit_rate_tolerance = avio_rb32(pb); - avio_get_str(pb, INT_MAX, rc_eq_buf, sizeof(rc_eq_buf)); - codec->rc_eq = av_strdup(rc_eq_buf); - codec->rc_max_rate = avio_rb32(pb); - codec->rc_min_rate = avio_rb32(pb); - codec->rc_buffer_size = avio_rb32(pb); - codec->i_quant_factor = av_int2double(avio_rb64(pb)); - codec->b_quant_factor = av_int2double(avio_rb64(pb)); - codec->i_quant_offset = av_int2double(avio_rb64(pb)); - codec->b_quant_offset = av_int2double(avio_rb64(pb)); - codec->dct_algo = avio_rb32(pb); - codec->strict_std_compliance = avio_rb32(pb); - codec->max_b_frames = avio_rb32(pb); - codec->mpeg_quant = avio_rb32(pb); - codec->intra_dc_precision = avio_rb32(pb); - codec->me_method = avio_rb32(pb); - codec->mb_decision = avio_rb32(pb); - codec->nsse_weight = avio_rb32(pb); - codec->frame_skip_cmp = avio_rb32(pb); - codec->rc_buffer_aggressivity = av_int2double(avio_rb64(pb)); - codec->codec_tag = avio_rb32(pb); - codec->thread_count = avio_r8(pb); - codec->coder_type = avio_rb32(pb); - codec->me_cmp = avio_rb32(pb); - codec->me_subpel_quality = avio_rb32(pb); - codec->me_range = avio_rb32(pb); - codec->keyint_min = avio_rb32(pb); - codec->scenechange_threshold = avio_rb32(pb); - codec->b_frame_strategy = avio_rb32(pb); - codec->qcompress = av_int2double(avio_rb64(pb)); - codec->qblur = av_int2double(avio_rb64(pb)); - codec->max_qdiff = avio_rb32(pb); - codec->refs = avio_rb32(pb); - break; - case MKBETAG('S', 'T', 'A', 'U'): - codec->sample_rate = avio_rb32(pb); - codec->channels = avio_rl16(pb); - codec->frame_size = avio_rl16(pb); - break; - } - break; - } - avio_seek(pb, next, SEEK_SET); - } - - /* get until end of block reached */ - while ((avio_tell(pb) % ffm->packet_size) != 0) - avio_r8(pb); - - /* init packet demux */ - ffm->packet_ptr = ffm->packet; - ffm->packet_end = ffm->packet; - ffm->frame_offset = 0; - ffm->dts = 0; - ffm->read_state = READ_HEADER; - ffm->first_packet = 1; - return 0; - fail: - ffm_close(s); - return -1; -} - -static int ffm_read_header(AVFormatContext *s) -{ - FFMContext *ffm = s->priv_data; - AVStream *st; - AVIOContext *pb = s->pb; - AVCodecContext *codec; - int i, nb_streams; - uint32_t tag; - - /* header */ - tag = avio_rl32(pb); - if (tag == MKTAG('F', 'F', 'M', '2')) - return ffm2_read_header(s); - if (tag != MKTAG('F', 'F', 'M', '1')) - goto fail; - ffm->packet_size = avio_rb32(pb); - if (ffm->packet_size != FFM_PACKET_SIZE) - goto fail; - ffm->write_index = avio_rb64(pb); - /* get also filesize */ - if (pb->seekable) { - ffm->file_size = avio_size(pb); - if (ffm->write_index && 0) - adjust_write_index(s); - } else { - ffm->file_size = (UINT64_C(1) << 63) - 1; - } - - nb_streams = avio_rb32(pb); - avio_rb32(pb); /* total bitrate */ - /* read each stream */ - for(i=0;icodec; - /* generic info */ - codec->codec_id = avio_rb32(pb); - codec->codec_type = avio_r8(pb); /* codec_type */ - codec->bit_rate = avio_rb32(pb); - codec->flags = avio_rb32(pb); - codec->flags2 = avio_rb32(pb); - codec->debug = avio_rb32(pb); - /* specific info */ - switch(codec->codec_type) { - case AVMEDIA_TYPE_VIDEO: - codec->time_base.num = avio_rb32(pb); - codec->time_base.den = avio_rb32(pb); - codec->width = avio_rb16(pb); - codec->height = avio_rb16(pb); - codec->gop_size = avio_rb16(pb); - codec->pix_fmt = avio_rb32(pb); - codec->qmin = avio_r8(pb); - codec->qmax = avio_r8(pb); - codec->max_qdiff = avio_r8(pb); - codec->qcompress = avio_rb16(pb) / 10000.0; - codec->qblur = avio_rb16(pb) / 10000.0; - codec->bit_rate_tolerance = avio_rb32(pb); - avio_get_str(pb, INT_MAX, rc_eq_buf, sizeof(rc_eq_buf)); - codec->rc_eq = av_strdup(rc_eq_buf); - codec->rc_max_rate = avio_rb32(pb); - codec->rc_min_rate = avio_rb32(pb); - codec->rc_buffer_size = avio_rb32(pb); - codec->i_quant_factor = av_int2double(avio_rb64(pb)); - codec->b_quant_factor = av_int2double(avio_rb64(pb)); - codec->i_quant_offset = av_int2double(avio_rb64(pb)); - codec->b_quant_offset = av_int2double(avio_rb64(pb)); - codec->dct_algo = avio_rb32(pb); - codec->strict_std_compliance = avio_rb32(pb); - codec->max_b_frames = avio_rb32(pb); - codec->mpeg_quant = avio_rb32(pb); - codec->intra_dc_precision = avio_rb32(pb); - codec->me_method = avio_rb32(pb); - codec->mb_decision = avio_rb32(pb); - codec->nsse_weight = avio_rb32(pb); - codec->frame_skip_cmp = avio_rb32(pb); - codec->rc_buffer_aggressivity = av_int2double(avio_rb64(pb)); - codec->codec_tag = avio_rb32(pb); - codec->thread_count = avio_r8(pb); - codec->coder_type = avio_rb32(pb); - codec->me_cmp = avio_rb32(pb); - codec->me_subpel_quality = avio_rb32(pb); - codec->me_range = avio_rb32(pb); - codec->keyint_min = avio_rb32(pb); - codec->scenechange_threshold = avio_rb32(pb); - codec->b_frame_strategy = avio_rb32(pb); - codec->qcompress = av_int2double(avio_rb64(pb)); - codec->qblur = av_int2double(avio_rb64(pb)); - codec->max_qdiff = avio_rb32(pb); - codec->refs = avio_rb32(pb); - break; - case AVMEDIA_TYPE_AUDIO: - codec->sample_rate = avio_rb32(pb); - codec->channels = avio_rl16(pb); - codec->frame_size = avio_rl16(pb); - break; - default: - goto fail; - } - if (codec->flags & CODEC_FLAG_GLOBAL_HEADER) { - codec->extradata_size = avio_rb32(pb); - codec->extradata = av_malloc(codec->extradata_size); - if (!codec->extradata) - return AVERROR(ENOMEM); - avio_read(pb, codec->extradata, codec->extradata_size); - } - } - - /* get until end of block reached */ - while ((avio_tell(pb) % ffm->packet_size) != 0) - avio_r8(pb); - - /* init packet demux */ - ffm->packet_ptr = ffm->packet; - ffm->packet_end = ffm->packet; - ffm->frame_offset = 0; - ffm->dts = 0; - ffm->read_state = READ_HEADER; - ffm->first_packet = 1; - return 0; - fail: - ffm_close(s); - return -1; -} - -/* return < 0 if eof */ -static int ffm_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - int size; - FFMContext *ffm = s->priv_data; - int duration, ret; - - switch(ffm->read_state) { - case READ_HEADER: - if ((ret = ffm_is_avail_data(s, FRAME_HEADER_SIZE+4)) < 0) - return ret; - - av_dlog(s, "pos=%08"PRIx64" spos=%"PRIx64", write_index=%"PRIx64" size=%"PRIx64"\n", - avio_tell(s->pb), s->pb->pos, ffm->write_index, ffm->file_size); - if (ffm_read_data(s, ffm->header, FRAME_HEADER_SIZE, 1) != - FRAME_HEADER_SIZE) - return -1; - if (ffm->header[1] & FLAG_DTS) - if (ffm_read_data(s, ffm->header+16, 4, 1) != 4) - return -1; - ffm->read_state = READ_DATA; - /* fall thru */ - case READ_DATA: - size = AV_RB24(ffm->header + 2); - if ((ret = ffm_is_avail_data(s, size)) < 0) - return ret; - - duration = AV_RB24(ffm->header + 5); - - if (av_new_packet(pkt, size) < 0) { - return AVERROR(ENOMEM); - } - pkt->stream_index = ffm->header[0]; - if ((unsigned)pkt->stream_index >= s->nb_streams) { - av_log(s, AV_LOG_ERROR, "invalid stream index %d\n", pkt->stream_index); - av_free_packet(pkt); - ffm->read_state = READ_HEADER; - return -1; - } - pkt->pos = avio_tell(s->pb); - if (ffm->header[1] & FLAG_KEY_FRAME) - pkt->flags |= AV_PKT_FLAG_KEY; - - ffm->read_state = READ_HEADER; - if (ffm_read_data(s, pkt->data, size, 0) != size) { - /* bad case: desynchronized packet. we cancel all the packet loading */ - av_free_packet(pkt); - return -1; - } - pkt->pts = AV_RB64(ffm->header+8); - if (ffm->header[1] & FLAG_DTS) - pkt->dts = pkt->pts - AV_RB32(ffm->header+16); - else - pkt->dts = pkt->pts; - pkt->duration = duration; - break; - } - return 0; -} - -/* seek to a given time in the file. The file read pointer is - positioned at or before pts. XXX: the following code is quite - approximative */ -static int ffm_seek(AVFormatContext *s, int stream_index, int64_t wanted_pts, int flags) -{ - FFMContext *ffm = s->priv_data; - int64_t pos_min, pos_max, pos; - int64_t pts_min, pts_max, pts; - double pos1; - - av_dlog(s, "wanted_pts=%0.6f\n", wanted_pts / 1000000.0); - /* find the position using linear interpolation (better than - dichotomy in typical cases) */ - if (ffm->write_index && ffm->write_index < ffm->file_size) { - if (get_dts(s, FFM_PACKET_SIZE) < wanted_pts) { - pos_min = FFM_PACKET_SIZE; - pos_max = ffm->write_index - FFM_PACKET_SIZE; - } else { - pos_min = ffm->write_index; - pos_max = ffm->file_size - FFM_PACKET_SIZE; - } - } else { - pos_min = FFM_PACKET_SIZE; - pos_max = ffm->file_size - FFM_PACKET_SIZE; - } - while (pos_min <= pos_max) { - pts_min = get_dts(s, pos_min); - pts_max = get_dts(s, pos_max); - if (pts_min > wanted_pts || pts_max <= wanted_pts) { - pos = pts_min > wanted_pts ? pos_min : pos_max; - goto found; - } - /* linear interpolation */ - pos1 = (double)(pos_max - pos_min) * (double)(wanted_pts - pts_min) / - (double)(pts_max - pts_min); - pos = (((int64_t)pos1) / FFM_PACKET_SIZE) * FFM_PACKET_SIZE; - if (pos <= pos_min) - pos = pos_min; - else if (pos >= pos_max) - pos = pos_max; - pts = get_dts(s, pos); - /* check if we are lucky */ - if (pts == wanted_pts) { - goto found; - } else if (pts > wanted_pts) { - pos_max = pos - FFM_PACKET_SIZE; - } else { - pos_min = pos + FFM_PACKET_SIZE; - } - } - pos = (flags & AVSEEK_FLAG_BACKWARD) ? pos_min : pos_max; - - found: - if (ffm_seek1(s, pos) < 0) - return -1; - - /* reset read state */ - ffm->read_state = READ_HEADER; - ffm->packet_ptr = ffm->packet; - ffm->packet_end = ffm->packet; - ffm->first_packet = 1; - - return 0; -} - -static int ffm_probe(AVProbeData *p) -{ - if ( - p->buf[0] == 'F' && p->buf[1] == 'F' && p->buf[2] == 'M' && - (p->buf[3] == '1' || p->buf[3] == '2')) - return AVPROBE_SCORE_MAX + 1; - return 0; -} - -AVInputFormat ff_ffm_demuxer = { - .name = "ffm", - .long_name = NULL_IF_CONFIG_SMALL("FFM (FFserver live feed)"), - .priv_data_size = sizeof(FFMContext), - .read_probe = ffm_probe, - .read_header = ffm_read_header, - .read_packet = ffm_read_packet, - .read_close = ffm_close, - .read_seek = ffm_seek, -}; diff --git a/ffmpeg1/libavformat/ffmenc.c b/ffmpeg1/libavformat/ffmenc.c deleted file mode 100644 index 522945e..0000000 --- a/ffmpeg1/libavformat/ffmenc.c +++ /dev/null @@ -1,280 +0,0 @@ -/* - * FFM (ffserver live feed) muxer - * 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 - */ - -#include "libavutil/intreadwrite.h" -#include "libavutil/intfloat.h" -#include "libavutil/avassert.h" -#include "libavutil/parseutils.h" -#include "avformat.h" -#include "internal.h" -#include "ffm.h" - -static void flush_packet(AVFormatContext *s) -{ - FFMContext *ffm = s->priv_data; - int fill_size, h; - AVIOContext *pb = s->pb; - - fill_size = ffm->packet_end - ffm->packet_ptr; - memset(ffm->packet_ptr, 0, fill_size); - - av_assert1(avio_tell(pb) % ffm->packet_size == 0); - - /* put header */ - avio_wb16(pb, PACKET_ID); - avio_wb16(pb, fill_size); - avio_wb64(pb, ffm->dts); - h = ffm->frame_offset; - if (ffm->first_packet) - h |= 0x8000; - avio_wb16(pb, h); - avio_write(pb, ffm->packet, ffm->packet_end - ffm->packet); - avio_flush(pb); - - /* prepare next packet */ - ffm->frame_offset = 0; /* no key frame */ - ffm->packet_ptr = ffm->packet; - ffm->first_packet = 0; -} - -/* 'first' is true if first data of a frame */ -static void ffm_write_data(AVFormatContext *s, - const uint8_t *buf, int size, - int64_t dts, int header) -{ - FFMContext *ffm = s->priv_data; - int len; - - if (header && ffm->frame_offset == 0) { - ffm->frame_offset = ffm->packet_ptr - ffm->packet + FFM_HEADER_SIZE; - ffm->dts = dts; - } - - /* write as many packets as needed */ - while (size > 0) { - len = ffm->packet_end - ffm->packet_ptr; - if (len > size) - len = size; - memcpy(ffm->packet_ptr, buf, len); - - ffm->packet_ptr += len; - buf += len; - size -= len; - if (ffm->packet_ptr >= ffm->packet_end) - flush_packet(s); - } -} - -static void write_header_chunk(AVIOContext *pb, AVIOContext *dpb, unsigned id) -{ - uint8_t *dyn_buf; - int dyn_size= avio_close_dyn_buf(dpb, &dyn_buf); - avio_wb32(pb, id); - avio_wb32(pb, dyn_size); - avio_write(pb, dyn_buf, dyn_size); - av_free(dyn_buf); -} - -static int ffm_write_header(AVFormatContext *s) -{ - FFMContext *ffm = s->priv_data; - AVDictionaryEntry *t; - AVStream *st; - AVIOContext *pb = s->pb; - AVCodecContext *codec; - int bit_rate, i; - - if (t = av_dict_get(s->metadata, "creation_time", NULL, 0)) { - int ret = av_parse_time(&ffm->start_time, t->value, 0); - if (ret < 0) - return ret; - } - - ffm->packet_size = FFM_PACKET_SIZE; - - /* header */ - avio_wl32(pb, MKTAG('F', 'F', 'M', '2')); - avio_wb32(pb, ffm->packet_size); - avio_wb64(pb, 0); /* current write position */ - - if(avio_open_dyn_buf(&pb) < 0) - return AVERROR(ENOMEM); - - avio_wb32(pb, s->nb_streams); - bit_rate = 0; - for(i=0;inb_streams;i++) { - st = s->streams[i]; - bit_rate += st->codec->bit_rate; - } - avio_wb32(pb, bit_rate); - - write_header_chunk(s->pb, pb, MKBETAG('M', 'A', 'I', 'N')); - - /* list of streams */ - for(i=0;inb_streams;i++) { - st = s->streams[i]; - avpriv_set_pts_info(st, 64, 1, 1000000); - if(avio_open_dyn_buf(&pb) < 0) - return AVERROR(ENOMEM); - - codec = st->codec; - /* generic info */ - avio_wb32(pb, codec->codec_id); - avio_w8(pb, codec->codec_type); - avio_wb32(pb, codec->bit_rate); - avio_wb32(pb, codec->flags); - avio_wb32(pb, codec->flags2); - avio_wb32(pb, codec->debug); - if (codec->flags & CODEC_FLAG_GLOBAL_HEADER) { - avio_wb32(pb, codec->extradata_size); - avio_write(pb, codec->extradata, codec->extradata_size); - } - write_header_chunk(s->pb, pb, MKBETAG('C', 'O', 'M', 'M')); - if(avio_open_dyn_buf(&pb) < 0) - return AVERROR(ENOMEM); - /* specific info */ - switch(codec->codec_type) { - case AVMEDIA_TYPE_VIDEO: - avio_wb32(pb, codec->time_base.num); - avio_wb32(pb, codec->time_base.den); - avio_wb16(pb, codec->width); - avio_wb16(pb, codec->height); - avio_wb16(pb, codec->gop_size); - avio_wb32(pb, codec->pix_fmt); - avio_w8(pb, codec->qmin); - avio_w8(pb, codec->qmax); - avio_w8(pb, codec->max_qdiff); - avio_wb16(pb, (int) (codec->qcompress * 10000.0)); - avio_wb16(pb, (int) (codec->qblur * 10000.0)); - avio_wb32(pb, codec->bit_rate_tolerance); - avio_put_str(pb, codec->rc_eq ? codec->rc_eq : "tex^qComp"); - avio_wb32(pb, codec->rc_max_rate); - avio_wb32(pb, codec->rc_min_rate); - avio_wb32(pb, codec->rc_buffer_size); - avio_wb64(pb, av_double2int(codec->i_quant_factor)); - avio_wb64(pb, av_double2int(codec->b_quant_factor)); - avio_wb64(pb, av_double2int(codec->i_quant_offset)); - avio_wb64(pb, av_double2int(codec->b_quant_offset)); - avio_wb32(pb, codec->dct_algo); - avio_wb32(pb, codec->strict_std_compliance); - avio_wb32(pb, codec->max_b_frames); - avio_wb32(pb, codec->mpeg_quant); - avio_wb32(pb, codec->intra_dc_precision); - avio_wb32(pb, codec->me_method); - avio_wb32(pb, codec->mb_decision); - avio_wb32(pb, codec->nsse_weight); - avio_wb32(pb, codec->frame_skip_cmp); - avio_wb64(pb, av_double2int(codec->rc_buffer_aggressivity)); - avio_wb32(pb, codec->codec_tag); - avio_w8(pb, codec->thread_count); - avio_wb32(pb, codec->coder_type); - avio_wb32(pb, codec->me_cmp); - avio_wb32(pb, codec->me_subpel_quality); - avio_wb32(pb, codec->me_range); - avio_wb32(pb, codec->keyint_min); - avio_wb32(pb, codec->scenechange_threshold); - avio_wb32(pb, codec->b_frame_strategy); - avio_wb64(pb, av_double2int(codec->qcompress)); - avio_wb64(pb, av_double2int(codec->qblur)); - avio_wb32(pb, codec->max_qdiff); - avio_wb32(pb, codec->refs); - write_header_chunk(s->pb, pb, MKBETAG('S', 'T', 'V', 'I')); - break; - case AVMEDIA_TYPE_AUDIO: - avio_wb32(pb, codec->sample_rate); - avio_wl16(pb, codec->channels); - avio_wl16(pb, codec->frame_size); - write_header_chunk(s->pb, pb, MKBETAG('S', 'T', 'A', 'U')); - break; - default: - return -1; - } - } - pb = s->pb; - - avio_wb64(pb, 0); // end of header - - /* flush until end of block reached */ - while ((avio_tell(pb) % ffm->packet_size) != 0) - avio_w8(pb, 0); - - avio_flush(pb); - - /* init packet mux */ - ffm->packet_ptr = ffm->packet; - ffm->packet_end = ffm->packet + ffm->packet_size - FFM_HEADER_SIZE; - av_assert0(ffm->packet_end >= ffm->packet); - ffm->frame_offset = 0; - ffm->dts = 0; - ffm->first_packet = 1; - - return 0; -} - -static int ffm_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - FFMContext *ffm = s->priv_data; - int64_t dts; - uint8_t header[FRAME_HEADER_SIZE+4]; - int header_size = FRAME_HEADER_SIZE; - - dts = ffm->start_time + pkt->dts; - /* packet size & key_frame */ - header[0] = pkt->stream_index; - header[1] = 0; - if (pkt->flags & AV_PKT_FLAG_KEY) - header[1] |= FLAG_KEY_FRAME; - AV_WB24(header+2, pkt->size); - AV_WB24(header+5, pkt->duration); - AV_WB64(header+8, ffm->start_time + pkt->pts); - if (pkt->pts != pkt->dts) { - header[1] |= FLAG_DTS; - AV_WB32(header+16, pkt->pts - pkt->dts); - header_size += 4; - } - ffm_write_data(s, header, header_size, dts, 1); - ffm_write_data(s, pkt->data, pkt->size, dts, 0); - - return 0; -} - -static int ffm_write_trailer(AVFormatContext *s) -{ - FFMContext *ffm = s->priv_data; - - /* flush packets */ - if (ffm->packet_ptr > ffm->packet) - flush_packet(s); - - return 0; -} - -AVOutputFormat ff_ffm_muxer = { - .name = "ffm", - .long_name = NULL_IF_CONFIG_SMALL("FFM (FFserver live feed)"), - .extensions = "ffm", - .priv_data_size = sizeof(FFMContext), - .audio_codec = AV_CODEC_ID_MP2, - .video_codec = AV_CODEC_ID_MPEG1VIDEO, - .write_header = ffm_write_header, - .write_packet = ffm_write_packet, - .write_trailer = ffm_write_trailer, -}; diff --git a/ffmpeg1/libavformat/ffmeta.h b/ffmpeg1/libavformat/ffmeta.h deleted file mode 100644 index ae8778d..0000000 --- a/ffmpeg1/libavformat/ffmeta.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Common data for metadata muxer/demuxer - * Copyright (c) 2010 Anton Khirnov - * - * 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 AVFORMAT_FFMETA_H -#define AVFORMAT_FFMETA_H - -#define ID_STRING ";FFMETADATA" -#define ID_CHAPTER "[CHAPTER]" -#define ID_STREAM "[STREAM]" - -#endif /* AVFORMAT_FFMETA_H */ diff --git a/ffmpeg1/libavformat/ffmetadec.c b/ffmpeg1/libavformat/ffmetadec.c deleted file mode 100644 index 4bdc98a..0000000 --- a/ffmpeg1/libavformat/ffmetadec.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Metadata demuxer - * Copyright (c) 2010 Anton Khirnov - * - * 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 "libavutil/mathematics.h" -#include "avformat.h" -#include "ffmeta.h" -#include "internal.h" -#include "libavutil/dict.h" - -static int probe(AVProbeData *p) -{ - if(!memcmp(p->buf, ID_STRING, strlen(ID_STRING))) - return AVPROBE_SCORE_MAX; - return 0; -} - -static void get_line(AVIOContext *s, uint8_t *buf, int size) -{ - do { - uint8_t c; - int i = 0; - - while ((c = avio_r8(s))) { - if (c == '\\') { - if (i < size - 1) - buf[i++] = c; - c = avio_r8(s); - } else if (c == '\n') - break; - - if (i < size - 1) - buf[i++] = c; - } - buf[i] = 0; - } while (!url_feof(s) && (buf[0] == ';' || buf[0] == '#' || buf[0] == 0)); -} - -static AVChapter *read_chapter(AVFormatContext *s) -{ - uint8_t line[256]; - int64_t start, end; - AVRational tb = {1, 1e9}; - - get_line(s->pb, line, sizeof(line)); - - if (sscanf(line, "TIMEBASE=%d/%d", &tb.num, &tb.den)) - get_line(s->pb, line, sizeof(line)); - if (!sscanf(line, "START=%"SCNd64, &start)) { - av_log(s, AV_LOG_ERROR, "Expected chapter start timestamp, found %s.\n", line); - start = (s->nb_chapters && s->chapters[s->nb_chapters - 1]->end != AV_NOPTS_VALUE) ? - s->chapters[s->nb_chapters - 1]->end : 0; - } else - get_line(s->pb, line, sizeof(line)); - - if (!sscanf(line, "END=%"SCNd64, &end)) { - av_log(s, AV_LOG_ERROR, "Expected chapter end timestamp, found %s.\n", line); - end = AV_NOPTS_VALUE; - } - - return avpriv_new_chapter(s, s->nb_chapters, tb, start, end, NULL); -} - -static uint8_t *unescape(uint8_t *buf, int size) -{ - uint8_t *ret = av_malloc(size + 1); - uint8_t *p1 = ret, *p2 = buf; - - if (!ret) - return NULL; - - while (p2 < buf + size) { - if (*p2 == '\\') - p2++; - *p1++ = *p2++; - } - *p1 = 0; - return ret; -} - -static int read_tag(uint8_t *line, AVDictionary **m) -{ - uint8_t *key, *value, *p = line; - - /* find first not escaped '=' */ - while (1) { - if (*p == '=') - break; - else if (*p == '\\') - p++; - - if (*p++) - continue; - - return 0; - } - - if (!(key = unescape(line, p - line))) - return AVERROR(ENOMEM); - if (!(value = unescape(p + 1, strlen(p + 1)))) { - av_free(key); - return AVERROR(ENOMEM); - } - - av_dict_set(m, key, value, AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL); - return 0; -} - -static int read_header(AVFormatContext *s) -{ - AVDictionary **m = &s->metadata; - uint8_t line[1024]; - - while(!url_feof(s->pb)) { - get_line(s->pb, line, sizeof(line)); - - if (!memcmp(line, ID_STREAM, strlen(ID_STREAM))) { - AVStream *st = avformat_new_stream(s, NULL); - - if (!st) - return -1; - - st->codec->codec_type = AVMEDIA_TYPE_DATA; - st->codec->codec_id = AV_CODEC_ID_FFMETADATA; - - m = &st->metadata; - } else if (!memcmp(line, ID_CHAPTER, strlen(ID_CHAPTER))) { - AVChapter *ch = read_chapter(s); - - if (!ch) - return -1; - - m = &ch->metadata; - } else - read_tag(line, m); - } - - s->start_time = 0; - if (s->nb_chapters) - s->duration = av_rescale_q(s->chapters[s->nb_chapters - 1]->end, - s->chapters[s->nb_chapters - 1]->time_base, - AV_TIME_BASE_Q); - - return 0; -} - -static int read_packet(AVFormatContext *s, AVPacket *pkt) -{ - return AVERROR_EOF; -} - -AVInputFormat ff_ffmetadata_demuxer = { - .name = "ffmetadata", - .long_name = NULL_IF_CONFIG_SMALL("FFmpeg metadata in text"), - .read_probe = probe, - .read_header = read_header, - .read_packet = read_packet, -}; diff --git a/ffmpeg1/libavformat/ffmetaenc.c b/ffmpeg1/libavformat/ffmetaenc.c deleted file mode 100644 index a9adbb1..0000000 --- a/ffmpeg1/libavformat/ffmetaenc.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Metadata muxer - * Copyright (c) 2010 Anton Khirnov - * - * 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 - -#include "avformat.h" -#include "ffmeta.h" -#include "libavutil/dict.h" - - -static void write_escape_str(AVIOContext *s, const uint8_t *str) -{ - const uint8_t *p = str; - - while (*p) { - if (*p == '#' || *p == ';' || *p == '=' || *p == '\\' || *p == '\n') - avio_w8(s, '\\'); - avio_w8(s, *p); - p++; - } -} - -static void write_tags(AVIOContext *s, AVDictionary *m) -{ - AVDictionaryEntry *t = NULL; - while ((t = av_dict_get(m, "", t, AV_DICT_IGNORE_SUFFIX))) { - write_escape_str(s, t->key); - avio_w8(s, '='); - write_escape_str(s, t->value); - avio_w8(s, '\n'); - } -} - -static int write_header(AVFormatContext *s) -{ - avio_write(s->pb, ID_STRING, sizeof(ID_STRING) - 1); - avio_w8(s->pb, '1'); // version - avio_w8(s->pb, '\n'); - avio_flush(s->pb); - return 0; -} - -static int write_trailer(AVFormatContext *s) -{ - int i; - - write_tags(s->pb, s->metadata); - - for (i = 0; i < s->nb_streams; i++) { - avio_write(s->pb, ID_STREAM, sizeof(ID_STREAM) - 1); - avio_w8(s->pb, '\n'); - write_tags(s->pb, s->streams[i]->metadata); - } - - for (i = 0; i < s->nb_chapters; i++) { - AVChapter *ch = s->chapters[i]; - avio_write(s->pb, ID_CHAPTER, sizeof(ID_CHAPTER) - 1); - avio_w8(s->pb, '\n'); - avio_printf(s->pb, "TIMEBASE=%d/%d\n", ch->time_base.num, ch->time_base.den); - avio_printf(s->pb, "START=%"PRId64"\n", ch->start); - avio_printf(s->pb, "END=%"PRId64"\n", ch->end); - write_tags(s->pb, ch->metadata); - } - - return 0; -} - -static int write_packet(AVFormatContext *s, AVPacket *pkt) -{ - return 0; -} - -AVOutputFormat ff_ffmetadata_muxer = { - .name = "ffmetadata", - .long_name = NULL_IF_CONFIG_SMALL("FFmpeg metadata in text"), - .extensions = "ffmeta", - .write_header = write_header, - .write_packet = write_packet, - .write_trailer = write_trailer, - .flags = AVFMT_NOTIMESTAMPS | AVFMT_NOSTREAMS, -}; diff --git a/ffmpeg1/libavformat/file.c b/ffmpeg1/libavformat/file.c deleted file mode 100644 index e09a64b..0000000 --- a/ffmpeg1/libavformat/file.c +++ /dev/null @@ -1,218 +0,0 @@ -/* - * buffered file I/O - * 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 - */ - -#include "libavutil/avstring.h" -#include "libavutil/opt.h" -#include "avformat.h" -#include -#if HAVE_IO_H -#include -#endif -#if HAVE_UNISTD_H -#include -#endif -#include -#include -#include "os_support.h" -#include "url.h" - -/* Some systems may not have S_ISFIFO */ -#ifndef S_ISFIFO -# ifdef S_IFIFO -# define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO) -# else -# define S_ISFIFO(m) 0 -# endif -#endif - -/* standard file protocol */ - -typedef struct FileContext { - const AVClass *class; - int fd; - int trunc; -} FileContext; - -static const AVOption file_options[] = { - { "truncate", "Truncate existing files on write", offsetof(FileContext, trunc), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, AV_OPT_FLAG_ENCODING_PARAM }, - { NULL } -}; - -static const AVClass file_class = { - .class_name = "file", - .item_name = av_default_item_name, - .option = file_options, - .version = LIBAVUTIL_VERSION_INT, -}; - -static int file_read(URLContext *h, unsigned char *buf, int size) -{ - FileContext *c = h->priv_data; - int r = read(c->fd, buf, size); - return (-1 == r)?AVERROR(errno):r; -} - -static int file_write(URLContext *h, const unsigned char *buf, int size) -{ - FileContext *c = h->priv_data; - int r = write(c->fd, buf, size); - return (-1 == r)?AVERROR(errno):r; -} - -static int file_get_handle(URLContext *h) -{ - FileContext *c = h->priv_data; - return c->fd; -} - -static int file_check(URLContext *h, int mask) -{ -#if HAVE_ACCESS && defined(R_OK) - int ret = 0; - if (access(h->filename, F_OK) < 0) - return AVERROR(errno); - if (mask&AVIO_FLAG_READ) - if (access(h->filename, R_OK) >= 0) - ret |= AVIO_FLAG_READ; - if (mask&AVIO_FLAG_WRITE) - if (access(h->filename, W_OK) >= 0) - ret |= AVIO_FLAG_WRITE; -#else - struct stat st; - int ret = stat(h->filename, &st); - if (ret < 0) - return AVERROR(errno); - - ret |= st.st_mode&S_IRUSR ? mask&AVIO_FLAG_READ : 0; - ret |= st.st_mode&S_IWUSR ? mask&AVIO_FLAG_WRITE : 0; -#endif - return ret; -} - -#if CONFIG_FILE_PROTOCOL - -static int file_open(URLContext *h, const char *filename, int flags) -{ - FileContext *c = h->priv_data; - int access; - int fd; - struct stat st; - - av_strstart(filename, "file:", &filename); - - if (flags & AVIO_FLAG_WRITE && flags & AVIO_FLAG_READ) { - access = O_CREAT | O_RDWR; - if (c->trunc) - access |= O_TRUNC; - } else if (flags & AVIO_FLAG_WRITE) { - access = O_CREAT | O_WRONLY; - if (c->trunc) - access |= O_TRUNC; - } else { - access = O_RDONLY; - } -#ifdef O_BINARY - access |= O_BINARY; -#endif - fd = open(filename, access, 0666); - if (fd == -1) - return AVERROR(errno); - c->fd = fd; - - h->is_streamed = !fstat(fd, &st) && S_ISFIFO(st.st_mode); - - return 0; -} - -/* XXX: use llseek */ -static int64_t file_seek(URLContext *h, int64_t pos, int whence) -{ - FileContext *c = h->priv_data; - int64_t ret; - - if (whence == AVSEEK_SIZE) { - struct stat st; - ret = fstat(c->fd, &st); - return ret < 0 ? AVERROR(errno) : (S_ISFIFO(st.st_mode) ? 0 : st.st_size); - } - - ret = lseek(c->fd, pos, whence); - - return ret < 0 ? AVERROR(errno) : ret; -} - -static int file_close(URLContext *h) -{ - FileContext *c = h->priv_data; - return close(c->fd); -} - -URLProtocol ff_file_protocol = { - .name = "file", - .url_open = file_open, - .url_read = file_read, - .url_write = file_write, - .url_seek = file_seek, - .url_close = file_close, - .url_get_file_handle = file_get_handle, - .url_check = file_check, - .priv_data_size = sizeof(FileContext), - .priv_data_class = &file_class, -}; - -#endif /* CONFIG_FILE_PROTOCOL */ - -#if CONFIG_PIPE_PROTOCOL - -static int pipe_open(URLContext *h, const char *filename, int flags) -{ - FileContext *c = h->priv_data; - int fd; - char *final; - av_strstart(filename, "pipe:", &filename); - - fd = strtol(filename, &final, 10); - if((filename == final) || *final ) {/* No digits found, or something like 10ab */ - if (flags & AVIO_FLAG_WRITE) { - fd = 1; - } else { - fd = 0; - } - } -#if HAVE_SETMODE - setmode(fd, O_BINARY); -#endif - c->fd = fd; - h->is_streamed = 1; - return 0; -} - -URLProtocol ff_pipe_protocol = { - .name = "pipe", - .url_open = pipe_open, - .url_read = file_read, - .url_write = file_write, - .url_get_file_handle = file_get_handle, - .url_check = file_check, - .priv_data_size = sizeof(FileContext), -}; - -#endif /* CONFIG_PIPE_PROTOCOL */ diff --git a/ffmpeg1/libavformat/filmstripdec.c b/ffmpeg1/libavformat/filmstripdec.c deleted file mode 100644 index 1cd1a48..0000000 --- a/ffmpeg1/libavformat/filmstripdec.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Adobe Filmstrip demuxer - * Copyright (c) 2010 Peter Ross - * - * 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 - */ - -/** - * @file - * Adobe Filmstrip demuxer - */ - -#include "libavutil/intreadwrite.h" -#include "avformat.h" -#include "internal.h" - -#define RAND_TAG MKBETAG('R','a','n','d') - -typedef struct { - int leading; -} FilmstripDemuxContext; - -static int read_header(AVFormatContext *s) -{ - FilmstripDemuxContext *film = s->priv_data; - AVIOContext *pb = s->pb; - AVStream *st; - - if (!s->pb->seekable) - return AVERROR(EIO); - - avio_seek(pb, avio_size(pb) - 36, SEEK_SET); - if (avio_rb32(pb) != RAND_TAG) { - av_log(s, AV_LOG_ERROR, "magic number not found\n"); - return AVERROR_INVALIDDATA; - } - - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - - st->nb_frames = avio_rb32(pb); - if (avio_rb16(pb) != 0) { - avpriv_request_sample(s, "Unsupported packing method"); - return AVERROR_PATCHWELCOME; - } - - avio_skip(pb, 2); - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = AV_CODEC_ID_RAWVIDEO; - st->codec->pix_fmt = AV_PIX_FMT_RGBA; - st->codec->codec_tag = 0; /* no fourcc */ - st->codec->width = avio_rb16(pb); - st->codec->height = avio_rb16(pb); - film->leading = avio_rb16(pb); - avpriv_set_pts_info(st, 64, 1, avio_rb16(pb)); - - avio_seek(pb, 0, SEEK_SET); - - return 0; -} - -static int read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - FilmstripDemuxContext *film = s->priv_data; - AVStream *st = s->streams[0]; - - if (url_feof(s->pb)) - return AVERROR(EIO); - pkt->dts = avio_tell(s->pb) / (st->codec->width * (st->codec->height + film->leading) * 4); - pkt->size = av_get_packet(s->pb, pkt, st->codec->width * st->codec->height * 4); - avio_skip(s->pb, st->codec->width * film->leading * 4); - if (pkt->size < 0) - return pkt->size; - pkt->flags |= AV_PKT_FLAG_KEY; - return 0; -} - -static int read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) -{ - AVStream *st = s->streams[stream_index]; - if (avio_seek(s->pb, FFMAX(timestamp, 0) * st->codec->width * st->codec->height * 4, SEEK_SET) < 0) - return -1; - return 0; -} - -AVInputFormat ff_filmstrip_demuxer = { - .name = "filmstrip", - .long_name = NULL_IF_CONFIG_SMALL("Adobe Filmstrip"), - .priv_data_size = sizeof(FilmstripDemuxContext), - .read_header = read_header, - .read_packet = read_packet, - .read_seek = read_seek, - .extensions = "flm", -}; diff --git a/ffmpeg1/libavformat/filmstripenc.c b/ffmpeg1/libavformat/filmstripenc.c deleted file mode 100644 index 85d49be..0000000 --- a/ffmpeg1/libavformat/filmstripenc.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Adobe Filmstrip muxer - * Copyright (c) 2010 Peter Ross - * - * 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 - */ - -/** - * @file - * Adobe Filmstrip muxer - */ - -#include "libavutil/intreadwrite.h" -#include "avformat.h" - -#define RAND_TAG MKBETAG('R','a','n','d') - -typedef struct { - int nb_frames; -} FilmstripMuxContext; - -static int write_header(AVFormatContext *s) -{ - if (s->streams[0]->codec->pix_fmt != AV_PIX_FMT_RGBA) { - av_log(s, AV_LOG_ERROR, "only AV_PIX_FMT_RGBA is supported\n"); - return AVERROR_INVALIDDATA; - } - return 0; -} - -static int write_packet(AVFormatContext *s, AVPacket *pkt) -{ - FilmstripMuxContext *film = s->priv_data; - avio_write(s->pb, pkt->data, pkt->size); - film->nb_frames++; - return 0; -} - -static int write_trailer(AVFormatContext *s) -{ - FilmstripMuxContext *film = s->priv_data; - AVIOContext *pb = s->pb; - AVStream *st = s->streams[0]; - int i; - - avio_wb32(pb, RAND_TAG); - avio_wb32(pb, film->nb_frames); - avio_wb16(pb, 0); // packing method - avio_wb16(pb, 0); // reserved - avio_wb16(pb, st->codec->width); - avio_wb16(pb, st->codec->height); - avio_wb16(pb, 0); // leading - avio_wb16(pb, st->codec->time_base.den / st->codec->time_base.num); - for (i = 0; i < 16; i++) - avio_w8(pb, 0x00); // reserved - - return 0; -} - -AVOutputFormat ff_filmstrip_muxer = { - .name = "filmstrip", - .long_name = NULL_IF_CONFIG_SMALL("Adobe Filmstrip"), - .extensions = "flm", - .priv_data_size = sizeof(FilmstripMuxContext), - .audio_codec = AV_CODEC_ID_NONE, - .video_codec = AV_CODEC_ID_RAWVIDEO, - .write_header = write_header, - .write_packet = write_packet, - .write_trailer = write_trailer, -}; diff --git a/ffmpeg1/libavformat/flacdec.c b/ffmpeg1/libavformat/flacdec.c deleted file mode 100644 index d5aacfd..0000000 --- a/ffmpeg1/libavformat/flacdec.c +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Raw FLAC demuxer - * 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 - */ - -#include "libavcodec/flac.h" -#include "avformat.h" -#include "id3v2.h" -#include "internal.h" -#include "rawdec.h" -#include "oggdec.h" -#include "vorbiscomment.h" -#include "libavcodec/bytestream.h" - -#define RETURN_ERROR(code) do { ret = (code); goto fail; } while (0) - -static int parse_picture(AVFormatContext *s, uint8_t *buf, int buf_size) -{ - const CodecMime *mime = ff_id3v2_mime_tags; - enum AVCodecID id = AV_CODEC_ID_NONE; - AVBufferRef *data = NULL; - uint8_t mimetype[64], *desc = NULL; - AVIOContext *pb = NULL; - AVStream *st; - int type, width, height; - int len, ret = 0; - - pb = avio_alloc_context(buf, buf_size, 0, NULL, NULL, NULL, NULL); - if (!pb) - return AVERROR(ENOMEM); - - /* read the picture type */ - type = avio_rb32(pb); - if (type >= FF_ARRAY_ELEMS(ff_id3v2_picture_types) || type < 0) { - av_log(s, AV_LOG_ERROR, "Invalid picture type: %d.\n", type); - if (s->error_recognition & AV_EF_EXPLODE) { - RETURN_ERROR(AVERROR_INVALIDDATA); - } - type = 0; - } - - /* picture mimetype */ - len = avio_rb32(pb); - if (len <= 0 || - avio_read(pb, mimetype, FFMIN(len, sizeof(mimetype) - 1)) != len) { - av_log(s, AV_LOG_ERROR, "Could not read mimetype from an attached " - "picture.\n"); - if (s->error_recognition & AV_EF_EXPLODE) - ret = AVERROR_INVALIDDATA; - goto fail; - } - mimetype[len] = 0; - - while (mime->id != AV_CODEC_ID_NONE) { - if (!strncmp(mime->str, mimetype, sizeof(mimetype))) { - id = mime->id; - break; - } - mime++; - } - if (id == AV_CODEC_ID_NONE) { - av_log(s, AV_LOG_ERROR, "Unknown attached picture mimetype: %s.\n", - mimetype); - if (s->error_recognition & AV_EF_EXPLODE) - ret = AVERROR_INVALIDDATA; - goto fail; - } - - /* picture description */ - len = avio_rb32(pb); - if (len > 0) { - if (!(desc = av_malloc(len + 1))) { - RETURN_ERROR(AVERROR(ENOMEM)); - } - - if (avio_read(pb, desc, len) != len) { - av_log(s, AV_LOG_ERROR, "Error reading attached picture description.\n"); - if (s->error_recognition & AV_EF_EXPLODE) - ret = AVERROR(EIO); - goto fail; - } - desc[len] = 0; - } - - /* picture metadata */ - width = avio_rb32(pb); - height = avio_rb32(pb); - avio_skip(pb, 8); - - /* picture data */ - len = avio_rb32(pb); - if (len <= 0) { - av_log(s, AV_LOG_ERROR, "Invalid attached picture size: %d.\n", len); - if (s->error_recognition & AV_EF_EXPLODE) - ret = AVERROR_INVALIDDATA; - goto fail; - } - if (!(data = av_buffer_alloc(len))) { - RETURN_ERROR(AVERROR(ENOMEM)); - } - if (avio_read(pb, data->data, len) != len) { - av_log(s, AV_LOG_ERROR, "Error reading attached picture data.\n"); - if (s->error_recognition & AV_EF_EXPLODE) - ret = AVERROR(EIO); - goto fail; - } - - st = avformat_new_stream(s, NULL); - if (!st) { - RETURN_ERROR(AVERROR(ENOMEM)); - } - - av_init_packet(&st->attached_pic); - st->attached_pic.buf = data; - st->attached_pic.data = data->data; - st->attached_pic.size = len; - st->attached_pic.stream_index = st->index; - st->attached_pic.flags |= AV_PKT_FLAG_KEY; - - st->disposition |= AV_DISPOSITION_ATTACHED_PIC; - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = id; - st->codec->width = width; - st->codec->height = height; - av_dict_set(&st->metadata, "comment", ff_id3v2_picture_types[type], 0); - if (desc) - av_dict_set(&st->metadata, "title", desc, AV_DICT_DONT_STRDUP_VAL); - - av_freep(&pb); - - return 0; - -fail: - av_buffer_unref(&data); - av_freep(&desc); - av_freep(&pb); - return ret; - -} - -static int flac_read_header(AVFormatContext *s) -{ - int ret, metadata_last=0, metadata_type, metadata_size, found_streaminfo=0; - uint8_t header[4]; - uint8_t *buffer=NULL; - AVStream *st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = AV_CODEC_ID_FLAC; - st->need_parsing = AVSTREAM_PARSE_FULL_RAW; - /* the parameters will be extracted from the compressed bitstream */ - - /* if fLaC marker is not found, assume there is no header */ - if (avio_rl32(s->pb) != MKTAG('f','L','a','C')) { - avio_seek(s->pb, -4, SEEK_CUR); - return 0; - } - - /* process metadata blocks */ - while (!url_feof(s->pb) && !metadata_last) { - avio_read(s->pb, header, 4); - avpriv_flac_parse_block_header(header, &metadata_last, &metadata_type, - &metadata_size); - switch (metadata_type) { - /* allocate and read metadata block for supported types */ - case FLAC_METADATA_TYPE_STREAMINFO: - case FLAC_METADATA_TYPE_CUESHEET: - case FLAC_METADATA_TYPE_PICTURE: - case FLAC_METADATA_TYPE_VORBIS_COMMENT: - buffer = av_mallocz(metadata_size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!buffer) { - return AVERROR(ENOMEM); - } - if (avio_read(s->pb, buffer, metadata_size) != metadata_size) { - RETURN_ERROR(AVERROR(EIO)); - } - break; - /* skip metadata block for unsupported types */ - default: - ret = avio_skip(s->pb, metadata_size); - if (ret < 0) - return ret; - } - - if (metadata_type == FLAC_METADATA_TYPE_STREAMINFO) { - FLACStreaminfo si; - /* STREAMINFO can only occur once */ - if (found_streaminfo) { - RETURN_ERROR(AVERROR_INVALIDDATA); - } - if (metadata_size != FLAC_STREAMINFO_SIZE) { - RETURN_ERROR(AVERROR_INVALIDDATA); - } - found_streaminfo = 1; - st->codec->extradata = buffer; - st->codec->extradata_size = metadata_size; - buffer = NULL; - - /* get codec params from STREAMINFO header */ - avpriv_flac_parse_streaminfo(st->codec, &si, st->codec->extradata); - - /* set time base and duration */ - if (si.samplerate > 0) { - avpriv_set_pts_info(st, 64, 1, si.samplerate); - if (si.samples > 0) - st->duration = si.samples; - } - } else if (metadata_type == FLAC_METADATA_TYPE_CUESHEET) { - uint8_t isrc[13]; - uint64_t start; - const uint8_t *offset; - int i, chapters, track, ti; - if (metadata_size < 431) - RETURN_ERROR(AVERROR_INVALIDDATA); - offset = buffer + 395; - chapters = bytestream_get_byte(&offset) - 1; - if (chapters <= 0) - RETURN_ERROR(AVERROR_INVALIDDATA); - for (i = 0; i < chapters; i++) { - if (offset + 36 - buffer > metadata_size) - RETURN_ERROR(AVERROR_INVALIDDATA); - start = bytestream_get_be64(&offset); - track = bytestream_get_byte(&offset); - bytestream_get_buffer(&offset, isrc, 12); - isrc[12] = 0; - offset += 14; - ti = bytestream_get_byte(&offset); - if (ti <= 0) RETURN_ERROR(AVERROR_INVALIDDATA); - offset += ti * 12; - avpriv_new_chapter(s, track, st->time_base, start, AV_NOPTS_VALUE, isrc); - } - av_freep(&buffer); - } else if (metadata_type == FLAC_METADATA_TYPE_PICTURE) { - ret = parse_picture(s, buffer, metadata_size); - av_freep(&buffer); - if (ret < 0) { - av_log(s, AV_LOG_ERROR, "Error parsing attached picture.\n"); - return ret; - } - } else { - /* STREAMINFO must be the first block */ - if (!found_streaminfo) { - RETURN_ERROR(AVERROR_INVALIDDATA); - } - /* process supported blocks other than STREAMINFO */ - if (metadata_type == FLAC_METADATA_TYPE_VORBIS_COMMENT) { - if (ff_vorbis_comment(s, &s->metadata, buffer, metadata_size)) { - av_log(s, AV_LOG_WARNING, "error parsing VorbisComment metadata\n"); - } - } - av_freep(&buffer); - } - } - - return 0; - -fail: - av_free(buffer); - return ret; -} - -static int flac_probe(AVProbeData *p) -{ - if (p->buf_size < 4 || memcmp(p->buf, "fLaC", 4)) - return 0; - return AVPROBE_SCORE_MAX/2; -} - -AVInputFormat ff_flac_demuxer = { - .name = "flac", - .long_name = NULL_IF_CONFIG_SMALL("raw FLAC"), - .read_probe = flac_probe, - .read_header = flac_read_header, - .read_packet = ff_raw_read_partial_packet, - .flags = AVFMT_GENERIC_INDEX, - .extensions = "flac", - .raw_codec_id = AV_CODEC_ID_FLAC, -}; diff --git a/ffmpeg1/libavformat/flacenc.c b/ffmpeg1/libavformat/flacenc.c deleted file mode 100644 index b625278..0000000 --- a/ffmpeg1/libavformat/flacenc.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * raw FLAC muxer - * Copyright (c) 2006-2009 Justin Ruggles - * - * 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 "libavcodec/flac.h" -#include "avformat.h" -#include "flacenc.h" -#include "vorbiscomment.h" -#include "libavcodec/bytestream.h" - - -static int flac_write_block_padding(AVIOContext *pb, unsigned int n_padding_bytes, - int last_block) -{ - avio_w8(pb, last_block ? 0x81 : 0x01); - avio_wb24(pb, n_padding_bytes); - while (n_padding_bytes > 0) { - avio_w8(pb, 0); - n_padding_bytes--; - } - return 0; -} - -static int flac_write_block_comment(AVIOContext *pb, AVDictionary **m, - int last_block, int bitexact) -{ - const char *vendor = bitexact ? "ffmpeg" : LIBAVFORMAT_IDENT; - unsigned int len, count; - uint8_t *p, *p0; - - ff_metadata_conv(m, ff_vorbiscomment_metadata_conv, NULL); - - len = ff_vorbiscomment_length(*m, vendor, &count); - p0 = av_malloc(len+4); - if (!p0) - return AVERROR(ENOMEM); - p = p0; - - bytestream_put_byte(&p, last_block ? 0x84 : 0x04); - bytestream_put_be24(&p, len); - ff_vorbiscomment_write(&p, m, vendor, count); - - avio_write(pb, p0, len+4); - av_freep(&p0); - p = NULL; - - return 0; -} - -static int flac_write_header(struct AVFormatContext *s) -{ - int ret; - AVCodecContext *codec = s->streams[0]->codec; - - if (s->nb_streams > 1) { - av_log(s, AV_LOG_ERROR, "only one stream is supported\n"); - return AVERROR(EINVAL); - } - if (codec->codec_id != AV_CODEC_ID_FLAC) { - av_log(s, AV_LOG_ERROR, "unsupported codec\n"); - return AVERROR(EINVAL); - } - - ret = ff_flac_write_header(s->pb, codec, 0); - if (ret) - return ret; - - ret = flac_write_block_comment(s->pb, &s->metadata, 0, - codec->flags & CODEC_FLAG_BITEXACT); - if (ret) - return ret; - - /* The command line flac encoder defaults to placing a seekpoint - * every 10s. So one might add padding to allow that later - * but there seems to be no simple way to get the duration here. - * So let's try the flac default of 8192 bytes */ - flac_write_block_padding(s->pb, 8192, 1); - - return ret; -} - -static int flac_write_trailer(struct AVFormatContext *s) -{ - AVIOContext *pb = s->pb; - uint8_t *streaminfo; - enum FLACExtradataFormat format; - int64_t file_size; - - if (!avpriv_flac_is_extradata_valid(s->streams[0]->codec, &format, &streaminfo)) - return -1; - - if (pb->seekable) { - /* rewrite the STREAMINFO header block data */ - file_size = avio_tell(pb); - avio_seek(pb, 8, SEEK_SET); - avio_write(pb, streaminfo, FLAC_STREAMINFO_SIZE); - avio_seek(pb, file_size, SEEK_SET); - avio_flush(pb); - } else { - av_log(s, AV_LOG_WARNING, "unable to rewrite FLAC header.\n"); - } - return 0; -} - -static int flac_write_packet(struct AVFormatContext *s, AVPacket *pkt) -{ - avio_write(s->pb, pkt->data, pkt->size); - avio_flush(s->pb); - return 0; -} - -AVOutputFormat ff_flac_muxer = { - .name = "flac", - .long_name = NULL_IF_CONFIG_SMALL("raw FLAC"), - .mime_type = "audio/x-flac", - .extensions = "flac", - .audio_codec = AV_CODEC_ID_FLAC, - .video_codec = AV_CODEC_ID_NONE, - .write_header = flac_write_header, - .write_packet = flac_write_packet, - .write_trailer = flac_write_trailer, - .flags = AVFMT_NOTIMESTAMPS, -}; diff --git a/ffmpeg1/libavformat/flacenc.h b/ffmpeg1/libavformat/flacenc.h deleted file mode 100644 index e83ee32..0000000 --- a/ffmpeg1/libavformat/flacenc.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * raw FLAC muxer - * Copyright (C) 2009 Justin Ruggles - * - * 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 AVFORMAT_FLACENC_H -#define AVFORMAT_FLACENC_H - -#include "libavcodec/flac.h" -#include "libavcodec/bytestream.h" -#include "avformat.h" - -int ff_flac_write_header(AVIOContext *pb, AVCodecContext *codec, - int last_block); - -#endif /* AVFORMAT_FLACENC_H */ diff --git a/ffmpeg1/libavformat/flacenc_header.c b/ffmpeg1/libavformat/flacenc_header.c deleted file mode 100644 index e16c14b..0000000 --- a/ffmpeg1/libavformat/flacenc_header.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * raw FLAC muxer - * Copyright (C) 2009 Justin Ruggles - * - * 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 "libavcodec/flac.h" -#include "libavcodec/bytestream.h" -#include "avformat.h" -#include "flacenc.h" - -int ff_flac_write_header(AVIOContext *pb, AVCodecContext *codec, - int last_block) -{ - uint8_t header[8] = { - 0x66, 0x4C, 0x61, 0x43, 0x00, 0x00, 0x00, 0x22 - }; - uint8_t *streaminfo; - enum FLACExtradataFormat format; - - header[4] = last_block ? 0x80 : 0x00; - if (!avpriv_flac_is_extradata_valid(codec, &format, &streaminfo)) - return -1; - - /* write "fLaC" stream marker and first metadata block header */ - avio_write(pb, header, 8); - - /* write STREAMINFO */ - avio_write(pb, streaminfo, FLAC_STREAMINFO_SIZE); - - return 0; -} diff --git a/ffmpeg1/libavformat/flic.c b/ffmpeg1/libavformat/flic.c deleted file mode 100644 index 8d49116..0000000 --- a/ffmpeg1/libavformat/flic.c +++ /dev/null @@ -1,269 +0,0 @@ -/* - * FLI/FLC Animation File Demuxer - * Copyright (c) 2003 The ffmpeg Project - * - * 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 - */ - -/** - * @file - * FLI/FLC file demuxer - * by Mike Melanson (melanson@pcisys.net) - * for more information on the .fli/.flc file format and all of its many - * variations, visit: - * http://www.compuphase.com/flic.htm - * - * This demuxer handles standard 0xAF11- and 0xAF12-type FLIs. It also handles - * special FLIs from the PC games "Magic Carpet" and "X-COM: Terror from the Deep". - */ - -#include "libavutil/channel_layout.h" -#include "libavutil/intreadwrite.h" -#include "avformat.h" -#include "internal.h" - -#define FLIC_FILE_MAGIC_1 0xAF11 -#define FLIC_FILE_MAGIC_2 0xAF12 -#define FLIC_FILE_MAGIC_3 0xAF44 /* Flic Type for Extended FLX Format which - originated in Dave's Targa Animator (DTA) */ -#define FLIC_CHUNK_MAGIC_1 0xF1FA -#define FLIC_CHUNK_MAGIC_2 0xF5FA -#define FLIC_MC_SPEED 5 /* speed for Magic Carpet game FLIs */ -#define FLIC_DEFAULT_SPEED 5 /* for FLIs that have 0 speed */ -#define FLIC_TFTD_CHUNK_AUDIO 0xAAAA /* Audio chunk. Used in Terror from the Deep. - Has 10 B extra header not accounted for in the chunk header */ -#define FLIC_TFTD_SAMPLE_RATE 22050 - -#define FLIC_HEADER_SIZE 128 -#define FLIC_PREAMBLE_SIZE 6 - -typedef struct FlicDemuxContext { - int video_stream_index; - int audio_stream_index; - int frame_number; -} FlicDemuxContext; - -static int flic_probe(AVProbeData *p) -{ - int magic_number; - - if(p->buf_size < FLIC_HEADER_SIZE) - return 0; - - magic_number = AV_RL16(&p->buf[4]); - if ((magic_number != FLIC_FILE_MAGIC_1) && - (magic_number != FLIC_FILE_MAGIC_2) && - (magic_number != FLIC_FILE_MAGIC_3)) - return 0; - - if(AV_RL16(&p->buf[0x10]) != FLIC_CHUNK_MAGIC_1){ - if(AV_RL32(&p->buf[0x10]) > 2000) - return 0; - } - - if( AV_RL16(&p->buf[0x08]) > 4096 - || AV_RL16(&p->buf[0x0A]) > 4096) - return 0; - - - return AVPROBE_SCORE_MAX; -} - -static int flic_read_header(AVFormatContext *s) -{ - FlicDemuxContext *flic = s->priv_data; - AVIOContext *pb = s->pb; - unsigned char header[FLIC_HEADER_SIZE]; - AVStream *st, *ast; - int speed; - int magic_number; - unsigned char preamble[FLIC_PREAMBLE_SIZE]; - - flic->frame_number = 0; - - /* load the whole header and pull out the width and height */ - if (avio_read(pb, header, FLIC_HEADER_SIZE) != FLIC_HEADER_SIZE) - return AVERROR(EIO); - - magic_number = AV_RL16(&header[4]); - speed = AV_RL32(&header[0x10]); - if (speed == 0) - speed = FLIC_DEFAULT_SPEED; - - /* initialize the decoder streams */ - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - flic->video_stream_index = st->index; - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = AV_CODEC_ID_FLIC; - st->codec->codec_tag = 0; /* no fourcc */ - st->codec->width = AV_RL16(&header[0x08]); - st->codec->height = AV_RL16(&header[0x0A]); - - if (!st->codec->width || !st->codec->height) { - /* Ugly hack needed for the following sample: */ - /* http://samples.mplayerhq.hu/fli-flc/fli-bugs/specular.flc */ - av_log(s, AV_LOG_WARNING, - "File with no specified width/height. Trying 640x480.\n"); - st->codec->width = 640; - st->codec->height = 480; - } - - /* send over the whole 128-byte FLIC header */ - st->codec->extradata_size = FLIC_HEADER_SIZE; - st->codec->extradata = av_malloc(FLIC_HEADER_SIZE); - memcpy(st->codec->extradata, header, FLIC_HEADER_SIZE); - - /* peek at the preamble to detect TFTD videos - they seem to always start with an audio chunk */ - if (avio_read(pb, preamble, FLIC_PREAMBLE_SIZE) != FLIC_PREAMBLE_SIZE) { - av_log(s, AV_LOG_ERROR, "Failed to peek at preamble\n"); - return AVERROR(EIO); - } - - avio_seek(pb, -FLIC_PREAMBLE_SIZE, SEEK_CUR); - - /* Time to figure out the framerate: - * If the first preamble's magic number is 0xAAAA then this file is from - * X-COM: Terror from the Deep. If on the other hand there is a FLIC chunk - * magic number at offset 0x10 assume this file is from Magic Carpet instead. - * If neither of the above is true then this is a normal FLIC file. - */ - if (AV_RL16(&preamble[4]) == FLIC_TFTD_CHUNK_AUDIO) { - /* TFTD videos have an extra 22050 Hz 8-bit mono audio stream */ - ast = avformat_new_stream(s, NULL); - if (!ast) - return AVERROR(ENOMEM); - - flic->audio_stream_index = ast->index; - - /* all audio frames are the same size, so use the size of the first chunk for block_align */ - ast->codec->block_align = AV_RL32(&preamble[0]); - ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; - ast->codec->codec_id = AV_CODEC_ID_PCM_U8; - ast->codec->codec_tag = 0; - ast->codec->sample_rate = FLIC_TFTD_SAMPLE_RATE; - ast->codec->channels = 1; - ast->codec->bit_rate = st->codec->sample_rate * 8; - ast->codec->bits_per_coded_sample = 8; - ast->codec->channel_layout = AV_CH_LAYOUT_MONO; - ast->codec->extradata_size = 0; - - /* Since the header information is incorrect we have to figure out the - * framerate using block_align and the fact that the audio is 22050 Hz. - * We usually have two cases: 2205 -> 10 fps and 1470 -> 15 fps */ - avpriv_set_pts_info(st, 64, ast->codec->block_align, FLIC_TFTD_SAMPLE_RATE); - avpriv_set_pts_info(ast, 64, 1, FLIC_TFTD_SAMPLE_RATE); - } else if (AV_RL16(&header[0x10]) == FLIC_CHUNK_MAGIC_1) { - avpriv_set_pts_info(st, 64, FLIC_MC_SPEED, 70); - - /* rewind the stream since the first chunk is at offset 12 */ - avio_seek(pb, 12, SEEK_SET); - - /* send over abbreviated FLIC header chunk */ - av_free(st->codec->extradata); - st->codec->extradata_size = 12; - st->codec->extradata = av_malloc(12); - memcpy(st->codec->extradata, header, 12); - - } else if (magic_number == FLIC_FILE_MAGIC_1) { - avpriv_set_pts_info(st, 64, speed, 70); - } else if ((magic_number == FLIC_FILE_MAGIC_2) || - (magic_number == FLIC_FILE_MAGIC_3)) { - avpriv_set_pts_info(st, 64, speed, 1000); - } else { - av_log(s, AV_LOG_ERROR, "Invalid or unsupported magic chunk in file\n"); - return AVERROR_INVALIDDATA; - } - - return 0; -} - -static int flic_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - FlicDemuxContext *flic = s->priv_data; - AVIOContext *pb = s->pb; - int packet_read = 0; - unsigned int size; - int magic; - int ret = 0; - unsigned char preamble[FLIC_PREAMBLE_SIZE]; - - while (!packet_read) { - - if ((ret = avio_read(pb, preamble, FLIC_PREAMBLE_SIZE)) != - FLIC_PREAMBLE_SIZE) { - ret = AVERROR(EIO); - break; - } - - size = AV_RL32(&preamble[0]); - magic = AV_RL16(&preamble[4]); - - if (((magic == FLIC_CHUNK_MAGIC_1) || (magic == FLIC_CHUNK_MAGIC_2)) && size > FLIC_PREAMBLE_SIZE) { - if (av_new_packet(pkt, size)) { - ret = AVERROR(EIO); - break; - } - pkt->stream_index = flic->video_stream_index; - pkt->pts = flic->frame_number++; - pkt->pos = avio_tell(pb); - memcpy(pkt->data, preamble, FLIC_PREAMBLE_SIZE); - ret = avio_read(pb, pkt->data + FLIC_PREAMBLE_SIZE, - size - FLIC_PREAMBLE_SIZE); - if (ret != size - FLIC_PREAMBLE_SIZE) { - av_free_packet(pkt); - ret = AVERROR(EIO); - } - packet_read = 1; - } else if (magic == FLIC_TFTD_CHUNK_AUDIO) { - if (av_new_packet(pkt, size)) { - ret = AVERROR(EIO); - break; - } - - /* skip useless 10B sub-header (yes, it's not accounted for in the chunk header) */ - avio_skip(pb, 10); - - pkt->stream_index = flic->audio_stream_index; - pkt->pos = avio_tell(pb); - ret = avio_read(pb, pkt->data, size); - - if (ret != size) { - av_free_packet(pkt); - ret = AVERROR(EIO); - } - - packet_read = 1; - } else { - /* not interested in this chunk */ - avio_skip(pb, size - 6); - } - } - - return ret; -} - -AVInputFormat ff_flic_demuxer = { - .name = "flic", - .long_name = NULL_IF_CONFIG_SMALL("FLI/FLC/FLX animation"), - .priv_data_size = sizeof(FlicDemuxContext), - .read_probe = flic_probe, - .read_header = flic_read_header, - .read_packet = flic_read_packet, -}; diff --git a/ffmpeg1/libavformat/flv.h b/ffmpeg1/libavformat/flv.h deleted file mode 100644 index db9468f..0000000 --- a/ffmpeg1/libavformat/flv.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - * FLV common header - * - * Copyright (c) 2006 The FFmpeg Project - * - * 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 - */ - -/** - * @file - * FLV common header - */ - -#ifndef AVFORMAT_FLV_H -#define AVFORMAT_FLV_H - -/* offsets for packed values */ -#define FLV_AUDIO_SAMPLESSIZE_OFFSET 1 -#define FLV_AUDIO_SAMPLERATE_OFFSET 2 -#define FLV_AUDIO_CODECID_OFFSET 4 - -#define FLV_VIDEO_FRAMETYPE_OFFSET 4 - -/* bitmasks to isolate specific values */ -#define FLV_AUDIO_CHANNEL_MASK 0x01 -#define FLV_AUDIO_SAMPLESIZE_MASK 0x02 -#define FLV_AUDIO_SAMPLERATE_MASK 0x0c -#define FLV_AUDIO_CODECID_MASK 0xf0 - -#define FLV_VIDEO_CODECID_MASK 0x0f -#define FLV_VIDEO_FRAMETYPE_MASK 0xf0 - -#define AMF_END_OF_OBJECT 0x09 - -#define KEYFRAMES_TAG "keyframes" -#define KEYFRAMES_TIMESTAMP_TAG "times" -#define KEYFRAMES_BYTEOFFSET_TAG "filepositions" - - -enum { - FLV_HEADER_FLAG_HASVIDEO = 1, - FLV_HEADER_FLAG_HASAUDIO = 4, -}; - -enum { - FLV_TAG_TYPE_AUDIO = 0x08, - FLV_TAG_TYPE_VIDEO = 0x09, - FLV_TAG_TYPE_META = 0x12, -}; - -enum { - FLV_STREAM_TYPE_VIDEO, - FLV_STREAM_TYPE_AUDIO, - FLV_STREAM_TYPE_DATA, - FLV_STREAM_TYPE_NB, -}; - -enum { - FLV_MONO = 0, - FLV_STEREO = 1, -}; - -enum { - FLV_SAMPLESSIZE_8BIT = 0, - FLV_SAMPLESSIZE_16BIT = 1 << FLV_AUDIO_SAMPLESSIZE_OFFSET, -}; - -enum { - FLV_SAMPLERATE_SPECIAL = 0, /**< signifies 5512Hz and 8000Hz in the case of NELLYMOSER */ - FLV_SAMPLERATE_11025HZ = 1 << FLV_AUDIO_SAMPLERATE_OFFSET, - FLV_SAMPLERATE_22050HZ = 2 << FLV_AUDIO_SAMPLERATE_OFFSET, - FLV_SAMPLERATE_44100HZ = 3 << FLV_AUDIO_SAMPLERATE_OFFSET, -}; - -enum { - FLV_CODECID_PCM = 0, - FLV_CODECID_ADPCM = 1 << FLV_AUDIO_CODECID_OFFSET, - FLV_CODECID_MP3 = 2 << FLV_AUDIO_CODECID_OFFSET, - FLV_CODECID_PCM_LE = 3 << FLV_AUDIO_CODECID_OFFSET, - FLV_CODECID_NELLYMOSER_16KHZ_MONO = 4 << FLV_AUDIO_CODECID_OFFSET, - FLV_CODECID_NELLYMOSER_8KHZ_MONO = 5 << FLV_AUDIO_CODECID_OFFSET, - FLV_CODECID_NELLYMOSER = 6 << FLV_AUDIO_CODECID_OFFSET, - FLV_CODECID_PCM_ALAW = 7 << FLV_AUDIO_CODECID_OFFSET, - FLV_CODECID_PCM_MULAW = 8 << FLV_AUDIO_CODECID_OFFSET, - FLV_CODECID_AAC = 10<< FLV_AUDIO_CODECID_OFFSET, - FLV_CODECID_SPEEX = 11<< FLV_AUDIO_CODECID_OFFSET, -}; - -enum { - FLV_CODECID_H263 = 2, - FLV_CODECID_SCREEN = 3, - FLV_CODECID_VP6 = 4, - FLV_CODECID_VP6A = 5, - FLV_CODECID_SCREEN2 = 6, - FLV_CODECID_H264 = 7, - FLV_CODECID_REALH263= 8, - FLV_CODECID_MPEG4 = 9, -}; - -enum { - FLV_FRAME_KEY = 1 << FLV_VIDEO_FRAMETYPE_OFFSET, ///< key frame (for AVC, a seekable frame) - FLV_FRAME_INTER = 2 << FLV_VIDEO_FRAMETYPE_OFFSET, ///< inter frame (for AVC, a non-seekable frame) - FLV_FRAME_DISP_INTER = 3 << FLV_VIDEO_FRAMETYPE_OFFSET, ///< disposable inter frame (H.263 only) - FLV_FRAME_GENERATED_KEY = 4 << FLV_VIDEO_FRAMETYPE_OFFSET, ///< generated key frame (reserved for server use only) - FLV_FRAME_VIDEO_INFO_CMD = 5 << FLV_VIDEO_FRAMETYPE_OFFSET, ///< video info/command frame -}; - -typedef enum { - AMF_DATA_TYPE_NUMBER = 0x00, - AMF_DATA_TYPE_BOOL = 0x01, - AMF_DATA_TYPE_STRING = 0x02, - AMF_DATA_TYPE_OBJECT = 0x03, - AMF_DATA_TYPE_NULL = 0x05, - AMF_DATA_TYPE_UNDEFINED = 0x06, - AMF_DATA_TYPE_REFERENCE = 0x07, - AMF_DATA_TYPE_MIXEDARRAY = 0x08, - AMF_DATA_TYPE_OBJECT_END = 0x09, - AMF_DATA_TYPE_ARRAY = 0x0a, - AMF_DATA_TYPE_DATE = 0x0b, - AMF_DATA_TYPE_LONG_STRING = 0x0c, - AMF_DATA_TYPE_UNSUPPORTED = 0x0d, -} AMFDataType; - -#endif /* AVFORMAT_FLV_H */ diff --git a/ffmpeg1/libavformat/flvdec.c b/ffmpeg1/libavformat/flvdec.c deleted file mode 100644 index d0511f1..0000000 --- a/ffmpeg1/libavformat/flvdec.c +++ /dev/null @@ -1,923 +0,0 @@ -/* - * FLV demuxer - * Copyright (c) 2003 The FFmpeg Project - * - * This demuxer will generate a 1 byte extradata for VP6F content. - * It is composed of: - * - upper 4bits: difference between encoded width and visible width - * - lower 4bits: difference between encoded height and visible height - * - * 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 "libavutil/avstring.h" -#include "libavutil/channel_layout.h" -#include "libavutil/dict.h" -#include "libavutil/opt.h" -#include "libavutil/intfloat.h" -#include "libavutil/mathematics.h" -#include "libavcodec/bytestream.h" -#include "libavcodec/mpeg4audio.h" -#include "avformat.h" -#include "internal.h" -#include "avio_internal.h" -#include "flv.h" - -#define VALIDATE_INDEX_TS_THRESH 2500 - -typedef struct { - const AVClass *class; ///< Class for private options. - int trust_metadata; ///< configure streams according onMetaData - int wrong_dts; ///< wrong dts due to negative cts - uint8_t *new_extradata[FLV_STREAM_TYPE_NB]; - int new_extradata_size[FLV_STREAM_TYPE_NB]; - int last_sample_rate; - int last_channels; - struct { - int64_t dts; - int64_t pos; - } validate_index[2]; - int validate_next; - int validate_count; - int searched_for_end; -} FLVContext; - -static int flv_probe(AVProbeData *p) -{ - const uint8_t *d; - - d = p->buf; - if (d[0] == 'F' && d[1] == 'L' && d[2] == 'V' && d[3] < 5 && d[5]==0 && AV_RB32(d+5)>8) { - return AVPROBE_SCORE_MAX; - } - return 0; -} - -static AVStream *create_stream(AVFormatContext *s, int codec_type) -{ - AVStream *st = avformat_new_stream(s, NULL); - if (!st) - return NULL; - st->codec->codec_type = codec_type; - if(s->nb_streams>=3 ||( s->nb_streams==2 - && s->streams[0]->codec->codec_type != AVMEDIA_TYPE_DATA - && s->streams[1]->codec->codec_type != AVMEDIA_TYPE_DATA)) - s->ctx_flags &= ~AVFMTCTX_NOHEADER; - - avpriv_set_pts_info(st, 32, 1, 1000); /* 32 bit pts in ms */ - return st; -} -static int flv_same_audio_codec(AVCodecContext *acodec, int flags) -{ - int bits_per_coded_sample = (flags & FLV_AUDIO_SAMPLESIZE_MASK) ? 16 : 8; - int flv_codecid = flags & FLV_AUDIO_CODECID_MASK; - int codec_id; - - if (!acodec->codec_id && !acodec->codec_tag) - return 1; - - if (acodec->bits_per_coded_sample != bits_per_coded_sample) - return 0; - - switch(flv_codecid) { - //no distinction between S16 and S8 PCM codec flags - case FLV_CODECID_PCM: - codec_id = bits_per_coded_sample == 8 ? AV_CODEC_ID_PCM_U8 : -#if HAVE_BIGENDIAN - AV_CODEC_ID_PCM_S16BE; -#else - AV_CODEC_ID_PCM_S16LE; -#endif - return codec_id == acodec->codec_id; - case FLV_CODECID_PCM_LE: - codec_id = bits_per_coded_sample == 8 ? AV_CODEC_ID_PCM_U8 : AV_CODEC_ID_PCM_S16LE; - return codec_id == acodec->codec_id; - case FLV_CODECID_AAC: - return acodec->codec_id == AV_CODEC_ID_AAC; - case FLV_CODECID_ADPCM: - return acodec->codec_id == AV_CODEC_ID_ADPCM_SWF; - case FLV_CODECID_SPEEX: - return acodec->codec_id == AV_CODEC_ID_SPEEX; - case FLV_CODECID_MP3: - return acodec->codec_id == AV_CODEC_ID_MP3; - case FLV_CODECID_NELLYMOSER_8KHZ_MONO: - case FLV_CODECID_NELLYMOSER_16KHZ_MONO: - case FLV_CODECID_NELLYMOSER: - return acodec->codec_id == AV_CODEC_ID_NELLYMOSER; - case FLV_CODECID_PCM_MULAW: - return acodec->sample_rate == 8000 && - acodec->codec_id == AV_CODEC_ID_PCM_MULAW; - case FLV_CODECID_PCM_ALAW: - return acodec->sample_rate = 8000 && - acodec->codec_id == AV_CODEC_ID_PCM_ALAW; - default: - return acodec->codec_tag == (flv_codecid >> FLV_AUDIO_CODECID_OFFSET); - } -} - -static void flv_set_audio_codec(AVFormatContext *s, AVStream *astream, AVCodecContext *acodec, int flv_codecid) { - switch(flv_codecid) { - //no distinction between S16 and S8 PCM codec flags - case FLV_CODECID_PCM: - acodec->codec_id = acodec->bits_per_coded_sample == 8 ? AV_CODEC_ID_PCM_U8 : -#if HAVE_BIGENDIAN - AV_CODEC_ID_PCM_S16BE; -#else - AV_CODEC_ID_PCM_S16LE; -#endif - break; - case FLV_CODECID_PCM_LE: - acodec->codec_id = acodec->bits_per_coded_sample == 8 ? AV_CODEC_ID_PCM_U8 : AV_CODEC_ID_PCM_S16LE; break; - case FLV_CODECID_AAC : acodec->codec_id = AV_CODEC_ID_AAC; break; - case FLV_CODECID_ADPCM: acodec->codec_id = AV_CODEC_ID_ADPCM_SWF; break; - case FLV_CODECID_SPEEX: - acodec->codec_id = AV_CODEC_ID_SPEEX; - acodec->sample_rate = 16000; - break; - case FLV_CODECID_MP3 : acodec->codec_id = AV_CODEC_ID_MP3 ; astream->need_parsing = AVSTREAM_PARSE_FULL; break; - case FLV_CODECID_NELLYMOSER_8KHZ_MONO: - acodec->sample_rate = 8000; //in case metadata does not otherwise declare samplerate - acodec->codec_id = AV_CODEC_ID_NELLYMOSER; - break; - case FLV_CODECID_NELLYMOSER_16KHZ_MONO: - acodec->sample_rate = 16000; - acodec->codec_id = AV_CODEC_ID_NELLYMOSER; - break; - case FLV_CODECID_NELLYMOSER: - acodec->codec_id = AV_CODEC_ID_NELLYMOSER; - break; - case FLV_CODECID_PCM_MULAW: - acodec->sample_rate = 8000; - acodec->codec_id = AV_CODEC_ID_PCM_MULAW; - break; - case FLV_CODECID_PCM_ALAW: - acodec->sample_rate = 8000; - acodec->codec_id = AV_CODEC_ID_PCM_ALAW; - break; - default: - av_log(s, AV_LOG_INFO, "Unsupported audio codec (%x)\n", flv_codecid >> FLV_AUDIO_CODECID_OFFSET); - acodec->codec_tag = flv_codecid >> FLV_AUDIO_CODECID_OFFSET; - } -} - -static int flv_same_video_codec(AVCodecContext *vcodec, int flags) -{ - int flv_codecid = flags & FLV_VIDEO_CODECID_MASK; - - if (!vcodec->codec_id && !vcodec->codec_tag) - return 1; - - switch (flv_codecid) { - case FLV_CODECID_H263: - return vcodec->codec_id == AV_CODEC_ID_FLV1; - case FLV_CODECID_SCREEN: - return vcodec->codec_id == AV_CODEC_ID_FLASHSV; - case FLV_CODECID_SCREEN2: - return vcodec->codec_id == AV_CODEC_ID_FLASHSV2; - case FLV_CODECID_VP6: - return vcodec->codec_id == AV_CODEC_ID_VP6F; - case FLV_CODECID_VP6A: - return vcodec->codec_id == AV_CODEC_ID_VP6A; - case FLV_CODECID_H264: - return vcodec->codec_id == AV_CODEC_ID_H264; - default: - return vcodec->codec_tag == flv_codecid; - } -} - -static int flv_set_video_codec(AVFormatContext *s, AVStream *vstream, int flv_codecid, int read) { - AVCodecContext *vcodec = vstream->codec; - switch(flv_codecid) { - case FLV_CODECID_H263 : vcodec->codec_id = AV_CODEC_ID_FLV1 ; break; - case FLV_CODECID_REALH263: vcodec->codec_id = AV_CODEC_ID_H263 ; break; // Really mean it this time - case FLV_CODECID_SCREEN: vcodec->codec_id = AV_CODEC_ID_FLASHSV; break; - case FLV_CODECID_SCREEN2: vcodec->codec_id = AV_CODEC_ID_FLASHSV2; break; - case FLV_CODECID_VP6 : vcodec->codec_id = AV_CODEC_ID_VP6F ; - case FLV_CODECID_VP6A : - if(flv_codecid == FLV_CODECID_VP6A) - vcodec->codec_id = AV_CODEC_ID_VP6A; - if (read) { - if (vcodec->extradata_size != 1) { - vcodec->extradata = av_malloc(1 + FF_INPUT_BUFFER_PADDING_SIZE); - if (vcodec->extradata) - vcodec->extradata_size = 1; - } - if (vcodec->extradata) - vcodec->extradata[0] = avio_r8(s->pb); - else - avio_skip(s->pb, 1); - } - return 1; // 1 byte body size adjustment for flv_read_packet() - case FLV_CODECID_H264: - vcodec->codec_id = AV_CODEC_ID_H264; - return 3; // not 4, reading packet type will consume one byte - case FLV_CODECID_MPEG4: - vcodec->codec_id = AV_CODEC_ID_MPEG4; - return 3; - default: - av_log(s, AV_LOG_INFO, "Unsupported video codec (%x)\n", flv_codecid); - vcodec->codec_tag = flv_codecid; - } - - return 0; -} - -static int amf_get_string(AVIOContext *ioc, char *buffer, int buffsize) { - int length = avio_rb16(ioc); - if(length >= buffsize) { - avio_skip(ioc, length); - return -1; - } - - avio_read(ioc, buffer, length); - - buffer[length] = '\0'; - - return length; -} - -static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, AVStream *vstream, int64_t max_pos) { - FLVContext *flv = s->priv_data; - unsigned int timeslen = 0, fileposlen = 0, i; - char str_val[256]; - int64_t *times = NULL; - int64_t *filepositions = NULL; - int ret = AVERROR(ENOSYS); - int64_t initial_pos = avio_tell(ioc); - - if(vstream->nb_index_entries>0){ - av_log(s, AV_LOG_WARNING, "Skiping duplicate index\n"); - return 0; - } - - if (s->flags & AVFMT_FLAG_IGNIDX) - return 0; - - while (avio_tell(ioc) < max_pos - 2 && amf_get_string(ioc, str_val, sizeof(str_val)) > 0) { - int64_t** current_array; - unsigned int arraylen; - - // Expect array object in context - if (avio_r8(ioc) != AMF_DATA_TYPE_ARRAY) - break; - - arraylen = avio_rb32(ioc); - if(arraylen>>28) - break; - - if (!strcmp(KEYFRAMES_TIMESTAMP_TAG , str_val) && !times){ - current_array= × - timeslen= arraylen; - }else if (!strcmp(KEYFRAMES_BYTEOFFSET_TAG, str_val) && !filepositions){ - current_array= &filepositions; - fileposlen= arraylen; - }else // unexpected metatag inside keyframes, will not use such metadata for indexing - break; - - if (!(*current_array = av_mallocz(sizeof(**current_array) * arraylen))) { - ret = AVERROR(ENOMEM); - goto finish; - } - - for (i = 0; i < arraylen && avio_tell(ioc) < max_pos - 1; i++) { - if (avio_r8(ioc) != AMF_DATA_TYPE_NUMBER) - goto invalid; - current_array[0][i] = av_int2double(avio_rb64(ioc)); - } - if (times && filepositions) { - // All done, exiting at a position allowing amf_parse_object - // to finish parsing the object - ret = 0; - break; - } - } - - if (timeslen == fileposlen && fileposlen>1 && max_pos <= filepositions[0]) { - for (i = 0; i < fileposlen; i++) { - av_add_index_entry(vstream, filepositions[i], times[i]*1000, - 0, 0, AVINDEX_KEYFRAME); - if (i < 2) { - flv->validate_index[i].pos = filepositions[i]; - flv->validate_index[i].dts = times[i] * 1000; - flv->validate_count = i + 1; - } - } - } else { -invalid: - av_log(s, AV_LOG_WARNING, "Invalid keyframes object, skipping.\n"); - } - -finish: - av_freep(×); - av_freep(&filepositions); - avio_seek(ioc, initial_pos, SEEK_SET); - return ret; -} - -static int amf_parse_object(AVFormatContext *s, AVStream *astream, AVStream *vstream, const char *key, int64_t max_pos, int depth) { - AVCodecContext *acodec, *vcodec; - FLVContext *flv = s->priv_data; - AVIOContext *ioc; - AMFDataType amf_type; - char str_val[256]; - double num_val; - - num_val = 0; - ioc = s->pb; - - amf_type = avio_r8(ioc); - - switch(amf_type) { - case AMF_DATA_TYPE_NUMBER: - num_val = av_int2double(avio_rb64(ioc)); break; - case AMF_DATA_TYPE_BOOL: - num_val = avio_r8(ioc); break; - case AMF_DATA_TYPE_STRING: - if(amf_get_string(ioc, str_val, sizeof(str_val)) < 0) - return -1; - break; - case AMF_DATA_TYPE_OBJECT: - if ((vstream || astream) && ioc->seekable && key && !strcmp(KEYFRAMES_TAG, key) && depth == 1) - if (parse_keyframes_index(s, ioc, vstream ? vstream : astream, - max_pos) < 0) - av_log(s, AV_LOG_ERROR, "Keyframe index parsing failed\n"); - - while (avio_tell(ioc) < max_pos - 2 && amf_get_string(ioc, str_val, sizeof(str_val)) > 0) { - if (amf_parse_object(s, astream, vstream, str_val, max_pos, depth + 1) < 0) - return -1; //if we couldn't skip, bomb out. - } - if(avio_r8(ioc) != AMF_END_OF_OBJECT) - return -1; - break; - case AMF_DATA_TYPE_NULL: - case AMF_DATA_TYPE_UNDEFINED: - case AMF_DATA_TYPE_UNSUPPORTED: - break; //these take up no additional space - case AMF_DATA_TYPE_MIXEDARRAY: - avio_skip(ioc, 4); //skip 32-bit max array index - while(avio_tell(ioc) < max_pos - 2 && amf_get_string(ioc, str_val, sizeof(str_val)) > 0) { - //this is the only case in which we would want a nested parse to not skip over the object - if(amf_parse_object(s, astream, vstream, str_val, max_pos, depth + 1) < 0) - return -1; - } - if(avio_r8(ioc) != AMF_END_OF_OBJECT) - return -1; - break; - case AMF_DATA_TYPE_ARRAY: { - unsigned int arraylen, i; - - arraylen = avio_rb32(ioc); - for(i = 0; i < arraylen && avio_tell(ioc) < max_pos - 1; i++) { - if(amf_parse_object(s, NULL, NULL, NULL, max_pos, depth + 1) < 0) - return -1; //if we couldn't skip, bomb out. - } - } - break; - case AMF_DATA_TYPE_DATE: - avio_skip(ioc, 8 + 2); //timestamp (double) and UTC offset (int16) - break; - default: //unsupported type, we couldn't skip - return -1; - } - - if(depth == 1 && key) { //only look for metadata values when we are not nested and key != NULL - acodec = astream ? astream->codec : NULL; - vcodec = vstream ? vstream->codec : NULL; - - if (amf_type == AMF_DATA_TYPE_NUMBER) { - if (!strcmp(key, "duration")) - s->duration = num_val * AV_TIME_BASE; - else if (!strcmp(key, "videodatarate") && vcodec && 0 <= (int)(num_val * 1024.0)) - vcodec->bit_rate = num_val * 1024.0; - else if (!strcmp(key, "audiodatarate") && acodec && 0 <= (int)(num_val * 1024.0)) - acodec->bit_rate = num_val * 1024.0; - else if (!strcmp(key, "datastream")) { - AVStream *st = create_stream(s, AVMEDIA_TYPE_DATA); - if (!st) - return AVERROR(ENOMEM); - st->codec->codec_id = AV_CODEC_ID_TEXT; - } else if (flv->trust_metadata) { - if (!strcmp(key, "videocodecid") && vcodec) { - flv_set_video_codec(s, vstream, num_val, 0); - } else - if (!strcmp(key, "audiocodecid") && acodec) { - flv_set_audio_codec(s, astream, acodec, num_val); - } else - if (!strcmp(key, "audiosamplerate") && acodec) { - acodec->sample_rate = num_val; - } else - if (!strcmp(key, "width") && vcodec) { - vcodec->width = num_val; - } else - if (!strcmp(key, "height") && vcodec) { - vcodec->height = num_val; - } - } - } - - if (amf_type == AMF_DATA_TYPE_OBJECT && s->nb_streams == 1 && - ((!acodec && !strcmp(key, "audiocodecid")) || - (!vcodec && !strcmp(key, "videocodecid")))) - s->ctx_flags &= ~AVFMTCTX_NOHEADER; //If there is either audio/video missing, codecid will be an empty object - - if (!strcmp(key, "duration") || - !strcmp(key, "filesize") || - !strcmp(key, "width") || - !strcmp(key, "height") || - !strcmp(key, "videodatarate") || - !strcmp(key, "framerate") || - !strcmp(key, "videocodecid") || - !strcmp(key, "audiodatarate") || - !strcmp(key, "audiosamplerate") || - !strcmp(key, "audiosamplesize") || - !strcmp(key, "stereo") || - !strcmp(key, "audiocodecid")) - return 0; - - if(amf_type == AMF_DATA_TYPE_BOOL) { - av_strlcpy(str_val, num_val > 0 ? "true" : "false", sizeof(str_val)); - av_dict_set(&s->metadata, key, str_val, 0); - } else if(amf_type == AMF_DATA_TYPE_NUMBER) { - snprintf(str_val, sizeof(str_val), "%.f", num_val); - av_dict_set(&s->metadata, key, str_val, 0); - } else if (amf_type == AMF_DATA_TYPE_STRING) - av_dict_set(&s->metadata, key, str_val, 0); - } - - return 0; -} - -static int flv_read_metabody(AVFormatContext *s, int64_t next_pos) { - AMFDataType type; - AVStream *stream, *astream, *vstream, *dstream; - AVIOContext *ioc; - int i; - char buffer[11]; //only needs to hold the string "onMetaData". Anything longer is something we don't want. - - vstream = astream = dstream = NULL; - ioc = s->pb; - - //first object needs to be "onMetaData" string - type = avio_r8(ioc); - if (type != AMF_DATA_TYPE_STRING || - amf_get_string(ioc, buffer, sizeof(buffer)) < 0) - return -1; - - if (!strcmp(buffer, "onTextData")) - return 1; - - if (strcmp(buffer, "onMetaData")) - return -1; - - //find the streams now so that amf_parse_object doesn't need to do the lookup every time it is called. - for(i = 0; i < s->nb_streams; i++) { - stream = s->streams[i]; - if(stream->codec->codec_type == AVMEDIA_TYPE_VIDEO) vstream = stream; - else if(stream->codec->codec_type == AVMEDIA_TYPE_AUDIO) astream = stream; - else if(stream->codec->codec_type == AVMEDIA_TYPE_DATA) dstream = stream; - } - - //parse the second object (we want a mixed array) - if(amf_parse_object(s, astream, vstream, buffer, next_pos, 0) < 0) - return -1; - - return 0; -} - -static int flv_read_header(AVFormatContext *s) -{ - int offset, flags; - - avio_skip(s->pb, 4); - flags = avio_r8(s->pb); - /* old flvtool cleared this field */ - /* FIXME: better fix needed */ - if (!flags) { - flags = FLV_HEADER_FLAG_HASVIDEO | FLV_HEADER_FLAG_HASAUDIO; - av_log(s, AV_LOG_WARNING, "Broken FLV file, which says no streams present, this might fail\n"); - } - - s->ctx_flags |= AVFMTCTX_NOHEADER; - - if(flags & FLV_HEADER_FLAG_HASVIDEO){ - if(!create_stream(s, AVMEDIA_TYPE_VIDEO)) - return AVERROR(ENOMEM); - } - if(flags & FLV_HEADER_FLAG_HASAUDIO){ - if(!create_stream(s, AVMEDIA_TYPE_AUDIO)) - return AVERROR(ENOMEM); - } - // Flag doesn't indicate whether or not there is script-data present. Must - // create that stream if it's encountered. - - offset = avio_rb32(s->pb); - avio_seek(s->pb, offset, SEEK_SET); - avio_skip(s->pb, 4); - - s->start_time = 0; - - return 0; -} - -static int flv_read_close(AVFormatContext *s) -{ - int i; - FLVContext *flv = s->priv_data; - for(i=0; inew_extradata[i]); - return 0; -} - -static int flv_get_extradata(AVFormatContext *s, AVStream *st, int size) -{ - av_free(st->codec->extradata); - st->codec->extradata = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!st->codec->extradata) - return AVERROR(ENOMEM); - st->codec->extradata_size = size; - avio_read(s->pb, st->codec->extradata, st->codec->extradata_size); - return 0; -} - -static int flv_queue_extradata(FLVContext *flv, AVIOContext *pb, int stream, - int size) -{ - av_free(flv->new_extradata[stream]); - flv->new_extradata[stream] = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!flv->new_extradata[stream]) - return AVERROR(ENOMEM); - flv->new_extradata_size[stream] = size; - avio_read(pb, flv->new_extradata[stream], size); - return 0; -} - -static void clear_index_entries(AVFormatContext *s, int64_t pos) -{ - int i, j, out; - av_log(s, AV_LOG_WARNING, "Found invalid index entries, clearing the index.\n"); - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - /* Remove all index entries that point to >= pos */ - out = 0; - for (j = 0; j < st->nb_index_entries; j++) { - if (st->index_entries[j].pos < pos) - st->index_entries[out++] = st->index_entries[j]; - } - st->nb_index_entries = out; - } -} - - -static int flv_data_packet(AVFormatContext *s, AVPacket *pkt, - int64_t dts, int64_t next) -{ - int ret = AVERROR_INVALIDDATA, i; - AVIOContext *pb = s->pb; - AVStream *st = NULL; - AMFDataType type; - char buf[20]; - int length; - - type = avio_r8(pb); - if (type == AMF_DATA_TYPE_MIXEDARRAY) - avio_seek(pb, 4, SEEK_CUR); - else if (type != AMF_DATA_TYPE_OBJECT) - goto out; - - amf_get_string(pb, buf, sizeof(buf)); - if (strcmp(buf, "type") || avio_r8(pb) != AMF_DATA_TYPE_STRING) - goto out; - - amf_get_string(pb, buf, sizeof(buf)); - //FIXME parse it as codec_id - amf_get_string(pb, buf, sizeof(buf)); - if (strcmp(buf, "text") || avio_r8(pb) != AMF_DATA_TYPE_STRING) - goto out; - - length = avio_rb16(pb); - ret = av_get_packet(s->pb, pkt, length); - if (ret < 0) { - ret = AVERROR(EIO); - goto out; - } - - for (i = 0; i < s->nb_streams; i++) { - st = s->streams[i]; - if (st->codec->codec_type == AVMEDIA_TYPE_DATA) - break; - } - - if (i == s->nb_streams) { - st = create_stream(s, AVMEDIA_TYPE_DATA); - if (!st) - goto out; - st->codec->codec_id = AV_CODEC_ID_TEXT; - } - - pkt->dts = dts; - pkt->pts = dts; - pkt->size = ret; - - pkt->stream_index = st->index; - pkt->flags |= AV_PKT_FLAG_KEY; - - avio_seek(s->pb, next + 4, SEEK_SET); -out: - return ret; -} - -static int flv_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - FLVContext *flv = s->priv_data; - int ret, i, type, size, flags; - int stream_type=-1; - int64_t next, pos; - int64_t dts, pts = AV_NOPTS_VALUE; - int av_uninit(channels); - int av_uninit(sample_rate); - AVStream *st = NULL; - - for(;;avio_skip(s->pb, 4)){ /* pkt size is repeated at end. skip it */ - pos = avio_tell(s->pb); - type = avio_r8(s->pb); - size = avio_rb24(s->pb); - dts = avio_rb24(s->pb); - dts |= avio_r8(s->pb) << 24; - av_dlog(s, "type:%d, size:%d, dts:%"PRId64"\n", type, size, dts); - if (url_feof(s->pb)) - return AVERROR_EOF; - avio_skip(s->pb, 3); /* stream id, always 0 */ - flags = 0; - - if (flv->validate_next < flv->validate_count) { - int64_t validate_pos = flv->validate_index[flv->validate_next].pos; - if (pos == validate_pos) { - if (FFABS(dts - flv->validate_index[flv->validate_next].dts) <= - VALIDATE_INDEX_TS_THRESH) { - flv->validate_next++; - } else { - clear_index_entries(s, validate_pos); - flv->validate_count = 0; - } - } else if (pos > validate_pos) { - clear_index_entries(s, validate_pos); - flv->validate_count = 0; - } - } - - if(size == 0) - continue; - - next= size + avio_tell(s->pb); - - if (type == FLV_TAG_TYPE_AUDIO) { - stream_type=FLV_STREAM_TYPE_AUDIO; - flags = avio_r8(s->pb); - size--; - } else if (type == FLV_TAG_TYPE_VIDEO) { - stream_type=FLV_STREAM_TYPE_VIDEO; - flags = avio_r8(s->pb); - size--; - if ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_VIDEO_INFO_CMD) - goto skip; - } else if (type == FLV_TAG_TYPE_META) { - if (size > 13+1+4 && dts == 0) { // Header-type metadata stuff - flv_read_metabody(s, next); - goto skip; - } else if (dts != 0) { // Script-data "special" metadata frames - don't skip - stream_type=FLV_STREAM_TYPE_DATA; - } else { - goto skip; - } - } else { - av_log(s, AV_LOG_DEBUG, "skipping flv packet: type %d, size %d, flags %d\n", type, size, flags); - skip: - avio_seek(s->pb, next, SEEK_SET); - continue; - } - - /* skip empty data packets */ - if (!size) - continue; - - /* now find stream */ - for(i=0;inb_streams;i++) { - st = s->streams[i]; - if (stream_type == FLV_STREAM_TYPE_AUDIO) { - if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && - (s->audio_codec_id || flv_same_audio_codec(st->codec, flags))) { - break; - } - } else - if (stream_type == FLV_STREAM_TYPE_VIDEO) { - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && - (s->video_codec_id || flv_same_video_codec(st->codec, flags))) { - break; - } - } else if (stream_type == FLV_STREAM_TYPE_DATA) { - if (st->codec->codec_type == AVMEDIA_TYPE_DATA) - break; - } - } - if(i == s->nb_streams){ - av_log(s, AV_LOG_WARNING, "Stream discovered after head already parsed\n"); - st = create_stream(s, - (int[]){AVMEDIA_TYPE_VIDEO, AVMEDIA_TYPE_AUDIO, AVMEDIA_TYPE_DATA}[stream_type]); - if (!st) - return AVERROR(ENOMEM); - - } - av_dlog(s, "%d %X %d \n", stream_type, flags, st->discard); - if( (st->discard >= AVDISCARD_NONKEY && !((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY || (stream_type == FLV_STREAM_TYPE_AUDIO))) - ||(st->discard >= AVDISCARD_BIDIR && ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_DISP_INTER && (stream_type == FLV_STREAM_TYPE_VIDEO))) - || st->discard >= AVDISCARD_ALL - ){ - avio_seek(s->pb, next, SEEK_SET); - continue; - } - if ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY) - av_add_index_entry(st, pos, dts, size, 0, AVINDEX_KEYFRAME); - break; - } - - // if not streamed and no duration from metadata then seek to end to find the duration from the timestamps - if(s->pb->seekable && (!s->duration || s->duration==AV_NOPTS_VALUE) && !flv->searched_for_end){ - int size; - const int64_t pos= avio_tell(s->pb); - int64_t fsize= avio_size(s->pb); -retry_duration: - avio_seek(s->pb, fsize-4, SEEK_SET); - size= avio_rb32(s->pb); - avio_seek(s->pb, fsize-3-size, SEEK_SET); - if(size == avio_rb24(s->pb) + 11){ - uint32_t ts = avio_rb24(s->pb); - ts |= avio_r8(s->pb) << 24; - if(ts) - s->duration = ts * (int64_t)AV_TIME_BASE / 1000; - else if (fsize >= 8 && fsize - 8 >= size){ - fsize -= size+4; - goto retry_duration; - } - } - - avio_seek(s->pb, pos, SEEK_SET); - flv->searched_for_end = 1; - } - - if(stream_type == FLV_STREAM_TYPE_AUDIO){ - int bits_per_coded_sample; - channels = (flags & FLV_AUDIO_CHANNEL_MASK) == FLV_STEREO ? 2 : 1; - sample_rate = (44100 << ((flags & FLV_AUDIO_SAMPLERATE_MASK) >> FLV_AUDIO_SAMPLERATE_OFFSET) >> 3); - bits_per_coded_sample = (flags & FLV_AUDIO_SAMPLESIZE_MASK) ? 16 : 8; - if(!st->codec->channels || !st->codec->sample_rate || !st->codec->bits_per_coded_sample) { - st->codec->channels = channels; - st->codec->channel_layout = channels == 1 ? AV_CH_LAYOUT_MONO : - AV_CH_LAYOUT_STEREO; - st->codec->sample_rate = sample_rate; - st->codec->bits_per_coded_sample = bits_per_coded_sample; - } - if(!st->codec->codec_id){ - flv_set_audio_codec(s, st, st->codec, flags & FLV_AUDIO_CODECID_MASK); - flv->last_sample_rate = sample_rate = st->codec->sample_rate; - flv->last_channels = channels = st->codec->channels; - } else { - AVCodecContext ctx; - ctx.sample_rate = sample_rate; - flv_set_audio_codec(s, st, &ctx, flags & FLV_AUDIO_CODECID_MASK); - sample_rate = ctx.sample_rate; - } - } else if(stream_type == FLV_STREAM_TYPE_VIDEO) { - size -= flv_set_video_codec(s, st, flags & FLV_VIDEO_CODECID_MASK, 1); - } - - if (st->codec->codec_id == AV_CODEC_ID_AAC || - st->codec->codec_id == AV_CODEC_ID_H264 || - st->codec->codec_id == AV_CODEC_ID_MPEG4) { - int type = avio_r8(s->pb); - size--; - if (st->codec->codec_id == AV_CODEC_ID_H264 || st->codec->codec_id == AV_CODEC_ID_MPEG4) { - int32_t cts = (avio_rb24(s->pb)+0xff800000)^0xff800000; // sign extension - pts = dts + cts; - if (cts < 0) { // dts are wrong - flv->wrong_dts = 1; - av_log(s, AV_LOG_WARNING, "negative cts, previous timestamps might be wrong\n"); - } - if (flv->wrong_dts) - dts = AV_NOPTS_VALUE; - } - if (type == 0 && (!st->codec->extradata || st->codec->codec_id == AV_CODEC_ID_AAC)) { - if (st->codec->extradata) { - if ((ret = flv_queue_extradata(flv, s->pb, stream_type, size)) < 0) - return ret; - ret = AVERROR(EAGAIN); - goto leave; - } - if ((ret = flv_get_extradata(s, st, size)) < 0) - return ret; - if (st->codec->codec_id == AV_CODEC_ID_AAC && 0) { - MPEG4AudioConfig cfg; - if (avpriv_mpeg4audio_get_config(&cfg, st->codec->extradata, - st->codec->extradata_size * 8, 1) >= 0) { - st->codec->channels = cfg.channels; - st->codec->channel_layout = 0; - if (cfg.ext_sample_rate) - st->codec->sample_rate = cfg.ext_sample_rate; - else - st->codec->sample_rate = cfg.sample_rate; - av_dlog(s, "mp4a config channels %d sample rate %d\n", - st->codec->channels, st->codec->sample_rate); - } - } - - ret = AVERROR(EAGAIN); - goto leave; - } - } - - /* skip empty data packets */ - if (!size) { - ret = AVERROR(EAGAIN); - goto leave; - } - - ret= av_get_packet(s->pb, pkt, size); - if (ret < 0) - return ret; - pkt->dts = dts; - pkt->pts = pts == AV_NOPTS_VALUE ? dts : pts; - pkt->stream_index = st->index; - if (flv->new_extradata[stream_type]) { - uint8_t *side = av_packet_new_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, - flv->new_extradata_size[stream_type]); - if (side) { - memcpy(side, flv->new_extradata[stream_type], - flv->new_extradata_size[stream_type]); - av_freep(&flv->new_extradata[stream_type]); - flv->new_extradata_size[stream_type] = 0; - } - } - if (stream_type == FLV_STREAM_TYPE_AUDIO && (sample_rate != flv->last_sample_rate || - channels != flv->last_channels)) { - flv->last_sample_rate = sample_rate; - flv->last_channels = channels; - ff_add_param_change(pkt, channels, 0, sample_rate, 0, 0); - } - - if ( stream_type == FLV_STREAM_TYPE_AUDIO || - ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY) || - stream_type == FLV_STREAM_TYPE_DATA) - pkt->flags |= AV_PKT_FLAG_KEY; - -leave: - avio_skip(s->pb, 4); - return ret; -} - -static int flv_read_seek(AVFormatContext *s, int stream_index, - int64_t ts, int flags) -{ - FLVContext *flv = s->priv_data; - flv->validate_count = 0; - return avio_seek_time(s->pb, stream_index, ts, flags); -} - -#define OFFSET(x) offsetof(FLVContext, x) -#define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM -static const AVOption options[] = { - { "flv_metadata", "Allocate streams according the onMetaData array", OFFSET(trust_metadata), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VD}, - { NULL } -}; - -static const AVClass class = { - .class_name = "flvdec", - .item_name = av_default_item_name, - .option = options, - .version = LIBAVUTIL_VERSION_INT, -}; - -AVInputFormat ff_flv_demuxer = { - .name = "flv", - .long_name = NULL_IF_CONFIG_SMALL("FLV (Flash Video)"), - .priv_data_size = sizeof(FLVContext), - .read_probe = flv_probe, - .read_header = flv_read_header, - .read_packet = flv_read_packet, - .read_seek = flv_read_seek, - .read_close = flv_read_close, - .extensions = "flv", - .priv_class = &class, -}; diff --git a/ffmpeg1/libavformat/flvenc.c b/ffmpeg1/libavformat/flvenc.c deleted file mode 100644 index 502da0f..0000000 --- a/ffmpeg1/libavformat/flvenc.c +++ /dev/null @@ -1,591 +0,0 @@ -/* - * FLV muxer - * Copyright (c) 2003 The FFmpeg Project - * - * 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 "libavutil/intreadwrite.h" -#include "libavutil/dict.h" -#include "libavutil/intfloat.h" -#include "libavutil/avassert.h" -#include "avc.h" -#include "avformat.h" -#include "flv.h" -#include "internal.h" -#include "metadata.h" - - -static const AVCodecTag flv_video_codec_ids[] = { - { AV_CODEC_ID_FLV1, FLV_CODECID_H263 }, - { AV_CODEC_ID_H263, FLV_CODECID_REALH263 }, - { AV_CODEC_ID_MPEG4, FLV_CODECID_MPEG4 }, - { AV_CODEC_ID_FLASHSV, FLV_CODECID_SCREEN }, - { AV_CODEC_ID_FLASHSV2, FLV_CODECID_SCREEN2 }, - { AV_CODEC_ID_VP6F, FLV_CODECID_VP6 }, - { AV_CODEC_ID_VP6, FLV_CODECID_VP6 }, - { AV_CODEC_ID_VP6A, FLV_CODECID_VP6A }, - { AV_CODEC_ID_H264, FLV_CODECID_H264 }, - { AV_CODEC_ID_NONE, 0 } -}; - -static const AVCodecTag flv_audio_codec_ids[] = { - { AV_CODEC_ID_MP3, FLV_CODECID_MP3 >> FLV_AUDIO_CODECID_OFFSET }, - { AV_CODEC_ID_PCM_U8, FLV_CODECID_PCM >> FLV_AUDIO_CODECID_OFFSET }, - { AV_CODEC_ID_PCM_S16BE, FLV_CODECID_PCM >> FLV_AUDIO_CODECID_OFFSET }, - { AV_CODEC_ID_PCM_S16LE, FLV_CODECID_PCM_LE >> FLV_AUDIO_CODECID_OFFSET }, - { AV_CODEC_ID_ADPCM_SWF, FLV_CODECID_ADPCM >> FLV_AUDIO_CODECID_OFFSET }, - { AV_CODEC_ID_AAC, FLV_CODECID_AAC >> FLV_AUDIO_CODECID_OFFSET }, - { AV_CODEC_ID_NELLYMOSER, FLV_CODECID_NELLYMOSER >> FLV_AUDIO_CODECID_OFFSET }, - { AV_CODEC_ID_PCM_MULAW, FLV_CODECID_PCM_MULAW >> FLV_AUDIO_CODECID_OFFSET }, - { AV_CODEC_ID_PCM_ALAW, FLV_CODECID_PCM_ALAW >> FLV_AUDIO_CODECID_OFFSET }, - { AV_CODEC_ID_SPEEX, FLV_CODECID_SPEEX >> FLV_AUDIO_CODECID_OFFSET }, - { AV_CODEC_ID_NONE, 0 } -}; - -typedef struct FLVContext { - int reserved; - int64_t duration_offset; - int64_t filesize_offset; - int64_t duration; - int64_t delay; ///< first dts delay (needed for AVC & Speex) -} FLVContext; - -typedef struct FLVStreamContext { - int64_t last_ts; ///< last timestamp for each stream -} FLVStreamContext; - -static int get_audio_flags(AVFormatContext *s, AVCodecContext *enc) -{ - int flags = (enc->bits_per_coded_sample == 16) ? FLV_SAMPLESSIZE_16BIT - : FLV_SAMPLESSIZE_8BIT; - - if (enc->codec_id == AV_CODEC_ID_AAC) // specs force these parameters - return FLV_CODECID_AAC | FLV_SAMPLERATE_44100HZ | - FLV_SAMPLESSIZE_16BIT | FLV_STEREO; - else if (enc->codec_id == AV_CODEC_ID_SPEEX) { - if (enc->sample_rate != 16000) { - av_log(s, AV_LOG_ERROR, - "FLV only supports wideband (16kHz) Speex audio\n"); - return AVERROR(EINVAL); - } - if (enc->channels != 1) { - av_log(s, AV_LOG_ERROR, "FLV only supports mono Speex audio\n"); - return AVERROR(EINVAL); - } - return FLV_CODECID_SPEEX | FLV_SAMPLERATE_11025HZ | FLV_SAMPLESSIZE_16BIT; - } else { - switch (enc->sample_rate) { - case 44100: - flags |= FLV_SAMPLERATE_44100HZ; - break; - case 22050: - flags |= FLV_SAMPLERATE_22050HZ; - break; - case 11025: - flags |= FLV_SAMPLERATE_11025HZ; - break; - case 16000: // nellymoser only - case 8000: // nellymoser only - case 5512: // not MP3 - if (enc->codec_id != AV_CODEC_ID_MP3) { - flags |= FLV_SAMPLERATE_SPECIAL; - break; - } - default: - av_log(s, AV_LOG_ERROR, - "FLV does not support sample rate %d, " - "choose from (44100, 22050, 11025)\n", enc->sample_rate); - return AVERROR(EINVAL); - } - } - - if (enc->channels > 1) - flags |= FLV_STEREO; - - switch (enc->codec_id) { - case AV_CODEC_ID_MP3: - flags |= FLV_CODECID_MP3 | FLV_SAMPLESSIZE_16BIT; - break; - case AV_CODEC_ID_PCM_U8: - flags |= FLV_CODECID_PCM | FLV_SAMPLESSIZE_8BIT; - break; - case AV_CODEC_ID_PCM_S16BE: - flags |= FLV_CODECID_PCM | FLV_SAMPLESSIZE_16BIT; - break; - case AV_CODEC_ID_PCM_S16LE: - flags |= FLV_CODECID_PCM_LE | FLV_SAMPLESSIZE_16BIT; - break; - case AV_CODEC_ID_ADPCM_SWF: - flags |= FLV_CODECID_ADPCM | FLV_SAMPLESSIZE_16BIT; - break; - case AV_CODEC_ID_NELLYMOSER: - if (enc->sample_rate == 8000) - flags |= FLV_CODECID_NELLYMOSER_8KHZ_MONO | FLV_SAMPLESSIZE_16BIT; - else if (enc->sample_rate == 16000) - flags |= FLV_CODECID_NELLYMOSER_16KHZ_MONO | FLV_SAMPLESSIZE_16BIT; - else - flags |= FLV_CODECID_NELLYMOSER | FLV_SAMPLESSIZE_16BIT; - break; - case AV_CODEC_ID_PCM_MULAW: - flags = FLV_CODECID_PCM_MULAW | FLV_SAMPLERATE_SPECIAL | FLV_SAMPLESSIZE_16BIT; - break; - case AV_CODEC_ID_PCM_ALAW: - flags = FLV_CODECID_PCM_ALAW | FLV_SAMPLERATE_SPECIAL | FLV_SAMPLESSIZE_16BIT; - break; - case 0: - flags |= enc->codec_tag << 4; - break; - default: - av_log(s, AV_LOG_ERROR, "Audio codec '%s' not compatible with FLV\n", - avcodec_get_name(enc->codec_id)); - return AVERROR(EINVAL); - } - - return flags; -} - -static void put_amf_string(AVIOContext *pb, const char *str) -{ - size_t len = strlen(str); - avio_wb16(pb, len); - avio_write(pb, str, len); -} - -static void put_avc_eos_tag(AVIOContext *pb, unsigned ts) -{ - avio_w8(pb, FLV_TAG_TYPE_VIDEO); - avio_wb24(pb, 5); /* Tag Data Size */ - avio_wb24(pb, ts); /* lower 24 bits of timestamp in ms */ - avio_w8(pb, (ts >> 24) & 0x7F); /* MSB of ts in ms */ - avio_wb24(pb, 0); /* StreamId = 0 */ - avio_w8(pb, 23); /* ub[4] FrameType = 1, ub[4] CodecId = 7 */ - avio_w8(pb, 2); /* AVC end of sequence */ - avio_wb24(pb, 0); /* Always 0 for AVC EOS. */ - avio_wb32(pb, 16); /* Size of FLV tag */ -} - -static void put_amf_double(AVIOContext *pb, double d) -{ - avio_w8(pb, AMF_DATA_TYPE_NUMBER); - avio_wb64(pb, av_double2int(d)); -} - -static void put_amf_bool(AVIOContext *pb, int b) -{ - avio_w8(pb, AMF_DATA_TYPE_BOOL); - avio_w8(pb, !!b); -} - -static int flv_write_header(AVFormatContext *s) -{ - AVIOContext *pb = s->pb; - FLVContext *flv = s->priv_data; - AVCodecContext *audio_enc = NULL, *video_enc = NULL, *data_enc = NULL; - int i, metadata_count = 0; - double framerate = 0.0; - int64_t metadata_size_pos, data_size, metadata_count_pos; - AVDictionaryEntry *tag = NULL; - - for (i = 0; i < s->nb_streams; i++) { - AVCodecContext *enc = s->streams[i]->codec; - FLVStreamContext *sc; - switch (enc->codec_type) { - case AVMEDIA_TYPE_VIDEO: - if (s->streams[i]->avg_frame_rate.den && - s->streams[i]->avg_frame_rate.num) { - framerate = av_q2d(s->streams[i]->avg_frame_rate); - } else { - framerate = 1 / av_q2d(s->streams[i]->codec->time_base); - } - video_enc = enc; - if (enc->codec_tag == 0) { - av_log(s, AV_LOG_ERROR, "Video codec '%s' for stream %d is not compatible with FLV\n", - avcodec_get_name(enc->codec_id), i); - return AVERROR(EINVAL); - } - break; - case AVMEDIA_TYPE_AUDIO: - audio_enc = enc; - if (get_audio_flags(s, enc) < 0) - return AVERROR_INVALIDDATA; - break; - case AVMEDIA_TYPE_DATA: - if (enc->codec_id != AV_CODEC_ID_TEXT) { - av_log(s, AV_LOG_ERROR, "Data codec '%s' for stream %d is not compatible with FLV\n", - avcodec_get_name(enc->codec_id), i); - return AVERROR_INVALIDDATA; - } - data_enc = enc; - break; - default: - av_log(s, AV_LOG_ERROR, "Codec type '%s' for stream %d is not compatible with FLV\n", - av_get_media_type_string(enc->codec_type), i); - return AVERROR(EINVAL); - } - avpriv_set_pts_info(s->streams[i], 32, 1, 1000); /* 32 bit pts in ms */ - - sc = av_mallocz(sizeof(FLVStreamContext)); - if (!sc) - return AVERROR(ENOMEM); - s->streams[i]->priv_data = sc; - sc->last_ts = -1; - } - - flv->delay = AV_NOPTS_VALUE; - - avio_write(pb, "FLV", 3); - avio_w8(pb, 1); - avio_w8(pb, FLV_HEADER_FLAG_HASAUDIO * !!audio_enc + - FLV_HEADER_FLAG_HASVIDEO * !!video_enc); - avio_wb32(pb, 9); - avio_wb32(pb, 0); - - for (i = 0; i < s->nb_streams; i++) - if (s->streams[i]->codec->codec_tag == 5) { - avio_w8(pb, 8); // message type - avio_wb24(pb, 0); // include flags - avio_wb24(pb, 0); // time stamp - avio_wb32(pb, 0); // reserved - avio_wb32(pb, 11); // size - flv->reserved = 5; - } - - /* write meta_tag */ - avio_w8(pb, 18); // tag type META - metadata_size_pos = avio_tell(pb); - avio_wb24(pb, 0); // size of data part (sum of all parts below) - avio_wb24(pb, 0); // timestamp - avio_wb32(pb, 0); // reserved - - /* now data of data_size size */ - - /* first event name as a string */ - avio_w8(pb, AMF_DATA_TYPE_STRING); - put_amf_string(pb, "onMetaData"); // 12 bytes - - /* mixed array (hash) with size and string/type/data tuples */ - avio_w8(pb, AMF_DATA_TYPE_MIXEDARRAY); - metadata_count_pos = avio_tell(pb); - metadata_count = 5 * !!video_enc + - 5 * !!audio_enc + - 1 * !!data_enc + - 2; // +2 for duration and file size - - avio_wb32(pb, metadata_count); - - put_amf_string(pb, "duration"); - flv->duration_offset= avio_tell(pb); - - // fill in the guessed duration, it'll be corrected later if incorrect - put_amf_double(pb, s->duration / AV_TIME_BASE); - - if (video_enc) { - put_amf_string(pb, "width"); - put_amf_double(pb, video_enc->width); - - put_amf_string(pb, "height"); - put_amf_double(pb, video_enc->height); - - put_amf_string(pb, "videodatarate"); - put_amf_double(pb, video_enc->bit_rate / 1024.0); - - put_amf_string(pb, "framerate"); - put_amf_double(pb, framerate); - - put_amf_string(pb, "videocodecid"); - put_amf_double(pb, video_enc->codec_tag); - } - - if (audio_enc) { - put_amf_string(pb, "audiodatarate"); - put_amf_double(pb, audio_enc->bit_rate / 1024.0); - - put_amf_string(pb, "audiosamplerate"); - put_amf_double(pb, audio_enc->sample_rate); - - put_amf_string(pb, "audiosamplesize"); - put_amf_double(pb, audio_enc->codec_id == AV_CODEC_ID_PCM_U8 ? 8 : 16); - - put_amf_string(pb, "stereo"); - put_amf_bool(pb, audio_enc->channels == 2); - - put_amf_string(pb, "audiocodecid"); - put_amf_double(pb, audio_enc->codec_tag); - } - - if (data_enc) { - put_amf_string(pb, "datastream"); - put_amf_double(pb, 0.0); - } - - while ((tag = av_dict_get(s->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) { - if( !strcmp(tag->key, "width") - ||!strcmp(tag->key, "height") - ||!strcmp(tag->key, "videodatarate") - ||!strcmp(tag->key, "framerate") - ||!strcmp(tag->key, "videocodecid") - ||!strcmp(tag->key, "audiodatarate") - ||!strcmp(tag->key, "audiosamplerate") - ||!strcmp(tag->key, "audiosamplesize") - ||!strcmp(tag->key, "stereo") - ||!strcmp(tag->key, "audiocodecid") - ||!strcmp(tag->key, "duration") - ||!strcmp(tag->key, "onMetaData") - ){ - av_log(s, AV_LOG_DEBUG, "Ignoring metadata for %s\n", tag->key); - continue; - } - put_amf_string(pb, tag->key); - avio_w8(pb, AMF_DATA_TYPE_STRING); - put_amf_string(pb, tag->value); - metadata_count++; - } - - put_amf_string(pb, "filesize"); - flv->filesize_offset = avio_tell(pb); - put_amf_double(pb, 0); // delayed write - - put_amf_string(pb, ""); - avio_w8(pb, AMF_END_OF_OBJECT); - - /* write total size of tag */ - data_size = avio_tell(pb) - metadata_size_pos - 10; - - avio_seek(pb, metadata_count_pos, SEEK_SET); - avio_wb32(pb, metadata_count); - - avio_seek(pb, metadata_size_pos, SEEK_SET); - avio_wb24(pb, data_size); - avio_skip(pb, data_size + 10 - 3); - avio_wb32(pb, data_size + 11); - - for (i = 0; i < s->nb_streams; i++) { - AVCodecContext *enc = s->streams[i]->codec; - if (enc->codec_id == AV_CODEC_ID_AAC || enc->codec_id == AV_CODEC_ID_H264 || enc->codec_id == AV_CODEC_ID_MPEG4) { - int64_t pos; - avio_w8(pb, enc->codec_type == AVMEDIA_TYPE_VIDEO ? - FLV_TAG_TYPE_VIDEO : FLV_TAG_TYPE_AUDIO); - avio_wb24(pb, 0); // size patched later - avio_wb24(pb, 0); // ts - avio_w8(pb, 0); // ts ext - avio_wb24(pb, 0); // streamid - pos = avio_tell(pb); - if (enc->codec_id == AV_CODEC_ID_AAC) { - avio_w8(pb, get_audio_flags(s, enc)); - avio_w8(pb, 0); // AAC sequence header - avio_write(pb, enc->extradata, enc->extradata_size); - } else { - avio_w8(pb, enc->codec_tag | FLV_FRAME_KEY); // flags - avio_w8(pb, 0); // AVC sequence header - avio_wb24(pb, 0); // composition time - ff_isom_write_avcc(pb, enc->extradata, enc->extradata_size); - } - data_size = avio_tell(pb) - pos; - avio_seek(pb, -data_size - 10, SEEK_CUR); - avio_wb24(pb, data_size); - avio_skip(pb, data_size + 10 - 3); - avio_wb32(pb, data_size + 11); // previous tag size - } - } - - return 0; -} - -static int flv_write_trailer(AVFormatContext *s) -{ - int64_t file_size; - - AVIOContext *pb = s->pb; - FLVContext *flv = s->priv_data; - int i; - - /* Add EOS tag */ - for (i = 0; i < s->nb_streams; i++) { - AVCodecContext *enc = s->streams[i]->codec; - FLVStreamContext *sc = s->streams[i]->priv_data; - if (enc->codec_type == AVMEDIA_TYPE_VIDEO && - (enc->codec_id == AV_CODEC_ID_H264 || enc->codec_id == AV_CODEC_ID_MPEG4)) - put_avc_eos_tag(pb, sc->last_ts); - } - - file_size = avio_tell(pb); - - /* update information */ - if (avio_seek(pb, flv->duration_offset, SEEK_SET) < 0) - av_log(s, AV_LOG_WARNING, "Failed to update header with correct duration.\n"); - else - put_amf_double(pb, flv->duration / (double)1000); - if (avio_seek(pb, flv->filesize_offset, SEEK_SET) < 0) - av_log(s, AV_LOG_WARNING, "Failed to update header with correct filesize.\n"); - else - put_amf_double(pb, file_size); - - avio_seek(pb, file_size, SEEK_SET); - return 0; -} - -static int flv_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - AVIOContext *pb = s->pb; - AVCodecContext *enc = s->streams[pkt->stream_index]->codec; - FLVContext *flv = s->priv_data; - FLVStreamContext *sc = s->streams[pkt->stream_index]->priv_data; - unsigned ts; - int size = pkt->size; - uint8_t *data = NULL; - int flags = -1, flags_size, ret; - - if (enc->codec_id == AV_CODEC_ID_VP6 || enc->codec_id == AV_CODEC_ID_VP6F || - enc->codec_id == AV_CODEC_ID_VP6A || enc->codec_id == AV_CODEC_ID_AAC) - flags_size = 2; - else if (enc->codec_id == AV_CODEC_ID_H264 || enc->codec_id == AV_CODEC_ID_MPEG4) - flags_size = 5; - else - flags_size = 1; - - switch (enc->codec_type) { - case AVMEDIA_TYPE_VIDEO: - avio_w8(pb, FLV_TAG_TYPE_VIDEO); - - flags = enc->codec_tag; - if (flags == 0) { - av_log(s, AV_LOG_ERROR, - "Video codec '%s' is not compatible with FLV\n", - avcodec_get_name(enc->codec_id)); - return AVERROR(EINVAL); - } - - flags |= pkt->flags & AV_PKT_FLAG_KEY ? FLV_FRAME_KEY : FLV_FRAME_INTER; - break; - case AVMEDIA_TYPE_AUDIO: - flags = get_audio_flags(s, enc); - - av_assert0(size); - - avio_w8(pb, FLV_TAG_TYPE_AUDIO); - break; - case AVMEDIA_TYPE_DATA: - avio_w8(pb, FLV_TAG_TYPE_META); - break; - default: - return AVERROR(EINVAL); - } - - if (enc->codec_id == AV_CODEC_ID_H264 || enc->codec_id == AV_CODEC_ID_MPEG4) { - /* check if extradata looks like mp4 formated */ - if (enc->extradata_size > 0 && *(uint8_t*)enc->extradata != 1) - if ((ret = ff_avc_parse_nal_units_buf(pkt->data, &data, &size)) < 0) - return ret; - } else if (enc->codec_id == AV_CODEC_ID_AAC && pkt->size > 2 && - (AV_RB16(pkt->data) & 0xfff0) == 0xfff0) { - av_log(s, AV_LOG_ERROR, "Malformed AAC bitstream detected: " - "use audio bitstream filter 'aac_adtstoasc' to fix it " - "('-bsf:a aac_adtstoasc' option with ffmpeg)\n"); - return AVERROR_INVALIDDATA; - } - - if (flv->delay == AV_NOPTS_VALUE) - flv->delay = -pkt->dts; - - if (pkt->dts < -flv->delay) { - av_log(s, AV_LOG_WARNING, - "Packets are not in the proper order with respect to DTS\n"); - return AVERROR(EINVAL); - } - - ts = pkt->dts + flv->delay; // add delay to force positive dts - - /* check Speex packet duration */ - if (enc->codec_id == AV_CODEC_ID_SPEEX && ts - sc->last_ts > 160) - av_log(s, AV_LOG_WARNING, "Warning: Speex stream has more than " - "8 frames per packet. Adobe Flash " - "Player cannot handle this!\n"); - - if (sc->last_ts < ts) - sc->last_ts = ts; - - avio_wb24(pb, size + flags_size); - avio_wb24(pb, ts); - avio_w8(pb, (ts >> 24) & 0x7F); // timestamps are 32 bits _signed_ - avio_wb24(pb, flv->reserved); - - if (enc->codec_type == AVMEDIA_TYPE_DATA) { - int data_size; - int metadata_size_pos = avio_tell(pb); - avio_w8(pb, AMF_DATA_TYPE_STRING); - put_amf_string(pb, "onTextData"); - avio_w8(pb, AMF_DATA_TYPE_MIXEDARRAY); - avio_wb32(pb, 2); - put_amf_string(pb, "type"); - avio_w8(pb, AMF_DATA_TYPE_STRING); - put_amf_string(pb, "Text"); - put_amf_string(pb, "text"); - avio_w8(pb, AMF_DATA_TYPE_STRING); - put_amf_string(pb, pkt->data); - put_amf_string(pb, ""); - avio_w8(pb, AMF_END_OF_OBJECT); - /* write total size of tag */ - data_size = avio_tell(pb) - metadata_size_pos; - avio_seek(pb, metadata_size_pos - 10, SEEK_SET); - avio_wb24(pb, data_size); - avio_seek(pb, data_size + 10 - 3, SEEK_CUR); - avio_wb32(pb, data_size + 11); - } else { - av_assert1(flags>=0); - avio_w8(pb,flags); - if (enc->codec_id == AV_CODEC_ID_VP6) - avio_w8(pb,0); - if (enc->codec_id == AV_CODEC_ID_VP6F || enc->codec_id == AV_CODEC_ID_VP6A) - avio_w8(pb, enc->extradata_size ? enc->extradata[0] : 0); - else if (enc->codec_id == AV_CODEC_ID_AAC) - avio_w8(pb,1); // AAC raw - else if (enc->codec_id == AV_CODEC_ID_H264 || enc->codec_id == AV_CODEC_ID_MPEG4) { - avio_w8(pb,1); // AVC NALU - avio_wb24(pb,pkt->pts - pkt->dts); - } - - avio_write(pb, data ? data : pkt->data, size); - - avio_wb32(pb, size + flags_size + 11); // previous tag size - flv->duration = FFMAX(flv->duration, - pkt->pts + flv->delay + pkt->duration); - } - - avio_flush(pb); - av_free(data); - - return pb->error; -} - -AVOutputFormat ff_flv_muxer = { - .name = "flv", - .long_name = NULL_IF_CONFIG_SMALL("FLV (Flash Video)"), - .mime_type = "video/x-flv", - .extensions = "flv", - .priv_data_size = sizeof(FLVContext), - .audio_codec = CONFIG_LIBMP3LAME ? AV_CODEC_ID_MP3 : AV_CODEC_ID_ADPCM_SWF, - .video_codec = AV_CODEC_ID_FLV1, - .write_header = flv_write_header, - .write_packet = flv_write_packet, - .write_trailer = flv_write_trailer, - .codec_tag = (const AVCodecTag* const []) { - flv_video_codec_ids, flv_audio_codec_ids, 0 - }, - .flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS | - AVFMT_TS_NONSTRICT, -}; diff --git a/ffmpeg1/libavformat/framecrcenc.c b/ffmpeg1/libavformat/framecrcenc.c deleted file mode 100644 index 92f2e91..0000000 --- a/ffmpeg1/libavformat/framecrcenc.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * frame CRC encoder (for codec/format testing) - * Copyright (c) 2002 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 "libavutil/adler32.h" -#include "libavutil/avstring.h" -#include "avformat.h" -#include "internal.h" - -static int framecrc_write_packet(struct AVFormatContext *s, AVPacket *pkt) -{ - uint32_t crc = av_adler32_update(0, pkt->data, pkt->size); - char buf[256]; - - snprintf(buf, sizeof(buf), "%d, %10"PRId64", %10"PRId64", %8d, %8d, 0x%08x", - pkt->stream_index, pkt->dts, pkt->pts, pkt->duration, pkt->size, crc); - if (pkt->flags != AV_PKT_FLAG_KEY) - av_strlcatf(buf, sizeof(buf), ", F=0x%0X", pkt->flags); - if (pkt->side_data_elems) { - int i; - av_strlcatf(buf, sizeof(buf), ", S=%d", pkt->side_data_elems); - - for (i=0; iside_data_elems; i++) { - uint32_t side_data_crc = av_adler32_update(0, - pkt->side_data[i].data, - pkt->side_data[i].size); - av_strlcatf(buf, sizeof(buf), ", %8d, 0x%08x", pkt->side_data[i].size, side_data_crc); - } - } - av_strlcatf(buf, sizeof(buf), "\n"); - avio_write(s->pb, buf, strlen(buf)); - avio_flush(s->pb); - return 0; -} - -AVOutputFormat ff_framecrc_muxer = { - .name = "framecrc", - .long_name = NULL_IF_CONFIG_SMALL("framecrc testing"), - .audio_codec = AV_CODEC_ID_PCM_S16LE, - .video_codec = AV_CODEC_ID_RAWVIDEO, - .write_header = ff_framehash_write_header, - .write_packet = framecrc_write_packet, - .flags = AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT, -}; diff --git a/ffmpeg1/libavformat/framehash.c b/ffmpeg1/libavformat/framehash.c deleted file mode 100644 index 28e9e84..0000000 --- a/ffmpeg1/libavformat/framehash.c +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Common functions for the frame{crc,md5} muxers - * - * 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 - */ - -#include "internal.h" - -int ff_framehash_write_header(AVFormatContext *s) -{ - int i; - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - avpriv_set_pts_info(st, 64, st->codec->time_base.num, st->codec->time_base.den); - avio_printf(s->pb, "#tb %d: %d/%d\n", i, st->time_base.num, st->time_base.den); - avio_flush(s->pb); - } - return 0; -} diff --git a/ffmpeg1/libavformat/frmdec.c b/ffmpeg1/libavformat/frmdec.c deleted file mode 100644 index a6f19af..0000000 --- a/ffmpeg1/libavformat/frmdec.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Megalux Frame demuxer - * Copyright (c) 2010 Peter Ross - * - * 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 - */ - -/** - * @file - * Megalux Frame demuxer - */ - -#include "libavcodec/raw.h" -#include "libavutil/intreadwrite.h" -#include "avformat.h" - -static const PixelFormatTag frm_pix_fmt_tags[] = { - { AV_PIX_FMT_RGB555, 1 }, - { AV_PIX_FMT_RGB0, 2 }, - { AV_PIX_FMT_RGB24, 3 }, - { AV_PIX_FMT_BGR0, 4 }, - { AV_PIX_FMT_BGRA, 5 }, - { AV_PIX_FMT_NONE, 0 }, -}; - -typedef struct { - int count; -} FrmContext; - -static int frm_read_probe(AVProbeData *p) -{ - if (p->buf_size > 8 && - p->buf[0] == 'F' && p->buf[1] == 'R' && p->buf[2] == 'M' && - AV_RL16(&p->buf[4]) && AV_RL16(&p->buf[6])) - return AVPROBE_SCORE_MAX / 4; - return 0; -} - -static int frm_read_header(AVFormatContext *avctx) -{ - AVIOContext *pb = avctx->pb; - AVStream *st = avformat_new_stream(avctx, 0); - if (!st) - return AVERROR(ENOMEM); - - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = AV_CODEC_ID_RAWVIDEO; - avio_skip(pb, 3); - - st->codec->pix_fmt = avpriv_find_pix_fmt(frm_pix_fmt_tags, avio_r8(pb)); - if (!st->codec->pix_fmt) - return AVERROR_INVALIDDATA; - - st->codec->codec_tag = 0; - st->codec->width = avio_rl16(pb); - st->codec->height = avio_rl16(pb); - return 0; -} - -static int frm_read_packet(AVFormatContext *avctx, AVPacket *pkt) -{ - FrmContext *s = avctx->priv_data; - AVCodecContext *stc = avctx->streams[0]->codec; - int packet_size, ret; - - if (s->count) - return AVERROR_EOF; - - packet_size = avpicture_get_size(stc->pix_fmt, stc->width, stc->height); - if (packet_size < 0) - return AVERROR_INVALIDDATA; - - ret = av_get_packet(avctx->pb, pkt, packet_size); - if (ret < 0) - return ret; - - if (stc->pix_fmt == AV_PIX_FMT_BGRA) { - int i; - for (i = 3; i + 1 <= pkt->size; i += 4) - pkt->data[i] = 0xFF - pkt->data[i]; - } - - pkt->stream_index = 0; - s->count++; - - return 0; -} - -AVInputFormat ff_frm_demuxer = { - .name = "frm", - .priv_data_size = sizeof(FrmContext), - .long_name = NULL_IF_CONFIG_SMALL("Megalux Frame"), - .read_probe = frm_read_probe, - .read_header = frm_read_header, - .read_packet = frm_read_packet, -}; diff --git a/ffmpeg1/libavformat/g722.c b/ffmpeg1/libavformat/g722.c deleted file mode 100644 index 1a87c7d..0000000 --- a/ffmpeg1/libavformat/g722.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * g722 raw demuxer - * Copyright (c) 2010 Martin Storsjo - * - * 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 "libavutil/avassert.h" -#include "avformat.h" -#include "internal.h" -#include "rawdec.h" - -static int g722_read_header(AVFormatContext *s) -{ - AVStream *st; - - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = AV_CODEC_ID_ADPCM_G722; - st->codec->sample_rate = 16000; - st->codec->channels = 1; - - st->codec->bits_per_coded_sample = - av_get_bits_per_sample(st->codec->codec_id); - - av_assert0(st->codec->bits_per_coded_sample > 0); - - avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); - return 0; -} - -AVInputFormat ff_g722_demuxer = { - .name = "g722", - .long_name = NULL_IF_CONFIG_SMALL("raw G.722"), - .read_header = g722_read_header, - .read_packet = ff_raw_read_partial_packet, - .flags = AVFMT_GENERIC_INDEX, - .extensions = "g722,722", - .raw_codec_id = AV_CODEC_ID_ADPCM_G722, -}; diff --git a/ffmpeg1/libavformat/g723_1.c b/ffmpeg1/libavformat/g723_1.c deleted file mode 100644 index 8d35f88..0000000 --- a/ffmpeg1/libavformat/g723_1.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * G.723.1 demuxer - * Copyright (c) 2010 Mohamed Naufal Basheer - * - * 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 - */ - -/** - * @file - * G.723.1 demuxer - */ - -#include "libavutil/channel_layout.h" -#include "avformat.h" -#include "internal.h" - -static const uint8_t frame_size[4] = { 24, 20, 4, 1 }; - -static int g723_1_init(AVFormatContext *s) -{ - AVStream *st; - - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = AV_CODEC_ID_G723_1; - st->codec->channel_layout = AV_CH_LAYOUT_MONO; - st->codec->channels = 1; - st->codec->sample_rate = 8000; - - avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); - st->start_time = 0; - - return 0; -} - -static int g723_1_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - int size, byte, ret; - - pkt->pos = avio_tell(s->pb); - byte = avio_r8(s->pb); - size = frame_size[byte & 3]; - - ret = av_new_packet(pkt, size); - if (ret < 0) - return ret; - - pkt->data[0] = byte; - pkt->duration = 240; - pkt->stream_index = 0; - - ret = avio_read(s->pb, pkt->data + 1, size - 1); - if (ret < size - 1) { - av_free_packet(pkt); - return ret < 0 ? ret : AVERROR_EOF; - } - - return pkt->size; -} - -AVInputFormat ff_g723_1_demuxer = { - .name = "g723_1", - .long_name = NULL_IF_CONFIG_SMALL("G.723.1"), - .read_header = g723_1_init, - .read_packet = g723_1_read_packet, - .extensions = "tco,rco,g723_1", - .flags = AVFMT_GENERIC_INDEX -}; diff --git a/ffmpeg1/libavformat/g729dec.c b/ffmpeg1/libavformat/g729dec.c deleted file mode 100644 index 794558e..0000000 --- a/ffmpeg1/libavformat/g729dec.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - * G.729 raw format demuxer - * Copyright (c) 2011 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 "internal.h" -#include "libavutil/log.h" -#include "libavutil/opt.h" - -typedef struct G729DemuxerContext { - AVClass *class; - int bit_rate; -} G729DemuxerContext; - -static int g729_read_header(AVFormatContext *s) -{ - AVStream* st; - G729DemuxerContext *s1 = s->priv_data; - - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = AV_CODEC_ID_G729; - st->codec->sample_rate = 8000; - st->codec->channels = 1; - - if (s1 && s1->bit_rate) { - s->bit_rate = s1->bit_rate; - } - - if (s->bit_rate == 0) { - av_log(s, AV_LOG_DEBUG, "No bitrate specified. Assuming 8000 b/s\n"); - s->bit_rate = 8000; - } - - if (s->bit_rate == 6400) { - st->codec->block_align = 8; - } else if (s->bit_rate == 8000) { - st->codec->block_align = 10; - } else { - av_log(s, AV_LOG_ERROR, "Only 8000 b/s and 6400 b/s bitrates are supported. Provided: %d b/s\n", s->bit_rate); - return AVERROR_INVALIDDATA; - } - - avpriv_set_pts_info(st, st->codec->block_align << 3, 1, st->codec->sample_rate); - return 0; -} -static int g729_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - int ret; - - ret = av_get_packet(s->pb, pkt, s->streams[0]->codec->block_align); - - pkt->stream_index = 0; - if (ret < 0) - return ret; - - pkt->dts = pkt->pts = pkt->pos / s->streams[0]->codec->block_align; - - return ret; -} - -static const AVOption g729_options[] = { - { "bit_rate", "", offsetof(G729DemuxerContext, bit_rate), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM }, - { NULL }, -}; - -static const AVClass g729_demuxer_class = { - .class_name = "g729 demuxer", - .item_name = av_default_item_name, - .option = g729_options, - .version = LIBAVUTIL_VERSION_INT, -}; - -AVInputFormat ff_g729_demuxer = { - .name = "g729", - .long_name = NULL_IF_CONFIG_SMALL("G.729 raw format demuxer"), - .priv_data_size = sizeof(G729DemuxerContext), - .read_header = g729_read_header, - .read_packet = g729_read_packet, - .flags = AVFMT_GENERIC_INDEX, - .extensions = "g729", - .priv_class = &g729_demuxer_class, -}; diff --git a/ffmpeg1/libavformat/gif.c b/ffmpeg1/libavformat/gif.c deleted file mode 100644 index 31b0101..0000000 --- a/ffmpeg1/libavformat/gif.c +++ /dev/null @@ -1,381 +0,0 @@ -/* - * Animated GIF 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 - */ - -/* - * First version by Francois Revol revol@free.fr - * - * Features and limitations: - * - currently no compression is performed, - * in fact the size of the data is 9/8 the size of the image in 8bpp - * - uses only a global standard palette - * - tested with IE 5.0, Opera for BeOS, NetPositive (BeOS), and Mozilla (BeOS). - * - * Reference documents: - * http://www.goice.co.jp/member/mo/formats/gif.html - * http://astronomy.swin.edu.au/pbourke/dataformats/gif/ - * http://www.dcs.ed.ac.uk/home/mxr/gfx/2d/GIF89a.txt - * - * this url claims to have an LZW algorithm not covered by Unisys patent: - * http://www.msg.net/utility/whirlgif/gifencod.html - * could help reduce the size of the files _a lot_... - * some sites mentions an RLE type compression also. - */ - -#include "avformat.h" -#include "libavutil/log.h" -#include "libavutil/opt.h" - -/* The GIF format uses reversed order for bitstreams... */ -/* at least they don't use PDP_ENDIAN :) */ -#define BITSTREAM_WRITER_LE - -#include "libavcodec/put_bits.h" - -/* bitstream minipacket size */ -#define GIF_CHUNKS 100 - -/* slows down the decoding (and some browsers don't like it) */ -/* update on the 'some browsers don't like it issue from above: - * this was probably due to missing 'Data Sub-block Terminator' - * (byte 19) in the app_header */ -#define GIF_ADD_APP_HEADER // required to enable looping of animated gif - -typedef struct { - unsigned char r; - unsigned char g; - unsigned char b; -} rgb_triplet; - -/* we use the standard 216 color palette */ - -/* this script was used to create the palette: - * for r in 00 33 66 99 cc ff; do - * for g in 00 33 66 99 cc ff; do - * echo -n " " - * for b in 00 33 66 99 cc ff; do - * echo -n "{ 0x$r, 0x$g, 0x$b }, " - * done - * echo "" - * done - * done - */ - -static const rgb_triplet gif_clut[216] = { - { 0x00, 0x00, 0x00 }, { 0x00, 0x00, 0x33 }, { 0x00, 0x00, 0x66 }, { 0x00, 0x00, 0x99 }, { 0x00, 0x00, 0xcc }, { 0x00, 0x00, 0xff }, - { 0x00, 0x33, 0x00 }, { 0x00, 0x33, 0x33 }, { 0x00, 0x33, 0x66 }, { 0x00, 0x33, 0x99 }, { 0x00, 0x33, 0xcc }, { 0x00, 0x33, 0xff }, - { 0x00, 0x66, 0x00 }, { 0x00, 0x66, 0x33 }, { 0x00, 0x66, 0x66 }, { 0x00, 0x66, 0x99 }, { 0x00, 0x66, 0xcc }, { 0x00, 0x66, 0xff }, - { 0x00, 0x99, 0x00 }, { 0x00, 0x99, 0x33 }, { 0x00, 0x99, 0x66 }, { 0x00, 0x99, 0x99 }, { 0x00, 0x99, 0xcc }, { 0x00, 0x99, 0xff }, - { 0x00, 0xcc, 0x00 }, { 0x00, 0xcc, 0x33 }, { 0x00, 0xcc, 0x66 }, { 0x00, 0xcc, 0x99 }, { 0x00, 0xcc, 0xcc }, { 0x00, 0xcc, 0xff }, - { 0x00, 0xff, 0x00 }, { 0x00, 0xff, 0x33 }, { 0x00, 0xff, 0x66 }, { 0x00, 0xff, 0x99 }, { 0x00, 0xff, 0xcc }, { 0x00, 0xff, 0xff }, - { 0x33, 0x00, 0x00 }, { 0x33, 0x00, 0x33 }, { 0x33, 0x00, 0x66 }, { 0x33, 0x00, 0x99 }, { 0x33, 0x00, 0xcc }, { 0x33, 0x00, 0xff }, - { 0x33, 0x33, 0x00 }, { 0x33, 0x33, 0x33 }, { 0x33, 0x33, 0x66 }, { 0x33, 0x33, 0x99 }, { 0x33, 0x33, 0xcc }, { 0x33, 0x33, 0xff }, - { 0x33, 0x66, 0x00 }, { 0x33, 0x66, 0x33 }, { 0x33, 0x66, 0x66 }, { 0x33, 0x66, 0x99 }, { 0x33, 0x66, 0xcc }, { 0x33, 0x66, 0xff }, - { 0x33, 0x99, 0x00 }, { 0x33, 0x99, 0x33 }, { 0x33, 0x99, 0x66 }, { 0x33, 0x99, 0x99 }, { 0x33, 0x99, 0xcc }, { 0x33, 0x99, 0xff }, - { 0x33, 0xcc, 0x00 }, { 0x33, 0xcc, 0x33 }, { 0x33, 0xcc, 0x66 }, { 0x33, 0xcc, 0x99 }, { 0x33, 0xcc, 0xcc }, { 0x33, 0xcc, 0xff }, - { 0x33, 0xff, 0x00 }, { 0x33, 0xff, 0x33 }, { 0x33, 0xff, 0x66 }, { 0x33, 0xff, 0x99 }, { 0x33, 0xff, 0xcc }, { 0x33, 0xff, 0xff }, - { 0x66, 0x00, 0x00 }, { 0x66, 0x00, 0x33 }, { 0x66, 0x00, 0x66 }, { 0x66, 0x00, 0x99 }, { 0x66, 0x00, 0xcc }, { 0x66, 0x00, 0xff }, - { 0x66, 0x33, 0x00 }, { 0x66, 0x33, 0x33 }, { 0x66, 0x33, 0x66 }, { 0x66, 0x33, 0x99 }, { 0x66, 0x33, 0xcc }, { 0x66, 0x33, 0xff }, - { 0x66, 0x66, 0x00 }, { 0x66, 0x66, 0x33 }, { 0x66, 0x66, 0x66 }, { 0x66, 0x66, 0x99 }, { 0x66, 0x66, 0xcc }, { 0x66, 0x66, 0xff }, - { 0x66, 0x99, 0x00 }, { 0x66, 0x99, 0x33 }, { 0x66, 0x99, 0x66 }, { 0x66, 0x99, 0x99 }, { 0x66, 0x99, 0xcc }, { 0x66, 0x99, 0xff }, - { 0x66, 0xcc, 0x00 }, { 0x66, 0xcc, 0x33 }, { 0x66, 0xcc, 0x66 }, { 0x66, 0xcc, 0x99 }, { 0x66, 0xcc, 0xcc }, { 0x66, 0xcc, 0xff }, - { 0x66, 0xff, 0x00 }, { 0x66, 0xff, 0x33 }, { 0x66, 0xff, 0x66 }, { 0x66, 0xff, 0x99 }, { 0x66, 0xff, 0xcc }, { 0x66, 0xff, 0xff }, - { 0x99, 0x00, 0x00 }, { 0x99, 0x00, 0x33 }, { 0x99, 0x00, 0x66 }, { 0x99, 0x00, 0x99 }, { 0x99, 0x00, 0xcc }, { 0x99, 0x00, 0xff }, - { 0x99, 0x33, 0x00 }, { 0x99, 0x33, 0x33 }, { 0x99, 0x33, 0x66 }, { 0x99, 0x33, 0x99 }, { 0x99, 0x33, 0xcc }, { 0x99, 0x33, 0xff }, - { 0x99, 0x66, 0x00 }, { 0x99, 0x66, 0x33 }, { 0x99, 0x66, 0x66 }, { 0x99, 0x66, 0x99 }, { 0x99, 0x66, 0xcc }, { 0x99, 0x66, 0xff }, - { 0x99, 0x99, 0x00 }, { 0x99, 0x99, 0x33 }, { 0x99, 0x99, 0x66 }, { 0x99, 0x99, 0x99 }, { 0x99, 0x99, 0xcc }, { 0x99, 0x99, 0xff }, - { 0x99, 0xcc, 0x00 }, { 0x99, 0xcc, 0x33 }, { 0x99, 0xcc, 0x66 }, { 0x99, 0xcc, 0x99 }, { 0x99, 0xcc, 0xcc }, { 0x99, 0xcc, 0xff }, - { 0x99, 0xff, 0x00 }, { 0x99, 0xff, 0x33 }, { 0x99, 0xff, 0x66 }, { 0x99, 0xff, 0x99 }, { 0x99, 0xff, 0xcc }, { 0x99, 0xff, 0xff }, - { 0xcc, 0x00, 0x00 }, { 0xcc, 0x00, 0x33 }, { 0xcc, 0x00, 0x66 }, { 0xcc, 0x00, 0x99 }, { 0xcc, 0x00, 0xcc }, { 0xcc, 0x00, 0xff }, - { 0xcc, 0x33, 0x00 }, { 0xcc, 0x33, 0x33 }, { 0xcc, 0x33, 0x66 }, { 0xcc, 0x33, 0x99 }, { 0xcc, 0x33, 0xcc }, { 0xcc, 0x33, 0xff }, - { 0xcc, 0x66, 0x00 }, { 0xcc, 0x66, 0x33 }, { 0xcc, 0x66, 0x66 }, { 0xcc, 0x66, 0x99 }, { 0xcc, 0x66, 0xcc }, { 0xcc, 0x66, 0xff }, - { 0xcc, 0x99, 0x00 }, { 0xcc, 0x99, 0x33 }, { 0xcc, 0x99, 0x66 }, { 0xcc, 0x99, 0x99 }, { 0xcc, 0x99, 0xcc }, { 0xcc, 0x99, 0xff }, - { 0xcc, 0xcc, 0x00 }, { 0xcc, 0xcc, 0x33 }, { 0xcc, 0xcc, 0x66 }, { 0xcc, 0xcc, 0x99 }, { 0xcc, 0xcc, 0xcc }, { 0xcc, 0xcc, 0xff }, - { 0xcc, 0xff, 0x00 }, { 0xcc, 0xff, 0x33 }, { 0xcc, 0xff, 0x66 }, { 0xcc, 0xff, 0x99 }, { 0xcc, 0xff, 0xcc }, { 0xcc, 0xff, 0xff }, - { 0xff, 0x00, 0x00 }, { 0xff, 0x00, 0x33 }, { 0xff, 0x00, 0x66 }, { 0xff, 0x00, 0x99 }, { 0xff, 0x00, 0xcc }, { 0xff, 0x00, 0xff }, - { 0xff, 0x33, 0x00 }, { 0xff, 0x33, 0x33 }, { 0xff, 0x33, 0x66 }, { 0xff, 0x33, 0x99 }, { 0xff, 0x33, 0xcc }, { 0xff, 0x33, 0xff }, - { 0xff, 0x66, 0x00 }, { 0xff, 0x66, 0x33 }, { 0xff, 0x66, 0x66 }, { 0xff, 0x66, 0x99 }, { 0xff, 0x66, 0xcc }, { 0xff, 0x66, 0xff }, - { 0xff, 0x99, 0x00 }, { 0xff, 0x99, 0x33 }, { 0xff, 0x99, 0x66 }, { 0xff, 0x99, 0x99 }, { 0xff, 0x99, 0xcc }, { 0xff, 0x99, 0xff }, - { 0xff, 0xcc, 0x00 }, { 0xff, 0xcc, 0x33 }, { 0xff, 0xcc, 0x66 }, { 0xff, 0xcc, 0x99 }, { 0xff, 0xcc, 0xcc }, { 0xff, 0xcc, 0xff }, - { 0xff, 0xff, 0x00 }, { 0xff, 0xff, 0x33 }, { 0xff, 0xff, 0x66 }, { 0xff, 0xff, 0x99 }, { 0xff, 0xff, 0xcc }, { 0xff, 0xff, 0xff }, -}; - -/* GIF header */ -static int gif_image_write_header(AVIOContext *pb, int width, int height, - int loop_count, uint32_t *palette) -{ - int i; - unsigned int v; - - avio_write(pb, "GIF", 3); - avio_write(pb, "89a", 3); - avio_wl16(pb, width); - avio_wl16(pb, height); - - avio_w8(pb, 0xf7); /* flags: global clut, 256 entries */ - avio_w8(pb, 0x1f); /* background color index */ - avio_w8(pb, 0); /* aspect ratio */ - - /* the global palette */ - if (!palette) { - avio_write(pb, (const unsigned char *)gif_clut, 216 * 3); - for (i = 0; i < ((256 - 216) * 3); i++) - avio_w8(pb, 0); - } else { - for (i = 0; i < 256; i++) { - v = palette[i]; - avio_w8(pb, (v >> 16) & 0xff); - avio_w8(pb, (v >> 8) & 0xff); - avio_w8(pb, (v) & 0xff); - } - } - - /* update: this is the 'NETSCAPE EXTENSION' that allows for looped animated - * GIF, see http://members.aol.com/royalef/gifabout.htm#net-extension - * - * byte 1 : 33 (hex 0x21) GIF Extension code - * byte 2 : 255 (hex 0xFF) Application Extension Label - * byte 3 : 11 (hex (0x0B) Length of Application Block - * (eleven bytes of data to follow) - * bytes 4 to 11 : "NETSCAPE" - * bytes 12 to 14 : "2.0" - * byte 15 : 3 (hex 0x03) Length of Data Sub-Block - * (three bytes of data to follow) - * byte 16 : 1 (hex 0x01) - * bytes 17 to 18 : 0 to 65535, an unsigned integer in - * lo-hi byte format. This indicate the - * number of iterations the loop should - * be executed. - * bytes 19 : 0 (hex 0x00) a Data Sub-block Terminator - */ - - /* application extension header */ -#ifdef GIF_ADD_APP_HEADER - if (loop_count >= 0 && loop_count <= 65535) { - avio_w8(pb, 0x21); - avio_w8(pb, 0xff); - avio_w8(pb, 0x0b); - // bytes 4 to 14 - avio_write(pb, "NETSCAPE2.0", sizeof("NETSCAPE2.0") - 1); - avio_w8(pb, 0x03); // byte 15 - avio_w8(pb, 0x01); // byte 16 - avio_wl16(pb, (uint16_t)loop_count); - avio_w8(pb, 0x00); // byte 19 - } -#endif - return 0; -} - -/* this is maybe slow, but allows for extensions */ -static inline unsigned char gif_clut_index(uint8_t r, uint8_t g, uint8_t b) -{ - return (((r) / 47) % 6) * 6 * 6 + (((g) / 47) % 6) * 6 + (((b) / 47) % 6); -} - -static int gif_image_write_image(AVIOContext *pb, - int x1, int y1, int width, int height, - const uint8_t *buf, int linesize, int pix_fmt) -{ - PutBitContext p; - uint8_t buffer[200]; /* 100 * 9 / 8 = 113 */ - int i, left, w, v; - const uint8_t *ptr; - /* image block */ - - avio_w8(pb, 0x2c); - avio_wl16(pb, x1); - avio_wl16(pb, y1); - avio_wl16(pb, width); - avio_wl16(pb, height); - avio_w8(pb, 0x00); /* flags */ - /* no local clut */ - - avio_w8(pb, 0x08); - - left = width * height; - - init_put_bits(&p, buffer, 130); - -/* - * the thing here is the bitstream is written as little packets, with a size - * byte before but it's still the same bitstream between packets (no flush !) - */ - ptr = buf; - w = width; - while (left > 0) { - put_bits(&p, 9, 0x0100); /* clear code */ - - for (i = (left < GIF_CHUNKS) ? left : GIF_CHUNKS; i; i--) { - if (pix_fmt == AV_PIX_FMT_RGB24) { - v = gif_clut_index(ptr[0], ptr[1], ptr[2]); - ptr += 3; - } else { - v = *ptr++; - } - put_bits(&p, 9, v); - if (--w == 0) { - w = width; - buf += linesize; - ptr = buf; - } - } - - if (left <= GIF_CHUNKS) { - put_bits(&p, 9, 0x101); /* end of stream */ - flush_put_bits(&p); - } - if (put_bits_ptr(&p) - p.buf > 0) { - avio_w8(pb, put_bits_ptr(&p) - p.buf); /* byte count of the packet */ - avio_write(pb, p.buf, put_bits_ptr(&p) - p.buf); /* the actual buffer */ - p.buf_ptr = p.buf; /* dequeue the bytes off the bitstream */ - } - left -= GIF_CHUNKS; - } - avio_w8(pb, 0x00); /* end of image block */ - - return 0; -} - -typedef struct { - AVClass *class; /** Class for private options. */ - int64_t time, file_time; - uint8_t buffer[100]; /* data chunks */ - int loop; -} GIFContext; - -static int gif_write_header(AVFormatContext *s) -{ - GIFContext *gif = s->priv_data; - AVIOContext *pb = s->pb; - AVCodecContext *enc, *video_enc; - int i, width, height /*, rate*/; - -/* XXX: do we reject audio streams or just ignore them ? - * if (s->nb_streams > 1) - * return -1; - */ - gif->time = 0; - gif->file_time = 0; - - video_enc = NULL; - for (i = 0; i < s->nb_streams; i++) { - enc = s->streams[i]->codec; - if (enc->codec_type != AVMEDIA_TYPE_AUDIO) - video_enc = enc; - } - - if (!video_enc) { - av_free(gif); - return -1; - } else { - width = video_enc->width; - height = video_enc->height; -// rate = video_enc->time_base.den; - } - - if (video_enc->pix_fmt != AV_PIX_FMT_RGB24) { - av_log(s, AV_LOG_ERROR, - "ERROR: gif only handles the rgb24 pixel format. Use -pix_fmt rgb24.\n"); - return AVERROR(EIO); - } - - gif_image_write_header(pb, width, height, gif->loop, NULL); - - avio_flush(s->pb); - return 0; -} - -static int gif_write_video(AVFormatContext *s, AVCodecContext *enc, - const uint8_t *buf, int size) -{ - AVIOContext *pb = s->pb; - int jiffies; - - /* graphic control extension block */ - avio_w8(pb, 0x21); - avio_w8(pb, 0xf9); - avio_w8(pb, 0x04); /* block size */ - avio_w8(pb, 0x04); /* flags */ - - /* 1 jiffy is 1/70 s */ - /* the delay_time field indicates the number of jiffies - 1 */ - /* XXX: should use delay, in order to be more accurate */ - /* instead of using the same rounded value each time */ - /* XXX: don't even remember if I really use it for now */ - jiffies = (70 * enc->time_base.num / enc->time_base.den) - 1; - - avio_wl16(pb, jiffies); - - avio_w8(pb, 0x1f); /* transparent color index */ - avio_w8(pb, 0x00); - - gif_image_write_image(pb, 0, 0, enc->width, enc->height, - buf, enc->width * 3, AV_PIX_FMT_RGB24); - - avio_flush(s->pb); - return 0; -} - -static int gif_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - AVCodecContext *codec = s->streams[pkt->stream_index]->codec; - if (codec->codec_type == AVMEDIA_TYPE_AUDIO) - return 0; /* just ignore audio */ - else - return gif_write_video(s, codec, pkt->data, pkt->size); -} - -static int gif_write_trailer(AVFormatContext *s) -{ - AVIOContext *pb = s->pb; - - avio_w8(pb, 0x3b); - - return 0; -} - -#define OFFSET(x) offsetof(GIFContext, x) -#define ENC AV_OPT_FLAG_ENCODING_PARAM -static const AVOption options[] = { - { "loop", "Number of times to loop the output.", OFFSET(loop), - AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 65535, ENC }, - { NULL }, -}; - -static const AVClass gif_muxer_class = { - .class_name = "GIF muxer", - .item_name = av_default_item_name, - .version = LIBAVUTIL_VERSION_INT, - .option = options, -}; - -AVOutputFormat ff_gif_muxer = { - .name = "gif", - .long_name = NULL_IF_CONFIG_SMALL("GIF Animation"), - .mime_type = "image/gif", - .extensions = "gif", - .priv_data_size = sizeof(GIFContext), - .audio_codec = AV_CODEC_ID_NONE, - .video_codec = AV_CODEC_ID_RAWVIDEO, - .write_header = gif_write_header, - .write_packet = gif_write_packet, - .write_trailer = gif_write_trailer, - .priv_class = &gif_muxer_class, -}; diff --git a/ffmpeg1/libavformat/gifdec.c b/ffmpeg1/libavformat/gifdec.c deleted file mode 100644 index 1122849..0000000 --- a/ffmpeg1/libavformat/gifdec.c +++ /dev/null @@ -1,302 +0,0 @@ -/* - * GIF demuxer - * Copyright (c) 2012 Vitaliy E Sugrobov - * - * 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 - */ - -/** - * @file - * GIF demuxer. - */ - -#include "avformat.h" -#include "libavutil/intreadwrite.h" -#include "libavutil/opt.h" -#include "internal.h" -#include "libavcodec/gif.h" - -typedef struct GIFDemuxContext { - const AVClass *class; - /** - * Time span in hundredths of second before - * the next frame should be drawn on screen. - */ - int delay; - /** - * Minimum allowed delay between frames in hundredths of - * second. Values below this threshold considered to be - * invalid and set to value of default_delay. - */ - int min_delay; - int default_delay; -} GIFDemuxContext; - -/** - * Major web browsers display gifs at ~10-15fps when rate - * is not explicitly set or have too low values. We assume default rate to be 10. - * Default delay = 100hundredths of second / 10fps = 10hos per frame. - */ -#define GIF_DEFAULT_DELAY 10 -/** - * By default delay values less than this threshold considered to be invalid. - */ -#define GIF_MIN_DELAY 2 - -static int gif_probe(AVProbeData *p) -{ - /* check magick */ - if (memcmp(p->buf, gif87a_sig, 6) && memcmp(p->buf, gif89a_sig, 6)) - return 0; - - /* width or height contains zero? */ - if (!AV_RL16(&p->buf[6]) || !AV_RL16(&p->buf[8])) - return 0; - - return AVPROBE_SCORE_MAX; -} - -static int resync(AVIOContext *pb) -{ - int i; - for (i = 0; i < 6; i++) { - int b = avio_r8(pb); - if (b != gif87a_sig[i] && b != gif89a_sig[i]) - i = -(b != 'G'); - if (url_feof(pb)) - return AVERROR_EOF; - } - return 0; -} - -static int gif_read_header(AVFormatContext *s) -{ - GIFDemuxContext *gdc = s->priv_data; - AVIOContext *pb = s->pb; - AVStream *st; - int width, height, ret; - - if ((ret = resync(pb)) < 0) - return ret; - - gdc->delay = gdc->default_delay; - width = avio_rl16(pb); - height = avio_rl16(pb); - - if (width == 0 || height == 0) - return AVERROR_INVALIDDATA; - - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - - /* GIF format operates with time in "hundredths of second", - * therefore timebase is 1/100 */ - avpriv_set_pts_info(st, 64, 1, 100); - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = AV_CODEC_ID_GIF; - st->codec->width = width; - st->codec->height = height; - - /* jump to start because gif decoder needs header data too */ - if (avio_seek(pb, 0, SEEK_SET) != 0) - return AVERROR(EIO); - - return 0; -} - -static int gif_skip_subblocks(AVIOContext *pb) -{ - int sb_size, ret = 0; - - while (0x00 != (sb_size = avio_r8(pb))) { - if ((ret = avio_skip(pb, sb_size)) < 0) - return ret; - } - - return ret; -} - -static int gif_read_ext(AVFormatContext *s) -{ - GIFDemuxContext *gdc = s->priv_data; - AVIOContext *pb = s->pb; - int sb_size, ext_label = avio_r8(pb); - int ret; - - if (ext_label == GIF_GCE_EXT_LABEL) { - if ((sb_size = avio_r8(pb)) < 4) { - av_log(s, AV_LOG_FATAL, "Graphic Control Extension block's size less than 4.\n"); - return AVERROR_INVALIDDATA; - } - - /* skip packed fields */ - if ((ret = avio_skip(pb, 1)) < 0) - return ret; - - gdc->delay = avio_rl16(pb); - - if (gdc->delay < gdc->min_delay) - gdc->delay = gdc->default_delay; - - /* skip the rest of the Graphic Control Extension block */ - if ((ret = avio_skip(pb, sb_size - 3)) < 0 ) - return ret; - } - - if ((ret = gif_skip_subblocks(pb)) < 0) - return ret; - - return 0; -} - -static int gif_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - GIFDemuxContext *gdc = s->priv_data; - AVIOContext *pb = s->pb; - int packed_fields, block_label, ct_size, - keyframe, frame_parsed = 0, ret; - int64_t frame_start = avio_tell(pb), frame_end; - unsigned char buf[6]; - - if ((ret = avio_read(pb, buf, 6)) == 6) { - keyframe = memcmp(buf, gif87a_sig, 6) == 0 || - memcmp(buf, gif89a_sig, 6) == 0; - } else if (ret < 0) { - return ret; - } else { - keyframe = 0; - } - - if (keyframe) { -parse_keyframe: - /* skip 2 bytes of width and 2 of height */ - if ((ret = avio_skip(pb, 4)) < 0) - return ret; - - packed_fields = avio_r8(pb); - - /* skip 1 byte of Background Color Index and 1 byte of Pixel Aspect Ratio */ - if ((ret = avio_skip(pb, 2)) < 0) - return ret; - - /* global color table presence */ - if (packed_fields & 0x80) { - ct_size = 3 * (1 << ((packed_fields & 0x07) + 1)); - - if ((ret = avio_skip(pb, ct_size)) < 0) - return ret; - } - } else { - avio_seek(pb, -ret, SEEK_CUR); - ret = AVERROR_EOF; - } - - while (GIF_TRAILER != (block_label = avio_r8(pb)) && !url_feof(pb)) { - if (block_label == GIF_EXTENSION_INTRODUCER) { - if ((ret = gif_read_ext (s)) < 0 ) - goto resync; - } else if (block_label == GIF_IMAGE_SEPARATOR) { - /* skip to last byte of Image Descriptor header */ - if ((ret = avio_skip(pb, 8)) < 0) - return ret; - - packed_fields = avio_r8(pb); - - /* local color table presence */ - if (packed_fields & 0x80) { - ct_size = 3 * (1 << ((packed_fields & 0x07) + 1)); - - if ((ret = avio_skip(pb, ct_size)) < 0) - return ret; - } - - /* read LZW Minimum Code Size */ - if (avio_r8(pb) < 1) { - av_log(s, AV_LOG_ERROR, "lzw minimum code size must be >= 1\n"); - goto resync; - } - - if ((ret = gif_skip_subblocks(pb)) < 0) - goto resync; - - frame_end = avio_tell(pb); - - if (avio_seek(pb, frame_start, SEEK_SET) != frame_start) - return AVERROR(EIO); - - ret = av_get_packet(pb, pkt, frame_end - frame_start); - if (ret < 0) - return ret; - - if (keyframe) - pkt->flags |= AV_PKT_FLAG_KEY; - - pkt->stream_index = 0; - pkt->duration = gdc->delay; - - /* Graphic Control Extension's scope is single frame. - * Remove its influence. */ - gdc->delay = gdc->default_delay; - frame_parsed = 1; - - break; - } else { - av_log(s, AV_LOG_ERROR, "invalid block label\n"); -resync: - if (!keyframe) - avio_seek(pb, frame_start, SEEK_SET); - if ((ret = resync(pb)) < 0) - return ret; - frame_start = avio_tell(pb) - 6; - keyframe = 1; - goto parse_keyframe; - } - } - - if (ret >= 0 && !frame_parsed) { - /* This might happen when there is no image block - * between extension blocks and GIF_TRAILER or EOF */ - return AVERROR_EOF; - } else - return ret; -} - -static const AVOption options[] = { - { "min_delay" , "minimum valid delay between frames (in hundredths of second)", offsetof(GIFDemuxContext, min_delay) , AV_OPT_TYPE_INT, {.i64 = GIF_MIN_DELAY} , 0, 100 * 60, AV_OPT_FLAG_DECODING_PARAM }, - { "default_delay", "default delay between frames (in hundredths of second)" , offsetof(GIFDemuxContext, default_delay), AV_OPT_TYPE_INT, {.i64 = GIF_DEFAULT_DELAY}, 0, 100 * 60, AV_OPT_FLAG_DECODING_PARAM }, - { NULL }, -}; - -static const AVClass demuxer_class = { - .class_name = "GIF demuxer", - .item_name = av_default_item_name, - .option = options, - .version = LIBAVUTIL_VERSION_INT, - .category = AV_CLASS_CATEGORY_DEMUXER, -}; - -AVInputFormat ff_gif_demuxer = { - .name = "gif", - .long_name = NULL_IF_CONFIG_SMALL("CompuServe Graphics Interchange Format (GIF)"), - .priv_data_size = sizeof(GIFDemuxContext), - .read_probe = gif_probe, - .read_header = gif_read_header, - .read_packet = gif_read_packet, - .flags = AVFMT_GENERIC_INDEX, - .priv_class = &demuxer_class, -}; diff --git a/ffmpeg1/libavformat/gopher.c b/ffmpeg1/libavformat/gopher.c deleted file mode 100644 index 9dc155a..0000000 --- a/ffmpeg1/libavformat/gopher.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Gopher protocol - * - * Copyright (c) 2009 Toshimitsu Kimura - * - * based on libavformat/http.c, Copyright (c) 2000, 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 - */ - -#include "libavutil/avstring.h" -#include "avformat.h" -#include "internal.h" -#include "network.h" -#include "url.h" - -typedef struct { - URLContext *hd; -} GopherContext; - -static int gopher_write(URLContext *h, const uint8_t *buf, int size) -{ - GopherContext *s = h->priv_data; - return ffurl_write(s->hd, buf, size); -} - -static int gopher_connect(URLContext *h, const char *path) -{ - char buffer[1024]; - - if (!*path) return AVERROR(EINVAL); - switch (*++path) { - case '5': - case '9': - path = strchr(path, '/'); - if (!path) return AVERROR(EINVAL); - break; - default: - av_log(h, AV_LOG_WARNING, - "Gopher protocol type '%c' not supported yet!\n", - *path); - return AVERROR(EINVAL); - } - - /* send gopher sector */ - snprintf(buffer, sizeof(buffer), "%s\r\n", path); - - if (gopher_write(h, buffer, strlen(buffer)) < 0) - return AVERROR(EIO); - - return 0; -} - -static int gopher_close(URLContext *h) -{ - GopherContext *s = h->priv_data; - if (s->hd) { - ffurl_close(s->hd); - s->hd = NULL; - } - return 0; -} - -static int gopher_open(URLContext *h, const char *uri, int flags) -{ - GopherContext *s = h->priv_data; - char hostname[1024], auth[1024], path[1024], buf[1024]; - int port, err; - - h->is_streamed = 1; - - /* needed in any case to build the host string */ - av_url_split(NULL, 0, auth, sizeof(auth), hostname, sizeof(hostname), &port, - path, sizeof(path), uri); - - if (port < 0) - port = 70; - - ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, NULL); - - s->hd = NULL; - err = ffurl_open(&s->hd, buf, AVIO_FLAG_READ_WRITE, - &h->interrupt_callback, NULL); - if (err < 0) - goto fail; - - if ((err = gopher_connect(h, path)) < 0) - goto fail; - return 0; - fail: - gopher_close(h); - return err; -} - -static int gopher_read(URLContext *h, uint8_t *buf, int size) -{ - GopherContext *s = h->priv_data; - int len = ffurl_read(s->hd, buf, size); - return len; -} - - -URLProtocol ff_gopher_protocol = { - .name = "gopher", - .url_open = gopher_open, - .url_read = gopher_read, - .url_write = gopher_write, - .url_close = gopher_close, - .priv_data_size = sizeof(GopherContext), - .flags = URL_PROTOCOL_FLAG_NETWORK, -}; diff --git a/ffmpeg1/libavformat/gsmdec.c b/ffmpeg1/libavformat/gsmdec.c deleted file mode 100644 index 9899266..0000000 --- a/ffmpeg1/libavformat/gsmdec.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * RAW GSM demuxer - * Copyright (c) 2011 Justin Ruggles - * - * 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 - */ - -#include "libavutil/channel_layout.h" -#include "libavutil/mathematics.h" -#include "libavutil/opt.h" -#include "avformat.h" -#include "internal.h" - -#define GSM_BLOCK_SIZE 33 -#define GSM_BLOCK_SAMPLES 160 -#define GSM_SAMPLE_RATE 8000 - -typedef struct { - AVClass *class; - int sample_rate; -} GSMDemuxerContext; - -static int gsm_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - int ret, size; - - size = GSM_BLOCK_SIZE; - - pkt->pos = avio_tell(s->pb); - pkt->stream_index = 0; - - ret = av_get_packet(s->pb, pkt, size); - if (ret < GSM_BLOCK_SIZE) { - av_free_packet(pkt); - return ret < 0 ? ret : AVERROR(EIO); - } - pkt->duration = 1; - pkt->pts = pkt->pos / GSM_BLOCK_SIZE; - - return 0; -} - -static int gsm_read_header(AVFormatContext *s) -{ - GSMDemuxerContext *c = s->priv_data; - AVStream *st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = s->iformat->raw_codec_id; - st->codec->channels = 1; - st->codec->channel_layout = AV_CH_LAYOUT_MONO; - st->codec->sample_rate = c->sample_rate; - st->codec->bit_rate = GSM_BLOCK_SIZE * 8 * c->sample_rate / GSM_BLOCK_SAMPLES; - - avpriv_set_pts_info(st, 64, GSM_BLOCK_SAMPLES, GSM_SAMPLE_RATE); - - return 0; -} - -static const AVOption options[] = { - { "sample_rate", "", offsetof(GSMDemuxerContext, sample_rate), - AV_OPT_TYPE_INT, {.i64 = GSM_SAMPLE_RATE}, 1, INT_MAX / GSM_BLOCK_SIZE, - AV_OPT_FLAG_DECODING_PARAM }, - { NULL }, -}; - -static const AVClass class = { - .class_name = "gsm demuxer", - .item_name = av_default_item_name, - .option = options, - .version = LIBAVUTIL_VERSION_INT, -}; - -AVInputFormat ff_gsm_demuxer = { - .name = "gsm", - .long_name = NULL_IF_CONFIG_SMALL("raw GSM"), - .priv_data_size = sizeof(GSMDemuxerContext), - .read_header = gsm_read_header, - .read_packet = gsm_read_packet, - .flags = AVFMT_GENERIC_INDEX, - .extensions = "gsm", - .raw_codec_id = AV_CODEC_ID_GSM, - .priv_class = &class, -}; diff --git a/ffmpeg1/libavformat/gxf.c b/ffmpeg1/libavformat/gxf.c deleted file mode 100644 index 86e6291..0000000 --- a/ffmpeg1/libavformat/gxf.c +++ /dev/null @@ -1,596 +0,0 @@ -/* - * GXF demuxer. - * Copyright (c) 2006 Reimar Doeffinger - * - * 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 "libavutil/channel_layout.h" -#include "libavutil/common.h" -#include "avformat.h" -#include "internal.h" -#include "gxf.h" -#include "libavcodec/mpeg12data.h" - -struct gxf_stream_info { - int64_t first_field; - int64_t last_field; - AVRational frames_per_second; - int32_t fields_per_frame; - int64_t track_aux_data; -}; - -/** - * @brief parse gxf timecode and add it to metadata - */ -static int add_timecode_metadata(AVDictionary **pm, const char *key, uint32_t timecode, int fields_per_frame) -{ - char tmp[128]; - int field = timecode & 0xff; - int frame = fields_per_frame ? field / fields_per_frame : field; - int second = (timecode >> 8) & 0xff; - int minute = (timecode >> 16) & 0xff; - int hour = (timecode >> 24) & 0x1f; - int drop = (timecode >> 29) & 1; - // bit 30: color_frame, unused - // ignore invalid time code - if (timecode >> 31) - return 0; - snprintf(tmp, sizeof(tmp), "%02d:%02d:%02d%c%02d", - hour, minute, second, drop ? ';' : ':', frame); - return av_dict_set(pm, key, tmp, 0); -} - -/** - * @brief parses a packet header, extracting type and length - * @param pb AVIOContext to read header from - * @param type detected packet type is stored here - * @param length detected packet length, excluding header is stored here - * @return 0 if header not found or contains invalid data, 1 otherwise - */ -static int parse_packet_header(AVIOContext *pb, GXFPktType *type, int *length) { - if (avio_rb32(pb)) - return 0; - if (avio_r8(pb) != 1) - return 0; - *type = avio_r8(pb); - *length = avio_rb32(pb); - if ((*length >> 24) || *length < 16) - return 0; - *length -= 16; - if (avio_rb32(pb)) - return 0; - if (avio_r8(pb) != 0xe1) - return 0; - if (avio_r8(pb) != 0xe2) - return 0; - return 1; -} - -/** - * @brief check if file starts with a PKT_MAP header - */ -static int gxf_probe(AVProbeData *p) { - static const uint8_t startcode[] = {0, 0, 0, 0, 1, 0xbc}; // start with map packet - static const uint8_t endcode[] = {0, 0, 0, 0, 0xe1, 0xe2}; - if (!memcmp(p->buf, startcode, sizeof(startcode)) && - !memcmp(&p->buf[16 - sizeof(endcode)], endcode, sizeof(endcode))) - return AVPROBE_SCORE_MAX; - return 0; -} - -/** - * @brief gets the stream index for the track with the specified id, creates new - * stream if not found - * @param id id of stream to find / add - * @param format stream format identifier - */ -static int get_sindex(AVFormatContext *s, int id, int format) { - int i; - AVStream *st = NULL; - i = ff_find_stream_index(s, id); - if (i >= 0) - return i; - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - st->id = id; - switch (format) { - case 3: - case 4: - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = AV_CODEC_ID_MJPEG; - break; - case 13: - case 15: - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = AV_CODEC_ID_DVVIDEO; - break; - case 14: - case 16: - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = AV_CODEC_ID_DVVIDEO; - break; - case 11: - case 12: - case 20: - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = AV_CODEC_ID_MPEG2VIDEO; - st->need_parsing = AVSTREAM_PARSE_HEADERS; //get keyframe flag etc. - break; - case 22: - case 23: - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = AV_CODEC_ID_MPEG1VIDEO; - st->need_parsing = AVSTREAM_PARSE_HEADERS; //get keyframe flag etc. - break; - case 9: - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = AV_CODEC_ID_PCM_S24LE; - st->codec->channels = 1; - st->codec->channel_layout = AV_CH_LAYOUT_MONO; - st->codec->sample_rate = 48000; - st->codec->bit_rate = 3 * 1 * 48000 * 8; - st->codec->block_align = 3 * 1; - st->codec->bits_per_coded_sample = 24; - break; - case 10: - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = AV_CODEC_ID_PCM_S16LE; - st->codec->channels = 1; - st->codec->channel_layout = AV_CH_LAYOUT_MONO; - st->codec->sample_rate = 48000; - st->codec->bit_rate = 2 * 1 * 48000 * 8; - st->codec->block_align = 2 * 1; - st->codec->bits_per_coded_sample = 16; - break; - case 17: - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = AV_CODEC_ID_AC3; - st->codec->channels = 2; - st->codec->channel_layout = AV_CH_LAYOUT_STEREO; - st->codec->sample_rate = 48000; - break; - // timecode tracks: - case 7: - case 8: - case 24: - st->codec->codec_type = AVMEDIA_TYPE_DATA; - st->codec->codec_id = AV_CODEC_ID_NONE; - break; - default: - st->codec->codec_type = AVMEDIA_TYPE_UNKNOWN; - st->codec->codec_id = AV_CODEC_ID_NONE; - break; - } - return s->nb_streams - 1; -} - -/** - * @brief filters out interesting tags from material information. - * @param len length of tag section, will be adjusted to contain remaining bytes - * @param si struct to store collected information into - */ -static void gxf_material_tags(AVIOContext *pb, int *len, struct gxf_stream_info *si) { - si->first_field = AV_NOPTS_VALUE; - si->last_field = AV_NOPTS_VALUE; - while (*len >= 2) { - GXFMatTag tag = avio_r8(pb); - int tlen = avio_r8(pb); - *len -= 2; - if (tlen > *len) - return; - *len -= tlen; - if (tlen == 4) { - uint32_t value = avio_rb32(pb); - if (tag == MAT_FIRST_FIELD) - si->first_field = value; - else if (tag == MAT_LAST_FIELD) - si->last_field = value; - } else - avio_skip(pb, tlen); - } -} - -static const AVRational frame_rate_tab[] = { - { 60, 1}, - {60000, 1001}, - { 50, 1}, - { 30, 1}, - {30000, 1001}, - { 25, 1}, - { 24, 1}, - {24000, 1001}, - { 0, 0}, -}; - -/** - * @brief convert fps tag value to AVRational fps - * @param fps fps value from tag - * @return fps as AVRational, or 0 / 0 if unknown - */ -static AVRational fps_tag2avr(int32_t fps) { - if (fps < 1 || fps > 9) fps = 9; - return frame_rate_tab[fps - 1]; -} - -/** - * @brief convert UMF attributes flags to AVRational fps - * @param flags UMF flags to convert - * @return fps as AVRational, or 0 / 0 if unknown - */ -static AVRational fps_umf2avr(uint32_t flags) { - static const AVRational map[] = {{50, 1}, {60000, 1001}, {24, 1}, - {25, 1}, {30000, 1001}}; - int idx = av_log2((flags & 0x7c0) >> 6); - return map[idx]; -} - -/** - * @brief filters out interesting tags from track information. - * @param len length of tag section, will be adjusted to contain remaining bytes - * @param si struct to store collected information into - */ -static void gxf_track_tags(AVIOContext *pb, int *len, struct gxf_stream_info *si) { - si->frames_per_second = (AVRational){0, 0}; - si->fields_per_frame = 0; - si->track_aux_data = 0x80000000; - while (*len >= 2) { - GXFTrackTag tag = avio_r8(pb); - int tlen = avio_r8(pb); - *len -= 2; - if (tlen > *len) - return; - *len -= tlen; - if (tlen == 4) { - uint32_t value = avio_rb32(pb); - if (tag == TRACK_FPS) - si->frames_per_second = fps_tag2avr(value); - else if (tag == TRACK_FPF && (value == 1 || value == 2)) - si->fields_per_frame = value; - } else if (tlen == 8 && tag == TRACK_AUX) - si->track_aux_data = avio_rl64(pb); - else - avio_skip(pb, tlen); - } -} - -/** - * @brief read index from FLT packet into stream 0 av_index - */ -static void gxf_read_index(AVFormatContext *s, int pkt_len) { - AVIOContext *pb = s->pb; - AVStream *st; - uint32_t fields_per_map = avio_rl32(pb); - uint32_t map_cnt = avio_rl32(pb); - int i; - pkt_len -= 8; - if ((s->flags & AVFMT_FLAG_IGNIDX) || !s->streams) { - avio_skip(pb, pkt_len); - return; - } - st = s->streams[0]; - if (map_cnt > 1000) { - av_log(s, AV_LOG_ERROR, "too many index entries %u (%x)\n", map_cnt, map_cnt); - map_cnt = 1000; - } - if (pkt_len < 4 * map_cnt) { - av_log(s, AV_LOG_ERROR, "invalid index length\n"); - avio_skip(pb, pkt_len); - return; - } - pkt_len -= 4 * map_cnt; - av_add_index_entry(st, 0, 0, 0, 0, 0); - for (i = 0; i < map_cnt; i++) - av_add_index_entry(st, (uint64_t)avio_rl32(pb) * 1024, - i * (uint64_t)fields_per_map + 1, 0, 0, 0); - avio_skip(pb, pkt_len); -} - -static int gxf_header(AVFormatContext *s) { - AVIOContext *pb = s->pb; - GXFPktType pkt_type; - int map_len; - int len; - AVRational main_timebase = {0, 0}; - struct gxf_stream_info *si = s->priv_data; - int i; - if (!parse_packet_header(pb, &pkt_type, &map_len) || pkt_type != PKT_MAP) { - av_log(s, AV_LOG_ERROR, "map packet not found\n"); - return 0; - } - map_len -= 2; - if (avio_r8(pb) != 0x0e0 || avio_r8(pb) != 0xff) { - av_log(s, AV_LOG_ERROR, "unknown version or invalid map preamble\n"); - return 0; - } - map_len -= 2; - len = avio_rb16(pb); // length of material data section - if (len > map_len) { - av_log(s, AV_LOG_ERROR, "material data longer than map data\n"); - return 0; - } - map_len -= len; - gxf_material_tags(pb, &len, si); - avio_skip(pb, len); - map_len -= 2; - len = avio_rb16(pb); // length of track description - if (len > map_len) { - av_log(s, AV_LOG_ERROR, "track description longer than map data\n"); - return 0; - } - map_len -= len; - while (len > 0) { - int track_type, track_id, track_len; - AVStream *st; - int idx; - len -= 4; - track_type = avio_r8(pb); - track_id = avio_r8(pb); - track_len = avio_rb16(pb); - len -= track_len; - if (!(track_type & 0x80)) { - av_log(s, AV_LOG_ERROR, "invalid track type %x\n", track_type); - continue; - } - track_type &= 0x7f; - if ((track_id & 0xc0) != 0xc0) { - av_log(s, AV_LOG_ERROR, "invalid track id %x\n", track_id); - continue; - } - track_id &= 0x3f; - gxf_track_tags(pb, &track_len, si); - // check for timecode tracks - if (track_type == 7 || track_type == 8 || track_type == 24) { - add_timecode_metadata(&s->metadata, "timecode", - si->track_aux_data & 0xffffffff, - si->fields_per_frame); - - } - avio_skip(pb, track_len); - - idx = get_sindex(s, track_id, track_type); - if (idx < 0) continue; - st = s->streams[idx]; - if (!main_timebase.num || !main_timebase.den) { - main_timebase.num = si->frames_per_second.den; - main_timebase.den = si->frames_per_second.num * 2; - } - st->start_time = si->first_field; - if (si->first_field != AV_NOPTS_VALUE && si->last_field != AV_NOPTS_VALUE) - st->duration = si->last_field - si->first_field; - } - if (len < 0) - av_log(s, AV_LOG_ERROR, "invalid track description length specified\n"); - if (map_len) - avio_skip(pb, map_len); - if (!parse_packet_header(pb, &pkt_type, &len)) { - av_log(s, AV_LOG_ERROR, "sync lost in header\n"); - return -1; - } - if (pkt_type == PKT_FLT) { - gxf_read_index(s, len); - if (!parse_packet_header(pb, &pkt_type, &len)) { - av_log(s, AV_LOG_ERROR, "sync lost in header\n"); - return -1; - } - } - if (pkt_type == PKT_UMF) { - if (len >= 0x39) { - AVRational fps; - len -= 0x39; - avio_skip(pb, 5); // preamble - avio_skip(pb, 0x30); // payload description - fps = fps_umf2avr(avio_rl32(pb)); - if (!main_timebase.num || !main_timebase.den) { - av_log(s, AV_LOG_WARNING, "No FPS track tag, using UMF fps tag." - " This might give wrong results.\n"); - // this may not always be correct, but simply the best we can get - main_timebase.num = fps.den; - main_timebase.den = fps.num * 2; - } - - if (len >= 0x18) { - len -= 0x18; - avio_skip(pb, 0x10); - add_timecode_metadata(&s->metadata, "timecode_at_mark_in", - avio_rl32(pb), si->fields_per_frame); - add_timecode_metadata(&s->metadata, "timecode_at_mark_out", - avio_rl32(pb), si->fields_per_frame); - } - } else - av_log(s, AV_LOG_INFO, "UMF packet too short\n"); - } else - av_log(s, AV_LOG_INFO, "UMF packet missing\n"); - avio_skip(pb, len); - // set a fallback value, 60000/1001 is specified for audio-only files - // so use that regardless of why we do not know the video frame rate. - if (!main_timebase.num || !main_timebase.den) - main_timebase = (AVRational){1001, 60000}; - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - avpriv_set_pts_info(st, 32, main_timebase.num, main_timebase.den); - } - return 0; -} - -#define READ_ONE() \ - { \ - if (!max_interval-- || url_feof(pb)) \ - goto out; \ - tmp = tmp << 8 | avio_r8(pb); \ - } - -/** - * @brief resync the stream on the next media packet with specified properties - * @param max_interval how many bytes to search for matching packet at most - * @param track track id the media packet must belong to, -1 for any - * @param timestamp minimum timestamp (== field number) the packet must have, -1 for any - * @return timestamp of packet found - */ -static int64_t gxf_resync_media(AVFormatContext *s, uint64_t max_interval, int track, int timestamp) { - uint32_t tmp; - uint64_t last_pos; - uint64_t last_found_pos = 0; - int cur_track; - int64_t cur_timestamp = AV_NOPTS_VALUE; - int len; - AVIOContext *pb = s->pb; - GXFPktType type; - tmp = avio_rb32(pb); -start: - while (tmp) - READ_ONE(); - READ_ONE(); - if (tmp != 1) - goto start; - last_pos = avio_tell(pb); - if (avio_seek(pb, -5, SEEK_CUR) < 0) - goto out; - if (!parse_packet_header(pb, &type, &len) || type != PKT_MEDIA) { - if (avio_seek(pb, last_pos, SEEK_SET) < 0) - goto out; - goto start; - } - avio_r8(pb); - cur_track = avio_r8(pb); - cur_timestamp = avio_rb32(pb); - last_found_pos = avio_tell(pb) - 16 - 6; - if ((track >= 0 && track != cur_track) || (timestamp >= 0 && timestamp > cur_timestamp)) { - if (avio_seek(pb, last_pos, SEEK_SET) >= 0) - goto start; - } -out: - if (last_found_pos) - avio_seek(pb, last_found_pos, SEEK_SET); - return cur_timestamp; -} - -static int gxf_packet(AVFormatContext *s, AVPacket *pkt) { - AVIOContext *pb = s->pb; - GXFPktType pkt_type; - int pkt_len; - struct gxf_stream_info *si = s->priv_data; - - while (!pb->eof_reached) { - AVStream *st; - int track_type, track_id, ret; - int field_nr, field_info, skip = 0; - int stream_index; - if (!parse_packet_header(pb, &pkt_type, &pkt_len)) { - if (!url_feof(pb)) - av_log(s, AV_LOG_ERROR, "sync lost\n"); - return -1; - } - if (pkt_type == PKT_FLT) { - gxf_read_index(s, pkt_len); - continue; - } - if (pkt_type != PKT_MEDIA) { - avio_skip(pb, pkt_len); - continue; - } - if (pkt_len < 16) { - av_log(s, AV_LOG_ERROR, "invalid media packet length\n"); - continue; - } - pkt_len -= 16; - track_type = avio_r8(pb); - track_id = avio_r8(pb); - stream_index = get_sindex(s, track_id, track_type); - if (stream_index < 0) - return stream_index; - st = s->streams[stream_index]; - field_nr = avio_rb32(pb); - field_info = avio_rb32(pb); - avio_rb32(pb); // "timeline" field number - avio_r8(pb); // flags - avio_r8(pb); // reserved - if (st->codec->codec_id == AV_CODEC_ID_PCM_S24LE || - st->codec->codec_id == AV_CODEC_ID_PCM_S16LE) { - int first = field_info >> 16; - int last = field_info & 0xffff; // last is exclusive - int bps = av_get_bits_per_sample(st->codec->codec_id)>>3; - if (first <= last && last*bps <= pkt_len) { - avio_skip(pb, first*bps); - skip = pkt_len - last*bps; - pkt_len = (last-first)*bps; - } else - av_log(s, AV_LOG_ERROR, "invalid first and last sample values\n"); - } - ret = av_get_packet(pb, pkt, pkt_len); - if (skip) - avio_skip(pb, skip); - pkt->stream_index = stream_index; - pkt->dts = field_nr; - - //set duration manually for DV or else lavf misdetects the frame rate - if (st->codec->codec_id == AV_CODEC_ID_DVVIDEO) - pkt->duration = si->fields_per_frame; - - return ret; - } - return AVERROR_EOF; -} - -static int gxf_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) { - int res = 0; - uint64_t pos; - uint64_t maxlen = 100 * 1024 * 1024; - AVStream *st = s->streams[0]; - int64_t start_time = s->streams[stream_index]->start_time; - int64_t found; - int idx; - if (timestamp < start_time) timestamp = start_time; - idx = av_index_search_timestamp(st, timestamp - start_time, - AVSEEK_FLAG_ANY | AVSEEK_FLAG_BACKWARD); - if (idx < 0) - return -1; - pos = st->index_entries[idx].pos; - if (idx < st->nb_index_entries - 2) - maxlen = st->index_entries[idx + 2].pos - pos; - maxlen = FFMAX(maxlen, 200 * 1024); - res = avio_seek(s->pb, pos, SEEK_SET); - if (res < 0) - return res; - found = gxf_resync_media(s, maxlen, -1, timestamp); - if (FFABS(found - timestamp) > 4) - return -1; - return 0; -} - -static int64_t gxf_read_timestamp(AVFormatContext *s, int stream_index, - int64_t *pos, int64_t pos_limit) { - AVIOContext *pb = s->pb; - int64_t res; - if (avio_seek(pb, *pos, SEEK_SET) < 0) - return AV_NOPTS_VALUE; - res = gxf_resync_media(s, pos_limit - *pos, -1, -1); - *pos = avio_tell(pb); - return res; -} - -AVInputFormat ff_gxf_demuxer = { - .name = "gxf", - .long_name = NULL_IF_CONFIG_SMALL("GXF (General eXchange Format)"), - .priv_data_size = sizeof(struct gxf_stream_info), - .read_probe = gxf_probe, - .read_header = gxf_header, - .read_packet = gxf_packet, - .read_seek = gxf_seek, - .read_timestamp = gxf_read_timestamp, -}; diff --git a/ffmpeg1/libavformat/gxf.h b/ffmpeg1/libavformat/gxf.h deleted file mode 100644 index dcdcdef..0000000 --- a/ffmpeg1/libavformat/gxf.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * GXF demuxer - * copyright (c) 2006 Reimar Doeffinger - * - * 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 AVFORMAT_GXF_H -#define AVFORMAT_GXF_H - -typedef enum { - PKT_MAP = 0xbc, - PKT_MEDIA = 0xbf, - PKT_EOS = 0xfb, - PKT_FLT = 0xfc, - PKT_UMF = 0xfd, -} GXFPktType; - -typedef enum { - MAT_NAME = 0x40, - MAT_FIRST_FIELD = 0x41, - MAT_LAST_FIELD = 0x42, - MAT_MARK_IN = 0x43, - MAT_MARK_OUT = 0x44, - MAT_SIZE = 0x45, -} GXFMatTag; - -typedef enum { - TRACK_NAME = 0x4c, - TRACK_AUX = 0x4d, - TRACK_VER = 0x4e, - TRACK_MPG_AUX = 0x4f, - TRACK_FPS = 0x50, - TRACK_LINES = 0x51, - TRACK_FPF = 0x52, -} GXFTrackTag; - -#endif /* AVFORMAT_GXF_H */ diff --git a/ffmpeg1/libavformat/gxfenc.c b/ffmpeg1/libavformat/gxfenc.c deleted file mode 100644 index 28acb74..0000000 --- a/ffmpeg1/libavformat/gxfenc.c +++ /dev/null @@ -1,999 +0,0 @@ -/* - * GXF muxer. - * Copyright (c) 2006 SmartJog S.A., Baptiste Coudurier - * - * 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 "libavutil/avassert.h" -#include "libavutil/intfloat.h" -#include "libavutil/opt.h" -#include "libavutil/mathematics.h" -#include "libavutil/timecode.h" -#include "avformat.h" -#include "internal.h" -#include "gxf.h" -#include "audiointerleave.h" - -#define GXF_AUDIO_PACKET_SIZE 65536 - -#define GXF_TIMECODE(c, d, h, m, s, f) \ - ((c) << 30 | (d) << 29 | (h) << 24 | (m) << 16 | (s) << 8 | (f)) - -typedef struct GXFTimecode{ - int hh; - int mm; - int ss; - int ff; - int color; - int drop; -} GXFTimecode; - -typedef struct GXFStreamContext { - AudioInterleaveContext aic; - uint32_t track_type; - uint32_t sample_size; - uint32_t sample_rate; - uint16_t media_type; - uint16_t media_info; - int frame_rate_index; - int lines_index; - int fields; - int iframes; - int pframes; - int bframes; - int p_per_gop; - int b_per_i_or_p; ///< number of B frames per I frame or P frame - int first_gop_closed; - unsigned order; ///< interleaving order -} GXFStreamContext; - -typedef struct GXFContext { - AVClass *av_class; - uint32_t nb_fields; - uint16_t audio_tracks; - uint16_t mpeg_tracks; - int64_t creation_time; - uint32_t umf_start_offset; - uint32_t umf_track_offset; - uint32_t umf_media_offset; - uint32_t umf_length; - uint16_t umf_track_size; - uint16_t umf_media_size; - AVRational time_base; - int flags; - GXFStreamContext timecode_track; - unsigned *flt_entries; ///< offsets of packets /1024, starts after 2nd video field - unsigned flt_entries_nb; - uint64_t *map_offsets; ///< offset of map packets - unsigned map_offsets_nb; - unsigned packet_count; - GXFTimecode tc; -} GXFContext; - -static const struct { - int height, index; -} gxf_lines_tab[] = { - { 480, 1 }, /* NTSC */ - { 512, 1 }, /* NTSC + VBI */ - { 576, 2 }, /* PAL */ - { 608, 2 }, /* PAL + VBI */ - { 1080, 4 }, - { 720, 6 }, -}; - -static const AVCodecTag gxf_media_types[] = { - { AV_CODEC_ID_MJPEG , 3 }, /* NTSC */ - { AV_CODEC_ID_MJPEG , 4 }, /* PAL */ - { AV_CODEC_ID_PCM_S24LE , 9 }, - { AV_CODEC_ID_PCM_S16LE , 10 }, - { AV_CODEC_ID_MPEG2VIDEO, 11 }, /* NTSC */ - { AV_CODEC_ID_MPEG2VIDEO, 12 }, /* PAL */ - { AV_CODEC_ID_DVVIDEO , 13 }, /* NTSC */ - { AV_CODEC_ID_DVVIDEO , 14 }, /* PAL */ - { AV_CODEC_ID_DVVIDEO , 15 }, /* 50M NTSC */ - { AV_CODEC_ID_DVVIDEO , 16 }, /* 50M PAL */ - { AV_CODEC_ID_AC3 , 17 }, - //{ AV_CODEC_ID_NONE, , 18 }, /* Non compressed 24 bit audio */ - { AV_CODEC_ID_MPEG2VIDEO, 20 }, /* MPEG HD */ - { AV_CODEC_ID_MPEG1VIDEO, 22 }, /* NTSC */ - { AV_CODEC_ID_MPEG1VIDEO, 23 }, /* PAL */ - { AV_CODEC_ID_NONE, 0 }, -}; - -#define SERVER_PATH "EXT:/PDR/default/" -#define ES_NAME_PATTERN "EXT:/PDR/default/ES." - -static int gxf_find_lines_index(AVStream *st) -{ - GXFStreamContext *sc = st->priv_data; - int i; - - for (i = 0; i < 6; ++i) { - if (st->codec->height == gxf_lines_tab[i].height) { - sc->lines_index = gxf_lines_tab[i].index; - return 0; - } - } - return -1; -} - -static void gxf_write_padding(AVIOContext *pb, int64_t to_pad) -{ - for (; to_pad > 0; to_pad--) { - avio_w8(pb, 0); - } -} - -static int64_t updatePacketSize(AVIOContext *pb, int64_t pos) -{ - int64_t curpos; - int size; - - size = avio_tell(pb) - pos; - if (size % 4) { - gxf_write_padding(pb, 4 - size % 4); - size = avio_tell(pb) - pos; - } - curpos = avio_tell(pb); - avio_seek(pb, pos + 6, SEEK_SET); - avio_wb32(pb, size); - avio_seek(pb, curpos, SEEK_SET); - return curpos - pos; -} - -static int64_t updateSize(AVIOContext *pb, int64_t pos) -{ - int64_t curpos; - - curpos = avio_tell(pb); - avio_seek(pb, pos, SEEK_SET); - avio_wb16(pb, curpos - pos - 2); - avio_seek(pb, curpos, SEEK_SET); - return curpos - pos; -} - -static void gxf_write_packet_header(AVIOContext *pb, GXFPktType type) -{ - avio_wb32(pb, 0); /* packet leader for synchro */ - avio_w8(pb, 1); - avio_w8(pb, type); /* map packet */ - avio_wb32(pb, 0); /* size */ - avio_wb32(pb, 0); /* reserved */ - avio_w8(pb, 0xE1); /* trailer 1 */ - avio_w8(pb, 0xE2); /* trailer 2 */ -} - -static int gxf_write_mpeg_auxiliary(AVIOContext *pb, AVStream *st) -{ - GXFStreamContext *sc = st->priv_data; - char buffer[1024]; - int size, starting_line; - - if (sc->iframes) { - sc->p_per_gop = sc->pframes / sc->iframes; - if (sc->pframes % sc->iframes) - sc->p_per_gop++; - if (sc->pframes) { - sc->b_per_i_or_p = sc->bframes / sc->pframes; - if (sc->bframes % sc->pframes) - sc->b_per_i_or_p++; - } - if (sc->p_per_gop > 9) - sc->p_per_gop = 9; /* ensure value won't take more than one char */ - if (sc->b_per_i_or_p > 9) - sc->b_per_i_or_p = 9; /* ensure value won't take more than one char */ - } - if (st->codec->height == 512 || st->codec->height == 608) - starting_line = 7; // VBI - else if (st->codec->height == 480) - starting_line = 20; - else - starting_line = 23; // default PAL - - size = snprintf(buffer, sizeof(buffer), "Ver 1\nBr %.6f\nIpg 1\nPpi %d\nBpiop %d\n" - "Pix 0\nCf %d\nCg %d\nSl %d\nnl16 %d\nVi 1\nf1 1\n", - (float)st->codec->bit_rate, sc->p_per_gop, sc->b_per_i_or_p, - st->codec->pix_fmt == AV_PIX_FMT_YUV422P ? 2 : 1, sc->first_gop_closed == 1, - starting_line, (st->codec->height + 15) / 16); - av_assert0(size < sizeof(buffer)); - avio_w8(pb, TRACK_MPG_AUX); - avio_w8(pb, size + 1); - avio_write(pb, (uint8_t *)buffer, size + 1); - return size + 3; -} - -static int gxf_write_timecode_auxiliary(AVIOContext *pb, GXFContext *gxf) -{ - uint32_t timecode = GXF_TIMECODE(gxf->tc.color, gxf->tc.drop, - gxf->tc.hh, gxf->tc.mm, - gxf->tc.ss, gxf->tc.ff); - - avio_wl32(pb, timecode); - /* reserved */ - avio_wl32(pb, 0); - return 8; -} - -static int gxf_write_track_description(AVFormatContext *s, GXFStreamContext *sc, int index) -{ - GXFContext *gxf = s->priv_data; - AVIOContext *pb = s->pb; - int64_t pos; - int mpeg = sc->track_type == 4 || sc->track_type == 9; - - /* track description section */ - avio_w8(pb, sc->media_type + 0x80); - avio_w8(pb, index + 0xC0); - - pos = avio_tell(pb); - avio_wb16(pb, 0); /* size */ - - /* media file name */ - avio_w8(pb, TRACK_NAME); - avio_w8(pb, strlen(ES_NAME_PATTERN) + 3); - avio_write(pb, ES_NAME_PATTERN, sizeof(ES_NAME_PATTERN) - 1); - avio_wb16(pb, sc->media_info); - avio_w8(pb, 0); - - if (!mpeg) { - /* auxiliary information */ - avio_w8(pb, TRACK_AUX); - avio_w8(pb, 8); - if (sc->track_type == 3) - gxf_write_timecode_auxiliary(pb, gxf); - else - avio_wl64(pb, 0); - } - - /* file system version */ - avio_w8(pb, TRACK_VER); - avio_w8(pb, 4); - avio_wb32(pb, 0); - - if (mpeg) - gxf_write_mpeg_auxiliary(pb, s->streams[index]); - - /* frame rate */ - avio_w8(pb, TRACK_FPS); - avio_w8(pb, 4); - avio_wb32(pb, sc->frame_rate_index); - - /* lines per frame */ - avio_w8(pb, TRACK_LINES); - avio_w8(pb, 4); - avio_wb32(pb, sc->lines_index); - - /* fields per frame */ - avio_w8(pb, TRACK_FPF); - avio_w8(pb, 4); - avio_wb32(pb, sc->fields); - - return updateSize(pb, pos); -} - -static int gxf_write_material_data_section(AVFormatContext *s) -{ - GXFContext *gxf = s->priv_data; - AVIOContext *pb = s->pb; - int64_t pos; - int len; - const char *filename = strrchr(s->filename, '/'); - - pos = avio_tell(pb); - avio_wb16(pb, 0); /* size */ - - /* name */ - if (filename) - filename++; - else - filename = s->filename; - len = strlen(filename); - - avio_w8(pb, MAT_NAME); - avio_w8(pb, strlen(SERVER_PATH) + len + 1); - avio_write(pb, SERVER_PATH, sizeof(SERVER_PATH) - 1); - avio_write(pb, filename, len); - avio_w8(pb, 0); - - /* first field */ - avio_w8(pb, MAT_FIRST_FIELD); - avio_w8(pb, 4); - avio_wb32(pb, 0); - - /* last field */ - avio_w8(pb, MAT_LAST_FIELD); - avio_w8(pb, 4); - avio_wb32(pb, gxf->nb_fields); - - /* reserved */ - avio_w8(pb, MAT_MARK_IN); - avio_w8(pb, 4); - avio_wb32(pb, 0); - - avio_w8(pb, MAT_MARK_OUT); - avio_w8(pb, 4); - avio_wb32(pb, gxf->nb_fields); - - /* estimated size */ - avio_w8(pb, MAT_SIZE); - avio_w8(pb, 4); - avio_wb32(pb, avio_size(pb) / 1024); - - return updateSize(pb, pos); -} - -static int gxf_write_track_description_section(AVFormatContext *s) -{ - GXFContext *gxf = s->priv_data; - AVIOContext *pb = s->pb; - int64_t pos; - int i; - - pos = avio_tell(pb); - avio_wb16(pb, 0); /* size */ - for (i = 0; i < s->nb_streams; ++i) - gxf_write_track_description(s, s->streams[i]->priv_data, i); - - gxf_write_track_description(s, &gxf->timecode_track, s->nb_streams); - - return updateSize(pb, pos); -} - -static int gxf_write_map_packet(AVFormatContext *s, int rewrite) -{ - GXFContext *gxf = s->priv_data; - AVIOContext *pb = s->pb; - int64_t pos = avio_tell(pb); - - if (!rewrite) { - if (!(gxf->map_offsets_nb % 30)) { - gxf->map_offsets = av_realloc_f(gxf->map_offsets, - sizeof(*gxf->map_offsets), - gxf->map_offsets_nb+30); - if (!gxf->map_offsets) { - av_log(s, AV_LOG_ERROR, "could not realloc map offsets\n"); - return -1; - } - } - gxf->map_offsets[gxf->map_offsets_nb++] = pos; // do not increment here - } - - gxf_write_packet_header(pb, PKT_MAP); - - /* preamble */ - avio_w8(pb, 0xE0); /* version */ - avio_w8(pb, 0xFF); /* reserved */ - - gxf_write_material_data_section(s); - gxf_write_track_description_section(s); - - return updatePacketSize(pb, pos); -} - -static int gxf_write_flt_packet(AVFormatContext *s) -{ - GXFContext *gxf = s->priv_data; - AVIOContext *pb = s->pb; - int64_t pos = avio_tell(pb); - int fields_per_flt = (gxf->nb_fields+1) / 1000 + 1; - int flt_entries = gxf->nb_fields / fields_per_flt; - int i = 0; - - gxf_write_packet_header(pb, PKT_FLT); - - avio_wl32(pb, fields_per_flt); /* number of fields */ - avio_wl32(pb, flt_entries); /* number of active flt entries */ - - if (gxf->flt_entries) { - for (i = 0; i < flt_entries; i++) - avio_wl32(pb, gxf->flt_entries[(i*fields_per_flt)>>1]); - } - - for (; i < 1000; i++) - avio_wl32(pb, 0); - - return updatePacketSize(pb, pos); -} - -static int gxf_write_umf_material_description(AVFormatContext *s) -{ - GXFContext *gxf = s->priv_data; - AVIOContext *pb = s->pb; - int timecode_base = gxf->time_base.den == 60000 ? 60 : 50; - int64_t timestamp = 0; - AVDictionaryEntry *t; - uint64_t nb_fields; - uint32_t timecode_in; // timecode at mark in - uint32_t timecode_out; // timecode at mark out - - if (t = av_dict_get(s->metadata, "creation_time", NULL, 0)) - timestamp = ff_iso8601_to_unix_time(t->value); - - timecode_in = GXF_TIMECODE(gxf->tc.color, gxf->tc.drop, - gxf->tc.hh, gxf->tc.mm, - gxf->tc.ss, gxf->tc.ff); - - nb_fields = gxf->nb_fields + - gxf->tc.hh * (timecode_base * 3600) + - gxf->tc.mm * (timecode_base * 60) + - gxf->tc.ss * timecode_base + - gxf->tc.ff; - - timecode_out = GXF_TIMECODE(gxf->tc.color, gxf->tc.drop, - nb_fields / (timecode_base * 3600) % 24, - nb_fields / (timecode_base * 60) % 60, - nb_fields / timecode_base % 60, - nb_fields % timecode_base); - - avio_wl32(pb, gxf->flags); - avio_wl32(pb, gxf->nb_fields); /* length of the longest track */ - avio_wl32(pb, gxf->nb_fields); /* length of the shortest track */ - avio_wl32(pb, 0); /* mark in */ - avio_wl32(pb, gxf->nb_fields); /* mark out */ - avio_wl32(pb, timecode_in); /* timecode mark in */ - avio_wl32(pb, timecode_out); /* timecode mark out */ - avio_wl64(pb, timestamp); /* modification time */ - avio_wl64(pb, timestamp); /* creation time */ - avio_wl16(pb, 0); /* reserved */ - avio_wl16(pb, 0); /* reserved */ - avio_wl16(pb, gxf->audio_tracks); - avio_wl16(pb, 1); /* timecode track count */ - avio_wl16(pb, 0); /* reserved */ - avio_wl16(pb, gxf->mpeg_tracks); - return 48; -} - -static int gxf_write_umf_payload(AVFormatContext *s) -{ - GXFContext *gxf = s->priv_data; - AVIOContext *pb = s->pb; - - avio_wl32(pb, gxf->umf_length); /* total length of the umf data */ - avio_wl32(pb, 3); /* version */ - avio_wl32(pb, s->nb_streams+1); - avio_wl32(pb, gxf->umf_track_offset); /* umf track section offset */ - avio_wl32(pb, gxf->umf_track_size); - avio_wl32(pb, s->nb_streams+1); - avio_wl32(pb, gxf->umf_media_offset); - avio_wl32(pb, gxf->umf_media_size); - avio_wl32(pb, gxf->umf_length); /* user data offset */ - avio_wl32(pb, 0); /* user data size */ - avio_wl32(pb, 0); /* reserved */ - avio_wl32(pb, 0); /* reserved */ - return 48; -} - -static int gxf_write_umf_track_description(AVFormatContext *s) -{ - AVIOContext *pb = s->pb; - GXFContext *gxf = s->priv_data; - int64_t pos = avio_tell(pb); - int i; - - gxf->umf_track_offset = pos - gxf->umf_start_offset; - for (i = 0; i < s->nb_streams; ++i) { - GXFStreamContext *sc = s->streams[i]->priv_data; - avio_wl16(pb, sc->media_info); - avio_wl16(pb, 1); - } - - avio_wl16(pb, gxf->timecode_track.media_info); - avio_wl16(pb, 1); - - return avio_tell(pb) - pos; -} - -static int gxf_write_umf_media_mpeg(AVIOContext *pb, AVStream *st) -{ - GXFStreamContext *sc = st->priv_data; - - if (st->codec->pix_fmt == AV_PIX_FMT_YUV422P) - avio_wl32(pb, 2); - else - avio_wl32(pb, 1); /* default to 420 */ - avio_wl32(pb, sc->first_gop_closed == 1); /* closed = 1, open = 0, unknown = 255 */ - avio_wl32(pb, 3); /* top = 1, bottom = 2, frame = 3, unknown = 0 */ - avio_wl32(pb, 1); /* I picture per GOP */ - avio_wl32(pb, sc->p_per_gop); - avio_wl32(pb, sc->b_per_i_or_p); - if (st->codec->codec_id == AV_CODEC_ID_MPEG2VIDEO) - avio_wl32(pb, 2); - else if (st->codec->codec_id == AV_CODEC_ID_MPEG1VIDEO) - avio_wl32(pb, 1); - else - avio_wl32(pb, 0); - avio_wl32(pb, 0); /* reserved */ - return 32; -} - -static int gxf_write_umf_media_timecode(AVIOContext *pb, int drop) -{ - avio_wl32(pb, drop); /* drop frame */ - avio_wl32(pb, 0); /* reserved */ - avio_wl32(pb, 0); /* reserved */ - avio_wl32(pb, 0); /* reserved */ - avio_wl32(pb, 0); /* reserved */ - avio_wl32(pb, 0); /* reserved */ - avio_wl32(pb, 0); /* reserved */ - avio_wl32(pb, 0); /* reserved */ - return 32; -} - -static int gxf_write_umf_media_dv(AVIOContext *pb, GXFStreamContext *sc) -{ - int i; - - for (i = 0; i < 8; i++) { - avio_wb32(pb, 0); - } - return 32; -} - -static int gxf_write_umf_media_audio(AVIOContext *pb, GXFStreamContext *sc) -{ - avio_wl64(pb, av_double2int(1)); /* sound level to begin to */ - avio_wl64(pb, av_double2int(1)); /* sound level to begin to */ - avio_wl32(pb, 0); /* number of fields over which to ramp up sound level */ - avio_wl32(pb, 0); /* number of fields over which to ramp down sound level */ - avio_wl32(pb, 0); /* reserved */ - avio_wl32(pb, 0); /* reserved */ - return 32; -} - -static int gxf_write_umf_media_description(AVFormatContext *s) -{ - GXFContext *gxf = s->priv_data; - AVIOContext *pb = s->pb; - int64_t pos; - int i, j; - - pos = avio_tell(pb); - gxf->umf_media_offset = pos - gxf->umf_start_offset; - for (i = 0; i <= s->nb_streams; ++i) { - GXFStreamContext *sc; - int64_t startpos, curpos; - - if (i == s->nb_streams) - sc = &gxf->timecode_track; - else - sc = s->streams[i]->priv_data; - - startpos = avio_tell(pb); - avio_wl16(pb, 0); /* length */ - avio_wl16(pb, sc->media_info); - avio_wl16(pb, 0); /* reserved */ - avio_wl16(pb, 0); /* reserved */ - avio_wl32(pb, gxf->nb_fields); - avio_wl32(pb, 0); /* attributes rw, ro */ - avio_wl32(pb, 0); /* mark in */ - avio_wl32(pb, gxf->nb_fields); /* mark out */ - avio_write(pb, ES_NAME_PATTERN, strlen(ES_NAME_PATTERN)); - avio_wb16(pb, sc->media_info); - for (j = strlen(ES_NAME_PATTERN)+2; j < 88; j++) - avio_w8(pb, 0); - avio_wl32(pb, sc->track_type); - avio_wl32(pb, sc->sample_rate); - avio_wl32(pb, sc->sample_size); - avio_wl32(pb, 0); /* reserved */ - - if (sc == &gxf->timecode_track) - gxf_write_umf_media_timecode(pb, gxf->tc.drop); - else { - AVStream *st = s->streams[i]; - switch (st->codec->codec_id) { - case AV_CODEC_ID_MPEG1VIDEO: - case AV_CODEC_ID_MPEG2VIDEO: - gxf_write_umf_media_mpeg(pb, st); - break; - case AV_CODEC_ID_PCM_S16LE: - gxf_write_umf_media_audio(pb, sc); - break; - case AV_CODEC_ID_DVVIDEO: - gxf_write_umf_media_dv(pb, sc); - break; - } - } - - curpos = avio_tell(pb); - avio_seek(pb, startpos, SEEK_SET); - avio_wl16(pb, curpos - startpos); - avio_seek(pb, curpos, SEEK_SET); - } - return avio_tell(pb) - pos; -} - -static int gxf_write_umf_packet(AVFormatContext *s) -{ - GXFContext *gxf = s->priv_data; - AVIOContext *pb = s->pb; - int64_t pos = avio_tell(pb); - - gxf_write_packet_header(pb, PKT_UMF); - - /* preamble */ - avio_w8(pb, 3); /* first and last (only) packet */ - avio_wb32(pb, gxf->umf_length); /* data length */ - - gxf->umf_start_offset = avio_tell(pb); - gxf_write_umf_payload(s); - gxf_write_umf_material_description(s); - gxf->umf_track_size = gxf_write_umf_track_description(s); - gxf->umf_media_size = gxf_write_umf_media_description(s); - gxf->umf_length = avio_tell(pb) - gxf->umf_start_offset; - return updatePacketSize(pb, pos); -} - -static const int GXF_samples_per_frame[] = { 32768, 0 }; - -static void gxf_init_timecode_track(GXFStreamContext *sc, GXFStreamContext *vsc) -{ - if (!vsc) - return; - - sc->media_type = vsc->sample_rate == 60 ? 7 : 8; - sc->sample_rate = vsc->sample_rate; - sc->media_info = ('T'<<8) | '0'; - sc->track_type = 3; - sc->frame_rate_index = vsc->frame_rate_index; - sc->lines_index = vsc->lines_index; - sc->sample_size = 16; - sc->fields = vsc->fields; -} - -static int gxf_init_timecode(AVFormatContext *s, GXFTimecode *tc, const char *tcstr, int fields) -{ - char c; - - if (sscanf(tcstr, "%d:%d:%d%c%d", &tc->hh, &tc->mm, &tc->ss, &c, &tc->ff) != 5) { - av_log(s, AV_LOG_ERROR, "unable to parse timecode, " - "syntax: hh:mm:ss[:;.]ff\n"); - return -1; - } - - tc->color = 0; - tc->drop = c != ':'; - - if (fields == 2) - tc->ff = tc->ff * 2; - - return 0; -} - -static int gxf_write_header(AVFormatContext *s) -{ - AVIOContext *pb = s->pb; - GXFContext *gxf = s->priv_data; - GXFStreamContext *vsc = NULL; - uint8_t tracks[255] = {0}; - int i, media_info = 0; - AVDictionaryEntry *tcr = av_dict_get(s->metadata, "timecode", NULL, 0); - - if (!pb->seekable) { - av_log(s, AV_LOG_ERROR, "gxf muxer does not support streamed output, patch welcome\n"); - return -1; - } - - gxf->flags |= 0x00080000; /* material is simple clip */ - for (i = 0; i < s->nb_streams; ++i) { - AVStream *st = s->streams[i]; - GXFStreamContext *sc = av_mallocz(sizeof(*sc)); - if (!sc) - return AVERROR(ENOMEM); - st->priv_data = sc; - - sc->media_type = ff_codec_get_tag(gxf_media_types, st->codec->codec_id); - if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - if (st->codec->codec_id != AV_CODEC_ID_PCM_S16LE) { - av_log(s, AV_LOG_ERROR, "only 16 BIT PCM LE allowed for now\n"); - return -1; - } - if (st->codec->sample_rate != 48000) { - av_log(s, AV_LOG_ERROR, "only 48000hz sampling rate is allowed\n"); - return -1; - } - if (st->codec->channels != 1) { - av_log(s, AV_LOG_ERROR, "only mono tracks are allowed\n"); - return -1; - } - sc->track_type = 2; - sc->sample_rate = st->codec->sample_rate; - avpriv_set_pts_info(st, 64, 1, sc->sample_rate); - sc->sample_size = 16; - sc->frame_rate_index = -2; - sc->lines_index = -2; - sc->fields = -2; - gxf->audio_tracks++; - gxf->flags |= 0x04000000; /* audio is 16 bit pcm */ - media_info = 'A'; - } else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { - if (i != 0) { - av_log(s, AV_LOG_ERROR, "video stream must be the first track\n"); - return -1; - } - /* FIXME check from time_base ? */ - if (st->codec->height == 480 || st->codec->height == 512) { /* NTSC or NTSC+VBI */ - sc->frame_rate_index = 5; - sc->sample_rate = 60; - gxf->flags |= 0x00000080; - gxf->time_base = (AVRational){ 1001, 60000 }; - } else if (st->codec->height == 576 || st->codec->height == 608) { /* PAL or PAL+VBI */ - sc->frame_rate_index = 6; - sc->media_type++; - sc->sample_rate = 50; - gxf->flags |= 0x00000040; - gxf->time_base = (AVRational){ 1, 50 }; - } else { - av_log(s, AV_LOG_ERROR, "unsupported video resolution, " - "gxf muxer only accepts PAL or NTSC resolutions currently\n"); - return -1; - } - if (!tcr) - tcr = av_dict_get(st->metadata, "timecode", NULL, 0); - avpriv_set_pts_info(st, 64, gxf->time_base.num, gxf->time_base.den); - if (gxf_find_lines_index(st) < 0) - sc->lines_index = -1; - sc->sample_size = st->codec->bit_rate; - sc->fields = 2; /* interlaced */ - - vsc = sc; - - switch (st->codec->codec_id) { - case AV_CODEC_ID_MJPEG: - sc->track_type = 1; - gxf->flags |= 0x00004000; - media_info = 'J'; - break; - case AV_CODEC_ID_MPEG1VIDEO: - sc->track_type = 9; - gxf->mpeg_tracks++; - media_info = 'L'; - break; - case AV_CODEC_ID_MPEG2VIDEO: - sc->first_gop_closed = -1; - sc->track_type = 4; - gxf->mpeg_tracks++; - gxf->flags |= 0x00008000; - media_info = 'M'; - break; - case AV_CODEC_ID_DVVIDEO: - if (st->codec->pix_fmt == AV_PIX_FMT_YUV422P) { - sc->media_type += 2; - sc->track_type = 6; - gxf->flags |= 0x00002000; - media_info = 'E'; - } else { - sc->track_type = 5; - gxf->flags |= 0x00001000; - media_info = 'D'; - } - break; - default: - av_log(s, AV_LOG_ERROR, "video codec not supported\n"); - return -1; - } - } - /* FIXME first 10 audio tracks are 0 to 9 next 22 are A to V */ - sc->media_info = media_info<<8 | ('0'+tracks[media_info]++); - sc->order = s->nb_streams - st->index; - } - - if (ff_audio_interleave_init(s, GXF_samples_per_frame, (AVRational){ 1, 48000 }) < 0) - return -1; - - if (tcr && vsc) - gxf_init_timecode(s, &gxf->tc, tcr->value, vsc->fields); - - gxf_init_timecode_track(&gxf->timecode_track, vsc); - gxf->flags |= 0x200000; // time code track is non-drop frame - - gxf_write_map_packet(s, 0); - gxf_write_flt_packet(s); - gxf_write_umf_packet(s); - - gxf->packet_count = 3; - - avio_flush(pb); - return 0; -} - -static int gxf_write_eos_packet(AVIOContext *pb) -{ - int64_t pos = avio_tell(pb); - - gxf_write_packet_header(pb, PKT_EOS); - return updatePacketSize(pb, pos); -} - -static int gxf_write_trailer(AVFormatContext *s) -{ - GXFContext *gxf = s->priv_data; - AVIOContext *pb = s->pb; - int64_t end; - int i; - - ff_audio_interleave_close(s); - - gxf_write_eos_packet(pb); - end = avio_tell(pb); - avio_seek(pb, 0, SEEK_SET); - /* overwrite map, flt and umf packets with new values */ - gxf_write_map_packet(s, 1); - gxf_write_flt_packet(s); - gxf_write_umf_packet(s); - avio_flush(pb); - /* update duration in all map packets */ - for (i = 1; i < gxf->map_offsets_nb; i++) { - avio_seek(pb, gxf->map_offsets[i], SEEK_SET); - gxf_write_map_packet(s, 1); - avio_flush(pb); - } - - avio_seek(pb, end, SEEK_SET); - - av_freep(&gxf->flt_entries); - av_freep(&gxf->map_offsets); - - return 0; -} - -static int gxf_parse_mpeg_frame(GXFStreamContext *sc, const uint8_t *buf, int size) -{ - uint32_t c=-1; - int i; - for(i=0; ifirst_gop_closed == -1) /* GOP start code */ - sc->first_gop_closed= (buf[i+4]>>6)&1; - } - return (buf[i+1]>>3)&7; -} - -static int gxf_write_media_preamble(AVFormatContext *s, AVPacket *pkt, int size) -{ - GXFContext *gxf = s->priv_data; - AVIOContext *pb = s->pb; - AVStream *st = s->streams[pkt->stream_index]; - GXFStreamContext *sc = st->priv_data; - unsigned field_nb; - /* If the video is frame-encoded, the frame numbers shall be represented by - * even field numbers. - * see SMPTE360M-2004 6.4.2.1.3 Media field number */ - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { - field_nb = gxf->nb_fields; - } else { - field_nb = av_rescale_rnd(pkt->dts, gxf->time_base.den, - (int64_t)48000*gxf->time_base.num, AV_ROUND_UP); - } - - avio_w8(pb, sc->media_type); - avio_w8(pb, st->index); - avio_wb32(pb, field_nb); - if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - avio_wb16(pb, 0); - avio_wb16(pb, size / 2); - } else if (st->codec->codec_id == AV_CODEC_ID_MPEG2VIDEO) { - int frame_type = gxf_parse_mpeg_frame(sc, pkt->data, pkt->size); - if (frame_type == AV_PICTURE_TYPE_I) { - avio_w8(pb, 0x0d); - sc->iframes++; - } else if (frame_type == AV_PICTURE_TYPE_B) { - avio_w8(pb, 0x0f); - sc->bframes++; - } else { - avio_w8(pb, 0x0e); - sc->pframes++; - } - avio_wb24(pb, size); - } else if (st->codec->codec_id == AV_CODEC_ID_DVVIDEO) { - avio_w8(pb, size / 4096); - avio_wb24(pb, 0); - } else - avio_wb32(pb, size); - avio_wb32(pb, field_nb); - avio_w8(pb, 1); /* flags */ - avio_w8(pb, 0); /* reserved */ - return 16; -} - -static int gxf_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - GXFContext *gxf = s->priv_data; - AVIOContext *pb = s->pb; - AVStream *st = s->streams[pkt->stream_index]; - int64_t pos = avio_tell(pb); - int padding = 0; - int packet_start_offset = avio_tell(pb) / 1024; - - gxf_write_packet_header(pb, PKT_MEDIA); - if (st->codec->codec_id == AV_CODEC_ID_MPEG2VIDEO && pkt->size % 4) /* MPEG-2 frames must be padded */ - padding = 4 - pkt->size % 4; - else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) - padding = GXF_AUDIO_PACKET_SIZE - pkt->size; - gxf_write_media_preamble(s, pkt, pkt->size + padding); - avio_write(pb, pkt->data, pkt->size); - gxf_write_padding(pb, padding); - - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { - if (!(gxf->flt_entries_nb % 500)) { - gxf->flt_entries = av_realloc_f(gxf->flt_entries, - sizeof(*gxf->flt_entries), - gxf->flt_entries_nb+500); - if (!gxf->flt_entries) { - av_log(s, AV_LOG_ERROR, "could not reallocate flt entries\n"); - return -1; - } - } - gxf->flt_entries[gxf->flt_entries_nb++] = packet_start_offset; - gxf->nb_fields += 2; // count fields - } - - updatePacketSize(pb, pos); - - gxf->packet_count++; - if (gxf->packet_count == 100) { - gxf_write_map_packet(s, 0); - gxf->packet_count = 0; - } - - avio_flush(pb); - - return 0; -} - -static int gxf_compare_field_nb(AVFormatContext *s, AVPacket *next, AVPacket *cur) -{ - GXFContext *gxf = s->priv_data; - AVPacket *pkt[2] = { cur, next }; - int i, field_nb[2]; - GXFStreamContext *sc[2]; - - for (i = 0; i < 2; i++) { - AVStream *st = s->streams[pkt[i]->stream_index]; - sc[i] = st->priv_data; - if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - field_nb[i] = av_rescale_rnd(pkt[i]->dts, gxf->time_base.den, - (int64_t)48000*gxf->time_base.num, AV_ROUND_UP); - field_nb[i] &= ~1; // compare against even field number because audio must be before video - } else - field_nb[i] = pkt[i]->dts; // dts are field based - } - - return field_nb[1] > field_nb[0] || - (field_nb[1] == field_nb[0] && sc[1]->order > sc[0]->order); -} - -static int gxf_interleave_packet(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush) -{ - if (pkt && s->streams[pkt->stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO) - pkt->duration = 2; // enforce 2 fields - return ff_audio_rechunk_interleave(s, out, pkt, flush, - ff_interleave_packet_per_dts, gxf_compare_field_nb); -} - -AVOutputFormat ff_gxf_muxer = { - .name = "gxf", - .long_name = NULL_IF_CONFIG_SMALL("GXF (General eXchange Format)"), - .extensions = "gxf", - .priv_data_size = sizeof(GXFContext), - .audio_codec = AV_CODEC_ID_PCM_S16LE, - .video_codec = AV_CODEC_ID_MPEG2VIDEO, - .write_header = gxf_write_header, - .write_packet = gxf_write_packet, - .write_trailer = gxf_write_trailer, - .interleave_packet = gxf_interleave_packet, -}; diff --git a/ffmpeg1/libavformat/h261dec.c b/ffmpeg1/libavformat/h261dec.c deleted file mode 100644 index 1b254d6..0000000 --- a/ffmpeg1/libavformat/h261dec.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * RAW H.261 video demuxer - * Copyright (c) 2009 Michael Niedermayer - * - * 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 "libavcodec/get_bits.h" -#include "avformat.h" -#include "rawdec.h" - -static int h261_probe(AVProbeData *p) -{ - uint32_t code= -1; - int i; - int valid_psc=0; - int invalid_psc=0; - int next_gn=0; - int src_fmt=0; - GetBitContext gb; - - init_get_bits(&gb, p->buf, p->buf_size*8); - - for(i=0; ibuf_size*8; i++){ - if ((code & 0x01ff0000) || !(code & 0xff00)) { - code = (code<<8) + get_bits(&gb, 8); - i += 7; - } else - code = (code<<1) + get_bits1(&gb); - if ((code & 0xffff0000) == 0x10000) { - int gn= (code>>12)&0xf; - if(!gn) - src_fmt= code&8; - if(gn != next_gn) invalid_psc++; - else valid_psc++; - - if(src_fmt){ // CIF - next_gn= (gn+1 )%13; - }else{ //QCIF - next_gn= (gn+1+!!gn)% 7; - } - } - } - if(valid_psc > 2*invalid_psc + 6){ - return 50; - }else if(valid_psc > 2*invalid_psc + 2) - return 25; - return 0; -} - -FF_DEF_RAWVIDEO_DEMUXER(h261, "raw H.261", h261_probe, "h261", AV_CODEC_ID_H261) diff --git a/ffmpeg1/libavformat/h263dec.c b/ffmpeg1/libavformat/h263dec.c deleted file mode 100644 index 667fdbd..0000000 --- a/ffmpeg1/libavformat/h263dec.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * RAW H.263 video demuxer - * Copyright (c) 2009 Michael Niedermayer - * - * 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 "rawdec.h" - -static int h263_probe(AVProbeData *p) -{ - uint64_t code= -1; - int i; - int valid_psc=0; - int invalid_psc=0; - int res_change=0; - int src_fmt, last_src_fmt=-1; - int last_gn=0; - - for(i=0; ibuf_size; i++){ - code = (code<<8) + p->buf[i]; - if ((code & 0xfffffc0000) == 0x800000) { - src_fmt= (code>>2)&3; - if( src_fmt != last_src_fmt - && last_src_fmt>0 && last_src_fmt<6 - && src_fmt<6) - res_change++; - - if((code&0x300)==0x200 && src_fmt){ - valid_psc++; - last_gn=0; - }else - invalid_psc++; - last_src_fmt= src_fmt; - } else if((code & 0xffff800000) == 0x800000) { - int gn= (code>>(23-5)) & 0x1F; - if(gn 2*invalid_psc + 2*res_change + 3){ - return 50; - }else if(valid_psc > 2*invalid_psc) - return 25; - return 0; -} - -FF_DEF_RAWVIDEO_DEMUXER(h263, "raw H.263", h263_probe, NULL, AV_CODEC_ID_H263) diff --git a/ffmpeg1/libavformat/h264dec.c b/ffmpeg1/libavformat/h264dec.c deleted file mode 100644 index 9c67ab9..0000000 --- a/ffmpeg1/libavformat/h264dec.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * RAW H.264 video demuxer - * Copyright (c) 2008 Michael Niedermayer - * - * 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 "rawdec.h" - -static int h264_probe(AVProbeData *p) -{ - uint32_t code= -1; - int sps=0, pps=0, idr=0, res=0, sli=0; - int i; - - for(i=0; ibuf_size; i++){ - code = (code<<8) + p->buf[i]; - if ((code & 0xffffff00) == 0x100) { - int ref_idc= (code>>5)&3; - int type = code & 0x1F; - static const int8_t ref_zero[32]={ - 2, 0, 0, 0, 0,-1, 1,-1, - -1, 1, 1, 1, 1,-1, 2, 2, - 2, 2, 2, 0, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2 - }; - - if(code & 0x80) //forbidden bit - return 0; - - if(ref_zero[type] == 1 && ref_idc) - return 0; - if(ref_zero[type] ==-1 && !ref_idc) - return 0; - if(ref_zero[type] == 2) - res++; - - switch(type){ - case 1: sli++; break; - case 5: idr++; break; - case 7: - if (p->buf[i + 2] & 0x03) - return 0; - sps++; - break; - case 8: pps++; break; - } - } - } - if(sps && pps && (idr||sli>3) && res<(sps+pps+idr)) - return AVPROBE_SCORE_MAX/2+1; // +1 for .mpg - return 0; -} - -FF_DEF_RAWVIDEO_DEMUXER(h264 , "raw H.264 video", h264_probe, "h26l,h264,264", AV_CODEC_ID_H264) diff --git a/ffmpeg1/libavformat/hls.c b/ffmpeg1/libavformat/hls.c deleted file mode 100644 index 7de6059..0000000 --- a/ffmpeg1/libavformat/hls.c +++ /dev/null @@ -1,828 +0,0 @@ -/* - * Apple HTTP Live Streaming demuxer - * Copyright (c) 2010 Martin Storsjo - * - * 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 - */ - -/** - * @file - * Apple HTTP Live Streaming demuxer - * http://tools.ietf.org/html/draft-pantos-http-live-streaming - */ - -#include "libavutil/avstring.h" -#include "libavutil/intreadwrite.h" -#include "libavutil/mathematics.h" -#include "libavutil/opt.h" -#include "libavutil/dict.h" -#include "libavutil/time.h" -#include "avformat.h" -#include "internal.h" -#include "avio_internal.h" -#include "url.h" - -#define INITIAL_BUFFER_SIZE 32768 - -/* - * An apple http stream consists of a playlist with media segment files, - * played sequentially. There may be several playlists with the same - * video content, in different bandwidth variants, that are played in - * parallel (preferably only one bandwidth variant at a time). In this case, - * the user supplied the url to a main playlist that only lists the variant - * playlists. - * - * If the main playlist doesn't point at any variants, we still create - * one anonymous toplevel variant for this, to maintain the structure. - */ - -enum KeyType { - KEY_NONE, - KEY_AES_128, -}; - -struct segment { - int duration; - char url[MAX_URL_SIZE]; - char key[MAX_URL_SIZE]; - enum KeyType key_type; - uint8_t iv[16]; -}; - -/* - * Each variant has its own demuxer. If it currently is active, - * it has an open AVIOContext too, and potentially an AVPacket - * containing the next packet from this stream. - */ -struct variant { - int bandwidth; - char url[MAX_URL_SIZE]; - AVIOContext pb; - uint8_t* read_buffer; - URLContext *input; - AVFormatContext *parent; - int index; - AVFormatContext *ctx; - AVPacket pkt; - int stream_offset; - - int finished; - int target_duration; - int start_seq_no; - int n_segments; - struct segment **segments; - int needed, cur_needed; - int cur_seq_no; - int64_t last_load_time; - - char key_url[MAX_URL_SIZE]; - uint8_t key[16]; -}; - -typedef struct HLSContext { - int n_variants; - struct variant **variants; - int cur_seq_no; - int end_of_segment; - int first_packet; - int64_t first_timestamp; - int64_t seek_timestamp; - int seek_flags; - AVIOInterruptCB *interrupt_callback; - char *user_agent; ///< holds HTTP user agent set as an AVOption to the HTTP protocol context - char *cookies; ///< holds HTTP cookie values set in either the initial response or as an AVOption to the HTTP protocol context -} HLSContext; - -static int read_chomp_line(AVIOContext *s, char *buf, int maxlen) -{ - int len = ff_get_line(s, buf, maxlen); - while (len > 0 && av_isspace(buf[len - 1])) - buf[--len] = '\0'; - return len; -} - -static void free_segment_list(struct variant *var) -{ - int i; - for (i = 0; i < var->n_segments; i++) - av_free(var->segments[i]); - av_freep(&var->segments); - var->n_segments = 0; -} - -static void free_variant_list(HLSContext *c) -{ - int i; - for (i = 0; i < c->n_variants; i++) { - struct variant *var = c->variants[i]; - free_segment_list(var); - av_free_packet(&var->pkt); - av_free(var->pb.buffer); - if (var->input) - ffurl_close(var->input); - if (var->ctx) { - var->ctx->pb = NULL; - avformat_close_input(&var->ctx); - } - av_free(var); - } - av_freep(&c->variants); - av_freep(&c->cookies); - av_freep(&c->user_agent); - c->n_variants = 0; -} - -/* - * Used to reset a statically allocated AVPacket to a clean slate, - * containing no data. - */ -static void reset_packet(AVPacket *pkt) -{ - av_init_packet(pkt); - pkt->data = NULL; -} - -static struct variant *new_variant(HLSContext *c, int bandwidth, - const char *url, const char *base) -{ - struct variant *var = av_mallocz(sizeof(struct variant)); - if (!var) - return NULL; - reset_packet(&var->pkt); - var->bandwidth = bandwidth; - ff_make_absolute_url(var->url, sizeof(var->url), base, url); - dynarray_add(&c->variants, &c->n_variants, var); - return var; -} - -struct variant_info { - char bandwidth[20]; -}; - -static void handle_variant_args(struct variant_info *info, const char *key, - int key_len, char **dest, int *dest_len) -{ - if (!strncmp(key, "BANDWIDTH=", key_len)) { - *dest = info->bandwidth; - *dest_len = sizeof(info->bandwidth); - } -} - -struct key_info { - char uri[MAX_URL_SIZE]; - char method[10]; - char iv[35]; -}; - -static void handle_key_args(struct key_info *info, const char *key, - int key_len, char **dest, int *dest_len) -{ - if (!strncmp(key, "METHOD=", key_len)) { - *dest = info->method; - *dest_len = sizeof(info->method); - } else if (!strncmp(key, "URI=", key_len)) { - *dest = info->uri; - *dest_len = sizeof(info->uri); - } else if (!strncmp(key, "IV=", key_len)) { - *dest = info->iv; - *dest_len = sizeof(info->iv); - } -} - -static int parse_playlist(HLSContext *c, const char *url, - struct variant *var, AVIOContext *in) -{ - int ret = 0, duration = 0, is_segment = 0, is_variant = 0, bandwidth = 0; - enum KeyType key_type = KEY_NONE; - uint8_t iv[16] = ""; - int has_iv = 0; - char key[MAX_URL_SIZE] = ""; - char line[1024]; - const char *ptr; - int close_in = 0; - - if (!in) { - AVDictionary *opts = NULL; - close_in = 1; - /* Some HLS servers dont like being sent the range header */ - av_dict_set(&opts, "seekable", "0", 0); - - // broker prior HTTP options that should be consistent across requests - av_dict_set(&opts, "user-agent", c->user_agent, 0); - av_dict_set(&opts, "cookies", c->cookies, 0); - - ret = avio_open2(&in, url, AVIO_FLAG_READ, - c->interrupt_callback, &opts); - av_dict_free(&opts); - if (ret < 0) - return ret; - } - - read_chomp_line(in, line, sizeof(line)); - if (strcmp(line, "#EXTM3U")) { - ret = AVERROR_INVALIDDATA; - goto fail; - } - - if (var) { - free_segment_list(var); - var->finished = 0; - } - while (!url_feof(in)) { - read_chomp_line(in, line, sizeof(line)); - if (av_strstart(line, "#EXT-X-STREAM-INF:", &ptr)) { - struct variant_info info = {{0}}; - is_variant = 1; - ff_parse_key_value(ptr, (ff_parse_key_val_cb) handle_variant_args, - &info); - bandwidth = atoi(info.bandwidth); - } else if (av_strstart(line, "#EXT-X-KEY:", &ptr)) { - struct key_info info = {{0}}; - ff_parse_key_value(ptr, (ff_parse_key_val_cb) handle_key_args, - &info); - key_type = KEY_NONE; - has_iv = 0; - if (!strcmp(info.method, "AES-128")) - key_type = KEY_AES_128; - if (!strncmp(info.iv, "0x", 2) || !strncmp(info.iv, "0X", 2)) { - ff_hex_to_data(iv, info.iv + 2); - has_iv = 1; - } - av_strlcpy(key, info.uri, sizeof(key)); - } else if (av_strstart(line, "#EXT-X-TARGETDURATION:", &ptr)) { - if (!var) { - var = new_variant(c, 0, url, NULL); - if (!var) { - ret = AVERROR(ENOMEM); - goto fail; - } - } - var->target_duration = atoi(ptr); - } else if (av_strstart(line, "#EXT-X-MEDIA-SEQUENCE:", &ptr)) { - if (!var) { - var = new_variant(c, 0, url, NULL); - if (!var) { - ret = AVERROR(ENOMEM); - goto fail; - } - } - var->start_seq_no = atoi(ptr); - } else if (av_strstart(line, "#EXT-X-ENDLIST", &ptr)) { - if (var) - var->finished = 1; - } else if (av_strstart(line, "#EXTINF:", &ptr)) { - is_segment = 1; - duration = atoi(ptr); - } else if (av_strstart(line, "#", NULL)) { - continue; - } else if (line[0]) { - if (is_variant) { - if (!new_variant(c, bandwidth, line, url)) { - ret = AVERROR(ENOMEM); - goto fail; - } - is_variant = 0; - bandwidth = 0; - } - if (is_segment) { - struct segment *seg; - if (!var) { - var = new_variant(c, 0, url, NULL); - if (!var) { - ret = AVERROR(ENOMEM); - goto fail; - } - } - seg = av_malloc(sizeof(struct segment)); - if (!seg) { - ret = AVERROR(ENOMEM); - goto fail; - } - seg->duration = duration; - seg->key_type = key_type; - if (has_iv) { - memcpy(seg->iv, iv, sizeof(iv)); - } else { - int seq = var->start_seq_no + var->n_segments; - memset(seg->iv, 0, sizeof(seg->iv)); - AV_WB32(seg->iv + 12, seq); - } - ff_make_absolute_url(seg->key, sizeof(seg->key), url, key); - ff_make_absolute_url(seg->url, sizeof(seg->url), url, line); - dynarray_add(&var->segments, &var->n_segments, seg); - is_segment = 0; - } - } - } - if (var) - var->last_load_time = av_gettime(); - -fail: - if (close_in) - avio_close(in); - return ret; -} - -static int open_input(HLSContext *c, struct variant *var) -{ - AVDictionary *opts = NULL; - int ret; - struct segment *seg = var->segments[var->cur_seq_no - var->start_seq_no]; - - // broker prior HTTP options that should be consistent across requests - av_dict_set(&opts, "user-agent", c->user_agent, 0); - av_dict_set(&opts, "cookies", c->cookies, 0); - av_dict_set(&opts, "seekable", "0", 0); - - if (seg->key_type == KEY_NONE) { - ret = ffurl_open(&var->input, seg->url, AVIO_FLAG_READ, - &var->parent->interrupt_callback, &opts); - goto cleanup; - } else if (seg->key_type == KEY_AES_128) { - char iv[33], key[33], url[MAX_URL_SIZE]; - if (strcmp(seg->key, var->key_url)) { - URLContext *uc; - if (ffurl_open(&uc, seg->key, AVIO_FLAG_READ, - &var->parent->interrupt_callback, &opts) == 0) { - if (ffurl_read_complete(uc, var->key, sizeof(var->key)) - != sizeof(var->key)) { - av_log(NULL, AV_LOG_ERROR, "Unable to read key file %s\n", - seg->key); - } - ffurl_close(uc); - } else { - av_log(NULL, AV_LOG_ERROR, "Unable to open key file %s\n", - seg->key); - } - av_strlcpy(var->key_url, seg->key, sizeof(var->key_url)); - } - ff_data_to_hex(iv, seg->iv, sizeof(seg->iv), 0); - ff_data_to_hex(key, var->key, sizeof(var->key), 0); - iv[32] = key[32] = '\0'; - if (strstr(seg->url, "://")) - snprintf(url, sizeof(url), "crypto+%s", seg->url); - else - snprintf(url, sizeof(url), "crypto:%s", seg->url); - if ((ret = ffurl_alloc(&var->input, url, AVIO_FLAG_READ, - &var->parent->interrupt_callback)) < 0) - goto cleanup; - av_opt_set(var->input->priv_data, "key", key, 0); - av_opt_set(var->input->priv_data, "iv", iv, 0); - /* Need to repopulate options */ - av_dict_free(&opts); - av_dict_set(&opts, "seekable", "0", 0); - if ((ret = ffurl_connect(var->input, &opts)) < 0) { - ffurl_close(var->input); - var->input = NULL; - goto cleanup; - } - ret = 0; - } - else - ret = AVERROR(ENOSYS); - -cleanup: - av_dict_free(&opts); - return ret; -} - -static int read_data(void *opaque, uint8_t *buf, int buf_size) -{ - struct variant *v = opaque; - HLSContext *c = v->parent->priv_data; - int ret, i; - -restart: - if (!v->input) { - /* If this is a live stream and the reload interval has elapsed since - * the last playlist reload, reload the variant playlists now. */ - int64_t reload_interval = v->n_segments > 0 ? - v->segments[v->n_segments - 1]->duration : - v->target_duration; - reload_interval *= 1000000; - -reload: - if (!v->finished && - av_gettime() - v->last_load_time >= reload_interval) { - if ((ret = parse_playlist(c, v->url, v, NULL)) < 0) - return ret; - /* If we need to reload the playlist again below (if - * there's still no more segments), switch to a reload - * interval of half the target duration. */ - reload_interval = v->target_duration * 500000LL; - } - if (v->cur_seq_no < v->start_seq_no) { - av_log(NULL, AV_LOG_WARNING, - "skipping %d segments ahead, expired from playlists\n", - v->start_seq_no - v->cur_seq_no); - v->cur_seq_no = v->start_seq_no; - } - if (v->cur_seq_no >= v->start_seq_no + v->n_segments) { - if (v->finished) - return AVERROR_EOF; - while (av_gettime() - v->last_load_time < reload_interval) { - if (ff_check_interrupt(c->interrupt_callback)) - return AVERROR_EXIT; - av_usleep(100*1000); - } - /* Enough time has elapsed since the last reload */ - goto reload; - } - - ret = open_input(c, v); - if (ret < 0) - return ret; - } - ret = ffurl_read(v->input, buf, buf_size); - if (ret > 0) - return ret; - ffurl_close(v->input); - v->input = NULL; - v->cur_seq_no++; - - c->end_of_segment = 1; - c->cur_seq_no = v->cur_seq_no; - - if (v->ctx && v->ctx->nb_streams && v->parent->nb_streams >= v->stream_offset + v->ctx->nb_streams) { - v->needed = 0; - for (i = v->stream_offset; i < v->stream_offset + v->ctx->nb_streams; - i++) { - if (v->parent->streams[i]->discard < AVDISCARD_ALL) - v->needed = 1; - } - } - if (!v->needed) { - av_log(v->parent, AV_LOG_INFO, "No longer receiving variant %d\n", - v->index); - return AVERROR_EOF; - } - goto restart; -} - -static int hls_read_header(AVFormatContext *s) -{ - URLContext *u = (s->flags & AVFMT_FLAG_CUSTOM_IO) ? NULL : s->pb->opaque; - HLSContext *c = s->priv_data; - int ret = 0, i, j, stream_offset = 0; - - c->interrupt_callback = &s->interrupt_callback; - - // if the URL context is good, read important options we must broker later - if (u && u->prot->priv_data_class) { - // get the previous user agent & set back to null if string size is zero - av_freep(&c->user_agent); - av_opt_get(u->priv_data, "user-agent", 0, (uint8_t**)&(c->user_agent)); - if (c->user_agent && !strlen(c->user_agent)) - av_freep(&c->user_agent); - - // get the previous cookies & set back to null if string size is zero - av_freep(&c->cookies); - av_opt_get(u->priv_data, "cookies", 0, (uint8_t**)&(c->cookies)); - if (c->cookies && !strlen(c->cookies)) - av_freep(&c->cookies); - } - - if ((ret = parse_playlist(c, s->filename, NULL, s->pb)) < 0) - goto fail; - - if (c->n_variants == 0) { - av_log(NULL, AV_LOG_WARNING, "Empty playlist\n"); - ret = AVERROR_EOF; - goto fail; - } - /* If the playlist only contained variants, parse each individual - * variant playlist. */ - if (c->n_variants > 1 || c->variants[0]->n_segments == 0) { - for (i = 0; i < c->n_variants; i++) { - struct variant *v = c->variants[i]; - if ((ret = parse_playlist(c, v->url, v, NULL)) < 0) - goto fail; - } - } - - if (c->variants[0]->n_segments == 0) { - av_log(NULL, AV_LOG_WARNING, "Empty playlist\n"); - ret = AVERROR_EOF; - goto fail; - } - - /* If this isn't a live stream, calculate the total duration of the - * stream. */ - if (c->variants[0]->finished) { - int64_t duration = 0; - for (i = 0; i < c->variants[0]->n_segments; i++) - duration += c->variants[0]->segments[i]->duration; - s->duration = duration * AV_TIME_BASE; - } - - /* Open the demuxer for each variant */ - for (i = 0; i < c->n_variants; i++) { - struct variant *v = c->variants[i]; - AVInputFormat *in_fmt = NULL; - char bitrate_str[20]; - AVProgram *program = NULL; - if (v->n_segments == 0) - continue; - - if (!(v->ctx = avformat_alloc_context())) { - ret = AVERROR(ENOMEM); - goto fail; - } - - v->index = i; - v->needed = 1; - v->parent = s; - - /* If this is a live stream with more than 3 segments, start at the - * third last segment. */ - v->cur_seq_no = v->start_seq_no; - if (!v->finished && v->n_segments > 3) - v->cur_seq_no = v->start_seq_no + v->n_segments - 3; - - v->read_buffer = av_malloc(INITIAL_BUFFER_SIZE); - ffio_init_context(&v->pb, v->read_buffer, INITIAL_BUFFER_SIZE, 0, v, - read_data, NULL, NULL); - v->pb.seekable = 0; - ret = av_probe_input_buffer(&v->pb, &in_fmt, v->segments[0]->url, - NULL, 0, 0); - if (ret < 0) { - /* Free the ctx - it isn't initialized properly at this point, - * so avformat_close_input shouldn't be called. If - * avformat_open_input fails below, it frees and zeros the - * context, so it doesn't need any special treatment like this. */ - av_log(s, AV_LOG_ERROR, "Error when loading first segment '%s'\n", v->segments[0]->url); - avformat_free_context(v->ctx); - v->ctx = NULL; - goto fail; - } - v->ctx->pb = &v->pb; - ret = avformat_open_input(&v->ctx, v->segments[0]->url, in_fmt, NULL); - if (ret < 0) - goto fail; - - v->stream_offset = stream_offset; - v->ctx->ctx_flags &= ~AVFMTCTX_NOHEADER; - ret = avformat_find_stream_info(v->ctx, NULL); - if (ret < 0) - goto fail; - snprintf(bitrate_str, sizeof(bitrate_str), "%d", v->bandwidth); - - /* Create new AVprogram for variant i */ - program = av_new_program(s, i); - if (!program) - goto fail; - av_dict_set(&program->metadata, "variant_bitrate", bitrate_str, 0); - - /* Create new AVStreams for each stream in this variant */ - for (j = 0; j < v->ctx->nb_streams; j++) { - AVStream *st = avformat_new_stream(s, NULL); - AVStream *ist = v->ctx->streams[j]; - if (!st) { - ret = AVERROR(ENOMEM); - goto fail; - } - ff_program_add_stream_index(s, i, stream_offset + j); - st->id = i; - avpriv_set_pts_info(st, ist->pts_wrap_bits, ist->time_base.num, ist->time_base.den); - avcodec_copy_context(st->codec, v->ctx->streams[j]->codec); - if (v->bandwidth) - av_dict_set(&st->metadata, "variant_bitrate", bitrate_str, - 0); - } - stream_offset += v->ctx->nb_streams; - } - - c->first_packet = 1; - c->first_timestamp = AV_NOPTS_VALUE; - c->seek_timestamp = AV_NOPTS_VALUE; - - return 0; -fail: - free_variant_list(c); - return ret; -} - -static int recheck_discard_flags(AVFormatContext *s, int first) -{ - HLSContext *c = s->priv_data; - int i, changed = 0; - - /* Check if any new streams are needed */ - for (i = 0; i < c->n_variants; i++) - c->variants[i]->cur_needed = 0; - - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - struct variant *var = c->variants[s->streams[i]->id]; - if (st->discard < AVDISCARD_ALL) - var->cur_needed = 1; - } - for (i = 0; i < c->n_variants; i++) { - struct variant *v = c->variants[i]; - if (v->cur_needed && !v->needed) { - v->needed = 1; - changed = 1; - v->cur_seq_no = c->cur_seq_no; - v->pb.eof_reached = 0; - av_log(s, AV_LOG_INFO, "Now receiving variant %d\n", i); - } else if (first && !v->cur_needed && v->needed) { - if (v->input) - ffurl_close(v->input); - v->input = NULL; - v->needed = 0; - changed = 1; - av_log(s, AV_LOG_INFO, "No longer receiving variant %d\n", i); - } - } - return changed; -} - -static int hls_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - HLSContext *c = s->priv_data; - int ret, i, minvariant = -1; - - if (c->first_packet) { - recheck_discard_flags(s, 1); - c->first_packet = 0; - } - -start: - c->end_of_segment = 0; - for (i = 0; i < c->n_variants; i++) { - struct variant *var = c->variants[i]; - /* Make sure we've got one buffered packet from each open variant - * stream */ - if (var->needed && !var->pkt.data) { - while (1) { - int64_t ts_diff; - AVStream *st; - ret = av_read_frame(var->ctx, &var->pkt); - if (ret < 0) { - if (!url_feof(&var->pb) && ret != AVERROR_EOF) - return ret; - reset_packet(&var->pkt); - break; - } else { - if (c->first_timestamp == AV_NOPTS_VALUE) - c->first_timestamp = var->pkt.dts; - } - - if (c->seek_timestamp == AV_NOPTS_VALUE) - break; - - if (var->pkt.dts == AV_NOPTS_VALUE) { - c->seek_timestamp = AV_NOPTS_VALUE; - break; - } - - st = var->ctx->streams[var->pkt.stream_index]; - ts_diff = av_rescale_rnd(var->pkt.dts, AV_TIME_BASE, - st->time_base.den, AV_ROUND_DOWN) - - c->seek_timestamp; - if (ts_diff >= 0 && (c->seek_flags & AVSEEK_FLAG_ANY || - var->pkt.flags & AV_PKT_FLAG_KEY)) { - c->seek_timestamp = AV_NOPTS_VALUE; - break; - } - } - } - /* Check if this stream has the packet with the lowest dts */ - if (var->pkt.data) { - if(minvariant < 0) { - minvariant = i; - } else { - struct variant *minvar = c->variants[minvariant]; - int64_t dts = var->pkt.dts; - int64_t mindts = minvar->pkt.dts; - AVStream *st = var->ctx->streams[ var->pkt.stream_index]; - AVStream *minst= minvar->ctx->streams[minvar->pkt.stream_index]; - - if( st->start_time != AV_NOPTS_VALUE) dts -= st->start_time; - if(minst->start_time != AV_NOPTS_VALUE) mindts -= minst->start_time; - - if (av_compare_ts(dts, st->time_base, mindts, minst->time_base) < 0) - minvariant = i; - } - } - } - if (c->end_of_segment) { - if (recheck_discard_flags(s, 0)) - goto start; - } - /* If we got a packet, return it */ - if (minvariant >= 0) { - *pkt = c->variants[minvariant]->pkt; - pkt->stream_index += c->variants[minvariant]->stream_offset; - reset_packet(&c->variants[minvariant]->pkt); - return 0; - } - return AVERROR_EOF; -} - -static int hls_close(AVFormatContext *s) -{ - HLSContext *c = s->priv_data; - - free_variant_list(c); - return 0; -} - -static int hls_read_seek(AVFormatContext *s, int stream_index, - int64_t timestamp, int flags) -{ - HLSContext *c = s->priv_data; - int i, j, ret; - - if ((flags & AVSEEK_FLAG_BYTE) || !c->variants[0]->finished) - return AVERROR(ENOSYS); - - c->seek_flags = flags; - c->seek_timestamp = stream_index < 0 ? timestamp : - av_rescale_rnd(timestamp, AV_TIME_BASE, - s->streams[stream_index]->time_base.den, - flags & AVSEEK_FLAG_BACKWARD ? - AV_ROUND_DOWN : AV_ROUND_UP); - timestamp = av_rescale_rnd(timestamp, 1, stream_index >= 0 ? - s->streams[stream_index]->time_base.den : - AV_TIME_BASE, flags & AVSEEK_FLAG_BACKWARD ? - AV_ROUND_DOWN : AV_ROUND_UP); - if (s->duration < c->seek_timestamp) { - c->seek_timestamp = AV_NOPTS_VALUE; - return AVERROR(EIO); - } - - ret = AVERROR(EIO); - for (i = 0; i < c->n_variants; i++) { - /* Reset reading */ - struct variant *var = c->variants[i]; - int64_t pos = c->first_timestamp == AV_NOPTS_VALUE ? 0 : - av_rescale_rnd(c->first_timestamp, 1, stream_index >= 0 ? - s->streams[stream_index]->time_base.den : - AV_TIME_BASE, flags & AVSEEK_FLAG_BACKWARD ? - AV_ROUND_DOWN : AV_ROUND_UP); - if (var->input) { - ffurl_close(var->input); - var->input = NULL; - } - av_free_packet(&var->pkt); - reset_packet(&var->pkt); - var->pb.eof_reached = 0; - /* Clear any buffered data */ - var->pb.buf_end = var->pb.buf_ptr = var->pb.buffer; - /* Reset the pos, to let the mpegts demuxer know we've seeked. */ - var->pb.pos = 0; - - /* Locate the segment that contains the target timestamp */ - for (j = 0; j < var->n_segments; j++) { - if (timestamp >= pos && - timestamp < pos + var->segments[j]->duration) { - var->cur_seq_no = var->start_seq_no + j; - ret = 0; - break; - } - pos += var->segments[j]->duration; - } - if (ret) - c->seek_timestamp = AV_NOPTS_VALUE; - } - return ret; -} - -static int hls_probe(AVProbeData *p) -{ - /* Require #EXTM3U at the start, and either one of the ones below - * somewhere for a proper match. */ - if (strncmp(p->buf, "#EXTM3U", 7)) - return 0; - if (strstr(p->buf, "#EXT-X-STREAM-INF:") || - strstr(p->buf, "#EXT-X-TARGETDURATION:") || - strstr(p->buf, "#EXT-X-MEDIA-SEQUENCE:")) - return AVPROBE_SCORE_MAX; - return 0; -} - -AVInputFormat ff_hls_demuxer = { - .name = "hls,applehttp", - .long_name = NULL_IF_CONFIG_SMALL("Apple HTTP Live Streaming"), - .priv_data_size = sizeof(HLSContext), - .read_probe = hls_probe, - .read_header = hls_read_header, - .read_packet = hls_read_packet, - .read_close = hls_close, - .read_seek = hls_read_seek, -}; diff --git a/ffmpeg1/libavformat/hlsenc.c b/ffmpeg1/libavformat/hlsenc.c deleted file mode 100644 index 18914c0..0000000 --- a/ffmpeg1/libavformat/hlsenc.c +++ /dev/null @@ -1,348 +0,0 @@ -/* - * Apple HTTP Live Streaming segmenter - * Copyright (c) 2012, Luca Barbato - * - * 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 - -#include "libavutil/mathematics.h" -#include "libavutil/parseutils.h" -#include "libavutil/avstring.h" -#include "libavutil/opt.h" -#include "libavutil/log.h" - -#include "avformat.h" -#include "internal.h" - -typedef struct ListEntry { - char name[1024]; - int duration; - struct ListEntry *next; -} ListEntry; - -typedef struct HLSContext { - const AVClass *class; // Class for private options. - unsigned number; - int64_t sequence; - AVOutputFormat *oformat; - AVFormatContext *avf; - float time; // Set by a private option. - int size; // Set by a private option. - int wrap; // Set by a private option. - int64_t recording_time; - int has_video; - int64_t start_pts; - int64_t end_pts; - int64_t duration; ///< last segment duration computed so far, in seconds - int nb_entries; - ListEntry *list; - ListEntry *end_list; - char *basename; - AVIOContext *pb; -} HLSContext; - -static int hls_mux_init(AVFormatContext *s) -{ - HLSContext *hls = s->priv_data; - AVFormatContext *oc; - int i; - - hls->avf = oc = avformat_alloc_context(); - if (!oc) - return AVERROR(ENOMEM); - - oc->oformat = hls->oformat; - oc->interrupt_callback = s->interrupt_callback; - - for (i = 0; i < s->nb_streams; i++) { - AVStream *st; - if (!(st = avformat_new_stream(oc, NULL))) - return AVERROR(ENOMEM); - avcodec_copy_context(st->codec, s->streams[i]->codec); - st->sample_aspect_ratio = s->streams[i]->sample_aspect_ratio; - } - - return 0; -} - -static int append_entry(HLSContext *hls, uint64_t duration) -{ - ListEntry *en = av_malloc(sizeof(*en)); - - if (!en) - return AVERROR(ENOMEM); - - av_strlcpy(en->name, av_basename(hls->avf->filename), sizeof(en->name)); - - en->duration = duration; - en->next = NULL; - - if (!hls->list) - hls->list = en; - else - hls->end_list->next = en; - - hls->end_list = en; - - if (hls->nb_entries >= hls->size) { - en = hls->list; - hls->list = en->next; - av_free(en); - } else - hls->nb_entries++; - - hls->sequence++; - - return 0; -} - -static void free_entries(HLSContext *hls) -{ - ListEntry *p = hls->list, *en; - - while(p) { - en = p; - p = p->next; - av_free(en); - } -} - -static int hls_window(AVFormatContext *s, int last) -{ - HLSContext *hls = s->priv_data; - ListEntry *en; - int target_duration = 0; - int ret = 0; - - if ((ret = avio_open2(&hls->pb, s->filename, AVIO_FLAG_WRITE, - &s->interrupt_callback, NULL)) < 0) - goto fail; - - for (en = hls->list; en; en = en->next) { - if (target_duration < en->duration) - target_duration = en->duration; - } - - avio_printf(hls->pb, "#EXTM3U\n"); - avio_printf(hls->pb, "#EXT-X-VERSION:3\n"); - avio_printf(hls->pb, "#EXT-X-TARGETDURATION:%d\n", target_duration); - avio_printf(hls->pb, "#EXT-X-MEDIA-SEQUENCE:%"PRId64"\n", - FFMAX(0, hls->sequence - hls->size)); - - for (en = hls->list; en; en = en->next) { - avio_printf(hls->pb, "#EXTINF:%d,\n", en->duration); - avio_printf(hls->pb, "%s\n", en->name); - } - - if (last) - avio_printf(hls->pb, "#EXT-X-ENDLIST\n"); - -fail: - avio_closep(&hls->pb); - return ret; -} - -static int hls_start(AVFormatContext *s) -{ - HLSContext *c = s->priv_data; - AVFormatContext *oc = c->avf; - int err = 0; - - if (c->wrap) - c->number %= c->wrap; - - if (av_get_frame_filename(oc->filename, sizeof(oc->filename), - c->basename, c->number++) < 0) { - av_log(oc, AV_LOG_ERROR, "Invalid segment filename template '%s'\n", c->basename); - return AVERROR(EINVAL); - } - - if ((err = avio_open2(&oc->pb, oc->filename, AVIO_FLAG_WRITE, - &s->interrupt_callback, NULL)) < 0) - return err; - - if (oc->oformat->priv_class && oc->priv_data) - av_opt_set(oc->priv_data, "mpegts_flags", "resend_headers", 0); - - return 0; -} - -static int hls_write_header(AVFormatContext *s) -{ - HLSContext *hls = s->priv_data; - int ret, i; - char *p; - const char *pattern = "%d.ts"; - int basename_size = strlen(s->filename) + strlen(pattern) + 1; - - hls->number = 0; - - hls->recording_time = hls->time * AV_TIME_BASE; - hls->start_pts = AV_NOPTS_VALUE; - - for (i = 0; i < s->nb_streams; i++) - hls->has_video += - s->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO; - - if (hls->has_video > 1) - av_log(s, AV_LOG_WARNING, - "More than a single video stream present, " - "expect issues decoding it.\n"); - - hls->oformat = av_guess_format("mpegts", NULL, NULL); - - if (!hls->oformat) { - ret = AVERROR_MUXER_NOT_FOUND; - goto fail; - } - - hls->basename = av_malloc(basename_size); - - if (!hls->basename) { - ret = AVERROR(ENOMEM); - goto fail; - } - - strcpy(hls->basename, s->filename); - - p = strrchr(hls->basename, '.'); - - if (p) - *p = '\0'; - - av_strlcat(hls->basename, pattern, basename_size); - - if ((ret = hls_mux_init(s)) < 0) - goto fail; - - if ((ret = hls_start(s)) < 0) - goto fail; - - if ((ret = avformat_write_header(hls->avf, NULL)) < 0) - return ret; - - -fail: - if (ret) { - av_free(hls->basename); - if (hls->avf) - avformat_free_context(hls->avf); - } - return ret; -} - -static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - HLSContext *hls = s->priv_data; - AVFormatContext *oc = hls->avf; - AVStream *st = s->streams[pkt->stream_index]; - int64_t end_pts = hls->recording_time * hls->number; - int ret, is_ref_pkt = 0; - - if (hls->start_pts == AV_NOPTS_VALUE) { - hls->start_pts = pkt->pts; - hls->end_pts = pkt->pts; - } - - if ((hls->has_video && st->codec->codec_type == AVMEDIA_TYPE_VIDEO) && - pkt->pts != AV_NOPTS_VALUE) { - is_ref_pkt = 1; - hls->duration = av_rescale(pkt->pts - hls->end_pts, - st->time_base.num, st->time_base.den); - } - - if (is_ref_pkt && - av_compare_ts(pkt->pts - hls->start_pts, st->time_base, - end_pts, AV_TIME_BASE_Q) >= 0 && - pkt->flags & AV_PKT_FLAG_KEY) { - - ret = append_entry(hls, hls->duration); - if (ret) - return ret; - - hls->end_pts = pkt->pts; - hls->duration = 0; - - av_write_frame(oc, NULL); /* Flush any buffered data */ - avio_close(oc->pb); - - ret = hls_start(s); - - if (ret) - return ret; - - oc = hls->avf; - - if ((ret = hls_window(s, 0)) < 0) - return ret; - } - - ret = ff_write_chained(oc, pkt->stream_index, pkt, s); - - return ret; -} - -static int hls_write_trailer(struct AVFormatContext *s) -{ - HLSContext *hls = s->priv_data; - AVFormatContext *oc = hls->avf; - - av_write_trailer(oc); - avio_closep(&oc->pb); - avformat_free_context(oc); - av_free(hls->basename); - append_entry(hls, hls->duration); - hls_window(s, 1); - - free_entries(hls); - avio_close(hls->pb); - return 0; -} - -#define OFFSET(x) offsetof(HLSContext, x) -#define E AV_OPT_FLAG_ENCODING_PARAM -static const AVOption options[] = { - {"start_number", "set first number in the sequence", OFFSET(sequence),AV_OPT_TYPE_INT64, {.i64 = 0}, 0, INT64_MAX, E}, - {"hls_time", "set segment length in seconds", OFFSET(time), AV_OPT_TYPE_FLOAT, {.dbl = 2}, 0, FLT_MAX, E}, - {"hls_list_size", "set maximum number of playlist entries", OFFSET(size), AV_OPT_TYPE_INT, {.i64 = 5}, 0, INT_MAX, E}, - {"hls_wrap", "set number after which the index wraps", OFFSET(wrap), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E}, - { NULL }, -}; - -static const AVClass hls_class = { - .class_name = "hls muxer", - .item_name = av_default_item_name, - .option = options, - .version = LIBAVUTIL_VERSION_INT, -}; - - -AVOutputFormat ff_hls_muxer = { - .name = "hls", - .long_name = NULL_IF_CONFIG_SMALL("Apple HTTP Live Streaming"), - .extensions = "m3u8", - .priv_data_size = sizeof(HLSContext), - .audio_codec = AV_CODEC_ID_MP2, - .video_codec = AV_CODEC_ID_MPEG2VIDEO, - .flags = AVFMT_NOFILE | AVFMT_ALLOW_FLUSH, - .write_header = hls_write_header, - .write_packet = hls_write_packet, - .write_trailer = hls_write_trailer, - .priv_class = &hls_class, -}; diff --git a/ffmpeg1/libavformat/hlsproto.c b/ffmpeg1/libavformat/hlsproto.c deleted file mode 100644 index 4e35043..0000000 --- a/ffmpeg1/libavformat/hlsproto.c +++ /dev/null @@ -1,323 +0,0 @@ -/* - * Apple HTTP Live Streaming Protocol Handler - * Copyright (c) 2010 Martin Storsjo - * - * 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 - */ - -/** - * @file - * Apple HTTP Live Streaming Protocol Handler - * http://tools.ietf.org/html/draft-pantos-http-live-streaming - */ - -#include "libavutil/avstring.h" -#include "libavutil/time.h" -#include "avformat.h" -#include "internal.h" -#include "url.h" -#include "version.h" - -/* - * An apple http stream consists of a playlist with media segment files, - * played sequentially. There may be several playlists with the same - * video content, in different bandwidth variants, that are played in - * parallel (preferably only one bandwidth variant at a time). In this case, - * the user supplied the url to a main playlist that only lists the variant - * playlists. - * - * If the main playlist doesn't point at any variants, we still create - * one anonymous toplevel variant for this, to maintain the structure. - */ - -struct segment { - int duration; - char url[MAX_URL_SIZE]; -}; - -struct variant { - int bandwidth; - char url[MAX_URL_SIZE]; -}; - -typedef struct HLSContext { - char playlisturl[MAX_URL_SIZE]; - int target_duration; - int start_seq_no; - int finished; - int n_segments; - struct segment **segments; - int n_variants; - struct variant **variants; - int cur_seq_no; - URLContext *seg_hd; - int64_t last_load_time; -} HLSContext; - -static int read_chomp_line(AVIOContext *s, char *buf, int maxlen) -{ - int len = ff_get_line(s, buf, maxlen); - while (len > 0 && av_isspace(buf[len - 1])) - buf[--len] = '\0'; - return len; -} - -static void free_segment_list(HLSContext *s) -{ - int i; - for (i = 0; i < s->n_segments; i++) - av_free(s->segments[i]); - av_freep(&s->segments); - s->n_segments = 0; -} - -static void free_variant_list(HLSContext *s) -{ - int i; - for (i = 0; i < s->n_variants; i++) - av_free(s->variants[i]); - av_freep(&s->variants); - s->n_variants = 0; -} - -struct variant_info { - char bandwidth[20]; -}; - -static void handle_variant_args(struct variant_info *info, const char *key, - int key_len, char **dest, int *dest_len) -{ - if (!strncmp(key, "BANDWIDTH=", key_len)) { - *dest = info->bandwidth; - *dest_len = sizeof(info->bandwidth); - } -} - -static int parse_playlist(URLContext *h, const char *url) -{ - HLSContext *s = h->priv_data; - AVIOContext *in; - int ret = 0, duration = 0, is_segment = 0, is_variant = 0, bandwidth = 0; - char line[1024]; - const char *ptr; - - if ((ret = avio_open2(&in, url, AVIO_FLAG_READ, - &h->interrupt_callback, NULL)) < 0) - return ret; - - read_chomp_line(in, line, sizeof(line)); - if (strcmp(line, "#EXTM3U")) - return AVERROR_INVALIDDATA; - - free_segment_list(s); - s->finished = 0; - while (!url_feof(in)) { - read_chomp_line(in, line, sizeof(line)); - if (av_strstart(line, "#EXT-X-STREAM-INF:", &ptr)) { - struct variant_info info = {{0}}; - is_variant = 1; - ff_parse_key_value(ptr, (ff_parse_key_val_cb) handle_variant_args, - &info); - bandwidth = atoi(info.bandwidth); - } else if (av_strstart(line, "#EXT-X-TARGETDURATION:", &ptr)) { - s->target_duration = atoi(ptr); - } else if (av_strstart(line, "#EXT-X-MEDIA-SEQUENCE:", &ptr)) { - s->start_seq_no = atoi(ptr); - } else if (av_strstart(line, "#EXT-X-ENDLIST", &ptr)) { - s->finished = 1; - } else if (av_strstart(line, "#EXTINF:", &ptr)) { - is_segment = 1; - duration = atoi(ptr); - } else if (av_strstart(line, "#", NULL)) { - continue; - } else if (line[0]) { - if (is_segment) { - struct segment *seg = av_malloc(sizeof(struct segment)); - if (!seg) { - ret = AVERROR(ENOMEM); - goto fail; - } - seg->duration = duration; - ff_make_absolute_url(seg->url, sizeof(seg->url), url, line); - dynarray_add(&s->segments, &s->n_segments, seg); - is_segment = 0; - } else if (is_variant) { - struct variant *var = av_malloc(sizeof(struct variant)); - if (!var) { - ret = AVERROR(ENOMEM); - goto fail; - } - var->bandwidth = bandwidth; - ff_make_absolute_url(var->url, sizeof(var->url), url, line); - dynarray_add(&s->variants, &s->n_variants, var); - is_variant = 0; - } - } - } - s->last_load_time = av_gettime(); - -fail: - avio_close(in); - return ret; -} - -static int hls_close(URLContext *h) -{ - HLSContext *s = h->priv_data; - - free_segment_list(s); - free_variant_list(s); - ffurl_close(s->seg_hd); - return 0; -} - -static int hls_open(URLContext *h, const char *uri, int flags) -{ - HLSContext *s = h->priv_data; - int ret, i; - const char *nested_url; - - if (flags & AVIO_FLAG_WRITE) - return AVERROR(ENOSYS); - - h->is_streamed = 1; - - if (av_strstart(uri, "hls+", &nested_url)) { - av_strlcpy(s->playlisturl, nested_url, sizeof(s->playlisturl)); - } else if (av_strstart(uri, "hls://", &nested_url)) { - av_log(h, AV_LOG_ERROR, - "No nested protocol specified. Specify e.g. hls+http://%s\n", - nested_url); - ret = AVERROR(EINVAL); - goto fail; - } else { - av_log(h, AV_LOG_ERROR, "Unsupported url %s\n", uri); - ret = AVERROR(EINVAL); - goto fail; - } - av_log(h, AV_LOG_WARNING, - "Using the hls protocol is discouraged, please try using the " - "hls demuxer instead. The hls demuxer should be more complete " - "and work as well as the protocol implementation. (If not, " - "please report it.) To use the demuxer, simply use %s as url.\n", - s->playlisturl); - - if ((ret = parse_playlist(h, s->playlisturl)) < 0) - goto fail; - - if (s->n_segments == 0 && s->n_variants > 0) { - int max_bandwidth = 0, maxvar = -1; - for (i = 0; i < s->n_variants; i++) { - if (s->variants[i]->bandwidth > max_bandwidth || i == 0) { - max_bandwidth = s->variants[i]->bandwidth; - maxvar = i; - } - } - av_strlcpy(s->playlisturl, s->variants[maxvar]->url, - sizeof(s->playlisturl)); - if ((ret = parse_playlist(h, s->playlisturl)) < 0) - goto fail; - } - - if (s->n_segments == 0) { - av_log(h, AV_LOG_WARNING, "Empty playlist\n"); - ret = AVERROR(EIO); - goto fail; - } - s->cur_seq_no = s->start_seq_no; - if (!s->finished && s->n_segments >= 3) - s->cur_seq_no = s->start_seq_no + s->n_segments - 3; - - return 0; - -fail: - hls_close(h); - return ret; -} - -static int hls_read(URLContext *h, uint8_t *buf, int size) -{ - HLSContext *s = h->priv_data; - const char *url; - int ret; - int64_t reload_interval; - -start: - if (s->seg_hd) { - ret = ffurl_read(s->seg_hd, buf, size); - if (ret > 0) - return ret; - } - if (s->seg_hd) { - ffurl_close(s->seg_hd); - s->seg_hd = NULL; - s->cur_seq_no++; - } - reload_interval = s->n_segments > 0 ? - s->segments[s->n_segments - 1]->duration : - s->target_duration; - reload_interval *= 1000000; -retry: - if (!s->finished) { - int64_t now = av_gettime(); - if (now - s->last_load_time >= reload_interval) { - if ((ret = parse_playlist(h, s->playlisturl)) < 0) - return ret; - /* If we need to reload the playlist again below (if - * there's still no more segments), switch to a reload - * interval of half the target duration. */ - reload_interval = s->target_duration * 500000LL; - } - } - if (s->cur_seq_no < s->start_seq_no) { - av_log(h, AV_LOG_WARNING, - "skipping %d segments ahead, expired from playlist\n", - s->start_seq_no - s->cur_seq_no); - s->cur_seq_no = s->start_seq_no; - } - if (s->cur_seq_no - s->start_seq_no >= s->n_segments) { - if (s->finished) - return AVERROR_EOF; - while (av_gettime() - s->last_load_time < reload_interval) { - if (ff_check_interrupt(&h->interrupt_callback)) - return AVERROR_EXIT; - av_usleep(100*1000); - } - goto retry; - } - url = s->segments[s->cur_seq_no - s->start_seq_no]->url, - av_log(h, AV_LOG_DEBUG, "opening %s\n", url); - ret = ffurl_open(&s->seg_hd, url, AVIO_FLAG_READ, - &h->interrupt_callback, NULL); - if (ret < 0) { - if (ff_check_interrupt(&h->interrupt_callback)) - return AVERROR_EXIT; - av_log(h, AV_LOG_WARNING, "Unable to open %s\n", url); - s->cur_seq_no++; - goto retry; - } - goto start; -} - -URLProtocol ff_hls_protocol = { - .name = "hls", - .url_open = hls_open, - .url_read = hls_read, - .url_close = hls_close, - .flags = URL_PROTOCOL_FLAG_NESTED_SCHEME, - .priv_data_size = sizeof(HLSContext), -}; diff --git a/ffmpeg1/libavformat/http.c b/ffmpeg1/libavformat/http.c deleted file mode 100644 index 1e3cff7..0000000 --- a/ffmpeg1/libavformat/http.c +++ /dev/null @@ -1,945 +0,0 @@ -/* - * HTTP protocol for ffmpeg client - * Copyright (c) 2000, 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 - */ - -#include "libavutil/avstring.h" -#include "avformat.h" -#include "internal.h" -#include "network.h" -#include "http.h" -#include "os_support.h" -#include "httpauth.h" -#include "url.h" -#include "libavutil/opt.h" - -/* XXX: POST protocol is not completely implemented because ffmpeg uses - only a subset of it. */ - -/* The IO buffer size is unrelated to the max URL size in itself, but needs - * to be large enough to fit the full request headers (including long - * path names). - */ -#define BUFFER_SIZE MAX_URL_SIZE -#define MAX_REDIRECTS 8 - -typedef struct { - const AVClass *class; - URLContext *hd; - unsigned char buffer[BUFFER_SIZE], *buf_ptr, *buf_end; - int line_count; - int http_code; - int64_t chunksize; /**< Used if "Transfer-Encoding: chunked" otherwise -1. */ - char *content_type; - char *user_agent; - int64_t off, filesize; - char location[MAX_URL_SIZE]; - HTTPAuthState auth_state; - HTTPAuthState proxy_auth_state; - char *headers; - int willclose; /**< Set if the server correctly handles Connection: close and will close the connection after feeding us the content. */ - int seekable; /**< Control seekability, 0 = disable, 1 = enable, -1 = probe. */ - int chunked_post; - int end_chunked_post; /**< A flag which indicates if the end of chunked encoding has been sent. */ - int end_header; /**< A flag which indicates we have finished to read POST reply. */ - int multiple_requests; /**< A flag which indicates if we use persistent connections. */ - uint8_t *post_data; - int post_datalen; - int is_akamai; - int rw_timeout; - char *mime_type; - char *cookies; ///< holds newline (\n) delimited Set-Cookie header field values (without the "Set-Cookie: " field name) -} HTTPContext; - -#define OFFSET(x) offsetof(HTTPContext, x) -#define D AV_OPT_FLAG_DECODING_PARAM -#define E AV_OPT_FLAG_ENCODING_PARAM -#define DEC AV_OPT_FLAG_DECODING_PARAM -static const AVOption options[] = { -{"seekable", "control seekability of connection", OFFSET(seekable), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, D }, -{"chunked_post", "use chunked transfer-encoding for posts", OFFSET(chunked_post), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, E }, -{"headers", "set custom HTTP headers, can override built in default headers", OFFSET(headers), AV_OPT_TYPE_STRING, { 0 }, 0, 0, D|E }, -{"content_type", "force a content type", OFFSET(content_type), AV_OPT_TYPE_STRING, { 0 }, 0, 0, D|E }, -{"user-agent", "override User-Agent header", OFFSET(user_agent), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC}, -{"multiple_requests", "use persistent connections", OFFSET(multiple_requests), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, D|E }, -{"post_data", "set custom HTTP post data", OFFSET(post_data), AV_OPT_TYPE_BINARY, .flags = D|E }, -{"timeout", "set timeout of socket I/O operations", OFFSET(rw_timeout), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX, D|E }, -{"mime_type", "set MIME type", OFFSET(mime_type), AV_OPT_TYPE_STRING, {0}, 0, 0, 0 }, -{"cookies", "set cookies to be sent in applicable future requests, use newline delimited Set-Cookie HTTP field value syntax", OFFSET(cookies), AV_OPT_TYPE_STRING, {0}, 0, 0, 0 }, -{NULL} -}; -#define HTTP_CLASS(flavor)\ -static const AVClass flavor ## _context_class = {\ - .class_name = #flavor,\ - .item_name = av_default_item_name,\ - .option = options,\ - .version = LIBAVUTIL_VERSION_INT,\ -} - -HTTP_CLASS(http); -HTTP_CLASS(https); - -static int http_connect(URLContext *h, const char *path, const char *local_path, - const char *hoststr, const char *auth, - const char *proxyauth, int *new_location); - -void ff_http_init_auth_state(URLContext *dest, const URLContext *src) -{ - memcpy(&((HTTPContext*)dest->priv_data)->auth_state, - &((HTTPContext*)src->priv_data)->auth_state, sizeof(HTTPAuthState)); - memcpy(&((HTTPContext*)dest->priv_data)->proxy_auth_state, - &((HTTPContext*)src->priv_data)->proxy_auth_state, - sizeof(HTTPAuthState)); -} - -/* return non zero if error */ -static int http_open_cnx(URLContext *h) -{ - const char *path, *proxy_path, *lower_proto = "tcp", *local_path; - char hostname[1024], hoststr[1024], proto[10]; - char auth[1024], proxyauth[1024] = ""; - char path1[MAX_URL_SIZE]; - char buf[1024], urlbuf[MAX_URL_SIZE]; - int port, use_proxy, err, location_changed = 0, redirects = 0, attempts = 0; - HTTPAuthType cur_auth_type, cur_proxy_auth_type; - HTTPContext *s = h->priv_data; - - /* fill the dest addr */ - redo: - /* needed in any case to build the host string */ - av_url_split(proto, sizeof(proto), auth, sizeof(auth), - hostname, sizeof(hostname), &port, - path1, sizeof(path1), s->location); - ff_url_join(hoststr, sizeof(hoststr), NULL, NULL, hostname, port, NULL); - - proxy_path = getenv("http_proxy"); - use_proxy = !ff_http_match_no_proxy(getenv("no_proxy"), hostname) && - proxy_path != NULL && av_strstart(proxy_path, "http://", NULL); - - if (!strcmp(proto, "https")) { - lower_proto = "tls"; - use_proxy = 0; - if (port < 0) - port = 443; - } - if (port < 0) - port = 80; - - if (path1[0] == '\0') - path = "/"; - else - path = path1; - local_path = path; - if (use_proxy) { - /* Reassemble the request URL without auth string - we don't - * want to leak the auth to the proxy. */ - ff_url_join(urlbuf, sizeof(urlbuf), proto, NULL, hostname, port, "%s", - path1); - path = urlbuf; - av_url_split(NULL, 0, proxyauth, sizeof(proxyauth), - hostname, sizeof(hostname), &port, NULL, 0, proxy_path); - } - - ff_url_join(buf, sizeof(buf), lower_proto, NULL, hostname, port, NULL); - - if (!s->hd) { - AVDictionary *opts = NULL; - char opts_format[20]; - if (s->rw_timeout != -1) { - snprintf(opts_format, sizeof(opts_format), "%d", s->rw_timeout); - av_dict_set(&opts, "timeout", opts_format, 0); - } /* if option is not given, don't pass it and let tcp use its own default */ - err = ffurl_open(&s->hd, buf, AVIO_FLAG_READ_WRITE, - &h->interrupt_callback, &opts); - av_dict_free(&opts); - if (err < 0) - goto fail; - } - - cur_auth_type = s->auth_state.auth_type; - cur_proxy_auth_type = s->auth_state.auth_type; - if (http_connect(h, path, local_path, hoststr, auth, proxyauth, &location_changed) < 0) - goto fail; - attempts++; - if (s->http_code == 401) { - if ((cur_auth_type == HTTP_AUTH_NONE || s->auth_state.stale) && - s->auth_state.auth_type != HTTP_AUTH_NONE && attempts < 4) { - ffurl_closep(&s->hd); - goto redo; - } else - goto fail; - } - if (s->http_code == 407) { - if ((cur_proxy_auth_type == HTTP_AUTH_NONE || s->proxy_auth_state.stale) && - s->proxy_auth_state.auth_type != HTTP_AUTH_NONE && attempts < 4) { - ffurl_closep(&s->hd); - goto redo; - } else - goto fail; - } - if ((s->http_code == 301 || s->http_code == 302 || s->http_code == 303 || s->http_code == 307) - && location_changed == 1) { - /* url moved, get next */ - ffurl_closep(&s->hd); - if (redirects++ >= MAX_REDIRECTS) - return AVERROR(EIO); - /* Restart the authentication process with the new target, which - * might use a different auth mechanism. */ - memset(&s->auth_state, 0, sizeof(s->auth_state)); - attempts = 0; - location_changed = 0; - goto redo; - } - return 0; - fail: - if (s->hd) - ffurl_closep(&s->hd); - return AVERROR(EIO); -} - -int ff_http_do_new_request(URLContext *h, const char *uri) -{ - HTTPContext *s = h->priv_data; - - s->off = 0; - av_strlcpy(s->location, uri, sizeof(s->location)); - - return http_open_cnx(h); -} - -static int http_open(URLContext *h, const char *uri, int flags) -{ - HTTPContext *s = h->priv_data; - - if( s->seekable == 1 ) - h->is_streamed = 0; - else - h->is_streamed = 1; - - s->filesize = -1; - av_strlcpy(s->location, uri, sizeof(s->location)); - - if (s->headers) { - int len = strlen(s->headers); - if (len < 2 || strcmp("\r\n", s->headers + len - 2)) - av_log(h, AV_LOG_WARNING, "No trailing CRLF found in HTTP header.\n"); - } - - return http_open_cnx(h); -} -static int http_getc(HTTPContext *s) -{ - int len; - if (s->buf_ptr >= s->buf_end) { - len = ffurl_read(s->hd, s->buffer, BUFFER_SIZE); - if (len < 0) { - return len; - } else if (len == 0) { - return -1; - } else { - s->buf_ptr = s->buffer; - s->buf_end = s->buffer + len; - } - } - return *s->buf_ptr++; -} - -static int http_get_line(HTTPContext *s, char *line, int line_size) -{ - int ch; - char *q; - - q = line; - for(;;) { - ch = http_getc(s); - if (ch < 0) - return ch; - if (ch == '\n') { - /* process line */ - if (q > line && q[-1] == '\r') - q--; - *q = '\0'; - - return 0; - } else { - if ((q - line) < line_size - 1) - *q++ = ch; - } - } -} - -static int process_line(URLContext *h, char *line, int line_count, - int *new_location) -{ - HTTPContext *s = h->priv_data; - char *tag, *p, *end; - - /* end of header */ - if (line[0] == '\0') { - s->end_header = 1; - return 0; - } - - p = line; - if (line_count == 0) { - while (!av_isspace(*p) && *p != '\0') - p++; - while (av_isspace(*p)) - p++; - s->http_code = strtol(p, &end, 10); - - av_dlog(NULL, "http_code=%d\n", s->http_code); - - /* error codes are 4xx and 5xx, but regard 401 as a success, so we - * don't abort until all headers have been parsed. */ - if (s->http_code >= 400 && s->http_code < 600 && (s->http_code != 401 - || s->auth_state.auth_type != HTTP_AUTH_NONE) && - (s->http_code != 407 || s->proxy_auth_state.auth_type != HTTP_AUTH_NONE)) { - end += strspn(end, SPACE_CHARS); - av_log(h, AV_LOG_WARNING, "HTTP error %d %s\n", - s->http_code, end); - return -1; - } - } else { - while (*p != '\0' && *p != ':') - p++; - if (*p != ':') - return 1; - - *p = '\0'; - tag = line; - p++; - while (av_isspace(*p)) - p++; - if (!av_strcasecmp(tag, "Location")) { - av_strlcpy(s->location, p, sizeof(s->location)); - *new_location = 1; - } else if (!av_strcasecmp (tag, "Content-Length") && s->filesize == -1) { - s->filesize = strtoll(p, NULL, 10); - } else if (!av_strcasecmp (tag, "Content-Range")) { - /* "bytes $from-$to/$document_size" */ - const char *slash; - if (!strncmp (p, "bytes ", 6)) { - p += 6; - s->off = strtoll(p, NULL, 10); - if ((slash = strchr(p, '/')) && strlen(slash) > 0) - s->filesize = strtoll(slash+1, NULL, 10); - } - if (s->seekable == -1 && (!s->is_akamai || s->filesize != 2147483647)) - h->is_streamed = 0; /* we _can_ in fact seek */ - } else if (!av_strcasecmp(tag, "Accept-Ranges") && !strncmp(p, "bytes", 5) && s->seekable == -1) { - h->is_streamed = 0; - } else if (!av_strcasecmp (tag, "Transfer-Encoding") && !av_strncasecmp(p, "chunked", 7)) { - s->filesize = -1; - s->chunksize = 0; - } else if (!av_strcasecmp (tag, "WWW-Authenticate")) { - ff_http_auth_handle_header(&s->auth_state, tag, p); - } else if (!av_strcasecmp (tag, "Authentication-Info")) { - ff_http_auth_handle_header(&s->auth_state, tag, p); - } else if (!av_strcasecmp (tag, "Proxy-Authenticate")) { - ff_http_auth_handle_header(&s->proxy_auth_state, tag, p); - } else if (!av_strcasecmp (tag, "Connection")) { - if (!strcmp(p, "close")) - s->willclose = 1; - } else if (!av_strcasecmp (tag, "Server") && !av_strcasecmp (p, "AkamaiGHost")) { - s->is_akamai = 1; - } else if (!av_strcasecmp (tag, "Content-Type")) { - av_free(s->mime_type); s->mime_type = av_strdup(p); - } else if (!av_strcasecmp (tag, "Set-Cookie")) { - if (!s->cookies) { - if (!(s->cookies = av_strdup(p))) - return AVERROR(ENOMEM); - } else { - char *tmp = s->cookies; - size_t str_size = strlen(tmp) + strlen(p) + 2; - if (!(s->cookies = av_malloc(str_size))) { - s->cookies = tmp; - return AVERROR(ENOMEM); - } - snprintf(s->cookies, str_size, "%s\n%s", tmp, p); - av_free(tmp); - } - } - } - return 1; -} - -/** - * Create a string containing cookie values for use as a HTTP cookie header - * field value for a particular path and domain from the cookie values stored in - * the HTTP protocol context. The cookie string is stored in *cookies. - * - * @return a negative value if an error condition occurred, 0 otherwise - */ -static int get_cookies(HTTPContext *s, char **cookies, const char *path, - const char *domain) -{ - // cookie strings will look like Set-Cookie header field values. Multiple - // Set-Cookie fields will result in multiple values delimited by a newline - int ret = 0; - char *next, *cookie, *set_cookies = av_strdup(s->cookies), *cset_cookies = set_cookies; - - if (!set_cookies) return AVERROR(EINVAL); - - *cookies = NULL; - while ((cookie = av_strtok(set_cookies, "\n", &next))) { - int domain_offset = 0; - char *param, *next_param, *cdomain = NULL, *cpath = NULL, *cvalue = NULL; - set_cookies = NULL; - - while ((param = av_strtok(cookie, "; ", &next_param))) { - cookie = NULL; - if (!av_strncasecmp("path=", param, 5)) { - av_free(cpath); - cpath = av_strdup(¶m[5]); - } else if (!av_strncasecmp("domain=", param, 7)) { - av_free(cdomain); - cdomain = av_strdup(¶m[7]); - } else if (!av_strncasecmp("secure", param, 6) || - !av_strncasecmp("comment", param, 7) || - !av_strncasecmp("max-age", param, 7) || - !av_strncasecmp("version", param, 7)) { - // ignore Comment, Max-Age, Secure and Version - } else { - av_free(cvalue); - cvalue = av_strdup(param); - } - } - - // ensure all of the necessary values are valid - if (!cdomain || !cpath || !cvalue) { - av_log(s, AV_LOG_WARNING, - "Invalid cookie found, no value, path or domain specified\n"); - goto done_cookie; - } - - // check if the request path matches the cookie path - if (av_strncasecmp(path, cpath, strlen(cpath))) - goto done_cookie; - - // the domain should be at least the size of our cookie domain - domain_offset = strlen(domain) - strlen(cdomain); - if (domain_offset < 0) - goto done_cookie; - - // match the cookie domain - if (av_strcasecmp(&domain[domain_offset], cdomain)) - goto done_cookie; - - // cookie parameters match, so copy the value - if (!*cookies) { - if (!(*cookies = av_strdup(cvalue))) { - ret = AVERROR(ENOMEM); - goto done_cookie; - } - } else { - char *tmp = *cookies; - size_t str_size = strlen(cvalue) + strlen(*cookies) + 3; - if (!(*cookies = av_malloc(str_size))) { - ret = AVERROR(ENOMEM); - goto done_cookie; - } - snprintf(*cookies, str_size, "%s; %s", tmp, cvalue); - av_free(tmp); - } - - done_cookie: - av_free(cdomain); - av_free(cpath); - av_free(cvalue); - if (ret < 0) { - if (*cookies) av_freep(cookies); - av_free(cset_cookies); - return ret; - } - } - - av_free(cset_cookies); - - return 0; -} - -static inline int has_header(const char *str, const char *header) -{ - /* header + 2 to skip over CRLF prefix. (make sure you have one!) */ - if (!str) - return 0; - return av_stristart(str, header + 2, NULL) || av_stristr(str, header); -} - -static int http_read_header(URLContext *h, int *new_location) -{ - HTTPContext *s = h->priv_data; - char line[MAX_URL_SIZE]; - int err = 0; - - s->chunksize = -1; - - for (;;) { - if ((err = http_get_line(s, line, sizeof(line))) < 0) - return err; - - av_dlog(NULL, "header='%s'\n", line); - - err = process_line(h, line, s->line_count, new_location); - if (err < 0) - return err; - if (err == 0) - break; - s->line_count++; - } - - return err; -} - -static int http_connect(URLContext *h, const char *path, const char *local_path, - const char *hoststr, const char *auth, - const char *proxyauth, int *new_location) -{ - HTTPContext *s = h->priv_data; - int post, err; - char headers[4096] = ""; - char *authstr = NULL, *proxyauthstr = NULL; - int64_t off = s->off; - int len = 0; - const char *method; - - - /* send http header */ - post = h->flags & AVIO_FLAG_WRITE; - - if (s->post_data) { - /* force POST method and disable chunked encoding when - * custom HTTP post data is set */ - post = 1; - s->chunked_post = 0; - } - - method = post ? "POST" : "GET"; - authstr = ff_http_auth_create_response(&s->auth_state, auth, local_path, - method); - proxyauthstr = ff_http_auth_create_response(&s->proxy_auth_state, proxyauth, - local_path, method); - - /* set default headers if needed */ - if (!has_header(s->headers, "\r\nUser-Agent: ")) - len += av_strlcatf(headers + len, sizeof(headers) - len, - "User-Agent: %s\r\n", - s->user_agent ? s->user_agent : LIBAVFORMAT_IDENT); - if (!has_header(s->headers, "\r\nAccept: ")) - len += av_strlcpy(headers + len, "Accept: */*\r\n", - sizeof(headers) - len); - // Note: we send this on purpose even when s->off is 0 when we're probing, - // since it allows us to detect more reliably if a (non-conforming) - // server supports seeking by analysing the reply headers. - if (!has_header(s->headers, "\r\nRange: ") && !post && (s->off > 0 || s->seekable == -1)) - len += av_strlcatf(headers + len, sizeof(headers) - len, - "Range: bytes=%"PRId64"-\r\n", s->off); - - if (!has_header(s->headers, "\r\nConnection: ")) { - if (s->multiple_requests) { - len += av_strlcpy(headers + len, "Connection: keep-alive\r\n", - sizeof(headers) - len); - } else { - len += av_strlcpy(headers + len, "Connection: close\r\n", - sizeof(headers) - len); - } - } - - if (!has_header(s->headers, "\r\nHost: ")) - len += av_strlcatf(headers + len, sizeof(headers) - len, - "Host: %s\r\n", hoststr); - if (!has_header(s->headers, "\r\nContent-Length: ") && s->post_data) - len += av_strlcatf(headers + len, sizeof(headers) - len, - "Content-Length: %d\r\n", s->post_datalen); - if (!has_header(s->headers, "\r\nContent-Type: ") && s->content_type) - len += av_strlcatf(headers + len, sizeof(headers) - len, - "Content-Type: %s\r\n", s->content_type); - if (!has_header(s->headers, "\r\nCookie: ") && s->cookies) { - char *cookies = NULL; - if (!get_cookies(s, &cookies, path, hoststr)) { - len += av_strlcatf(headers + len, sizeof(headers) - len, - "Cookie: %s\r\n", cookies); - av_free(cookies); - } - } - - /* now add in custom headers */ - if (s->headers) - av_strlcpy(headers + len, s->headers, sizeof(headers) - len); - - snprintf(s->buffer, sizeof(s->buffer), - "%s %s HTTP/1.1\r\n" - "%s" - "%s" - "%s" - "%s%s" - "\r\n", - method, - path, - post && s->chunked_post ? "Transfer-Encoding: chunked\r\n" : "", - headers, - authstr ? authstr : "", - proxyauthstr ? "Proxy-" : "", proxyauthstr ? proxyauthstr : ""); - - av_freep(&authstr); - av_freep(&proxyauthstr); - if ((err = ffurl_write(s->hd, s->buffer, strlen(s->buffer))) < 0) - return err; - - if (s->post_data) - if ((err = ffurl_write(s->hd, s->post_data, s->post_datalen)) < 0) - return err; - - /* init input buffer */ - s->buf_ptr = s->buffer; - s->buf_end = s->buffer; - s->line_count = 0; - s->off = 0; - s->filesize = -1; - s->willclose = 0; - s->end_chunked_post = 0; - s->end_header = 0; - if (post && !s->post_data) { - /* Pretend that it did work. We didn't read any header yet, since - * we've still to send the POST data, but the code calling this - * function will check http_code after we return. */ - s->http_code = 200; - return 0; - } - - /* wait for header */ - err = http_read_header(h, new_location); - if (err < 0) - return err; - - return (off == s->off) ? 0 : -1; -} - - -static int http_buf_read(URLContext *h, uint8_t *buf, int size) -{ - HTTPContext *s = h->priv_data; - int len; - /* read bytes from input buffer first */ - len = s->buf_end - s->buf_ptr; - if (len > 0) { - if (len > size) - len = size; - memcpy(buf, s->buf_ptr, len); - s->buf_ptr += len; - } else { - if (!s->willclose && s->filesize >= 0 && s->off >= s->filesize) - return AVERROR_EOF; - len = ffurl_read(s->hd, buf, size); - } - if (len > 0) { - s->off += len; - if (s->chunksize > 0) - s->chunksize -= len; - } - return len; -} - -static int http_read(URLContext *h, uint8_t *buf, int size) -{ - HTTPContext *s = h->priv_data; - int err, new_location; - - if (!s->hd) - return AVERROR_EOF; - - if (s->end_chunked_post && !s->end_header) { - err = http_read_header(h, &new_location); - if (err < 0) - return err; - } - - if (s->chunksize >= 0) { - if (!s->chunksize) { - char line[32]; - - for(;;) { - do { - if ((err = http_get_line(s, line, sizeof(line))) < 0) - return err; - } while (!*line); /* skip CR LF from last chunk */ - - s->chunksize = strtoll(line, NULL, 16); - - av_dlog(NULL, "Chunked encoding data size: %"PRId64"'\n", s->chunksize); - - if (!s->chunksize) - return 0; - break; - } - } - size = FFMIN(size, s->chunksize); - } - return http_buf_read(h, buf, size); -} - -/* used only when posting data */ -static int http_write(URLContext *h, const uint8_t *buf, int size) -{ - char temp[11] = ""; /* 32-bit hex + CRLF + nul */ - int ret; - char crlf[] = "\r\n"; - HTTPContext *s = h->priv_data; - - if (!s->chunked_post) { - /* non-chunked data is sent without any special encoding */ - return ffurl_write(s->hd, buf, size); - } - - /* silently ignore zero-size data since chunk encoding that would - * signal EOF */ - if (size > 0) { - /* upload data using chunked encoding */ - snprintf(temp, sizeof(temp), "%x\r\n", size); - - if ((ret = ffurl_write(s->hd, temp, strlen(temp))) < 0 || - (ret = ffurl_write(s->hd, buf, size)) < 0 || - (ret = ffurl_write(s->hd, crlf, sizeof(crlf) - 1)) < 0) - return ret; - } - return size; -} - -static int http_shutdown(URLContext *h, int flags) -{ - int ret = 0; - char footer[] = "0\r\n\r\n"; - HTTPContext *s = h->priv_data; - - /* signal end of chunked encoding if used */ - if ((flags & AVIO_FLAG_WRITE) && s->chunked_post) { - ret = ffurl_write(s->hd, footer, sizeof(footer) - 1); - ret = ret > 0 ? 0 : ret; - s->end_chunked_post = 1; - } - - return ret; -} - -static int http_close(URLContext *h) -{ - int ret = 0; - HTTPContext *s = h->priv_data; - - if (!s->end_chunked_post) { - /* Close the write direction by sending the end of chunked encoding. */ - ret = http_shutdown(h, h->flags); - } - - if (s->hd) - ffurl_closep(&s->hd); - return ret; -} - -static int64_t http_seek(URLContext *h, int64_t off, int whence) -{ - HTTPContext *s = h->priv_data; - URLContext *old_hd = s->hd; - int64_t old_off = s->off; - uint8_t old_buf[BUFFER_SIZE]; - int old_buf_size; - - if (whence == AVSEEK_SIZE) - return s->filesize; - else if ((s->filesize == -1 && whence == SEEK_END) || h->is_streamed) - return -1; - - /* we save the old context in case the seek fails */ - old_buf_size = s->buf_end - s->buf_ptr; - memcpy(old_buf, s->buf_ptr, old_buf_size); - s->hd = NULL; - if (whence == SEEK_CUR) - off += s->off; - else if (whence == SEEK_END) - off += s->filesize; - s->off = off; - - /* if it fails, continue on old connection */ - if (http_open_cnx(h) < 0) { - memcpy(s->buffer, old_buf, old_buf_size); - s->buf_ptr = s->buffer; - s->buf_end = s->buffer + old_buf_size; - s->hd = old_hd; - s->off = old_off; - return -1; - } - ffurl_close(old_hd); - return off; -} - -static int -http_get_file_handle(URLContext *h) -{ - HTTPContext *s = h->priv_data; - return ffurl_get_file_handle(s->hd); -} - -#if CONFIG_HTTP_PROTOCOL -URLProtocol ff_http_protocol = { - .name = "http", - .url_open = http_open, - .url_read = http_read, - .url_write = http_write, - .url_seek = http_seek, - .url_close = http_close, - .url_get_file_handle = http_get_file_handle, - .url_shutdown = http_shutdown, - .priv_data_size = sizeof(HTTPContext), - .priv_data_class = &http_context_class, - .flags = URL_PROTOCOL_FLAG_NETWORK, -}; -#endif -#if CONFIG_HTTPS_PROTOCOL -URLProtocol ff_https_protocol = { - .name = "https", - .url_open = http_open, - .url_read = http_read, - .url_write = http_write, - .url_seek = http_seek, - .url_close = http_close, - .url_get_file_handle = http_get_file_handle, - .url_shutdown = http_shutdown, - .priv_data_size = sizeof(HTTPContext), - .priv_data_class = &https_context_class, - .flags = URL_PROTOCOL_FLAG_NETWORK, -}; -#endif - -#if CONFIG_HTTPPROXY_PROTOCOL -static int http_proxy_close(URLContext *h) -{ - HTTPContext *s = h->priv_data; - if (s->hd) - ffurl_closep(&s->hd); - return 0; -} - -static int http_proxy_open(URLContext *h, const char *uri, int flags) -{ - HTTPContext *s = h->priv_data; - char hostname[1024], hoststr[1024]; - char auth[1024], pathbuf[1024], *path; - char lower_url[100]; - int port, ret = 0, attempts = 0; - HTTPAuthType cur_auth_type; - char *authstr; - int new_loc; - AVDictionary *opts = NULL; - char opts_format[20]; - - if( s->seekable == 1 ) - h->is_streamed = 0; - else - h->is_streamed = 1; - - av_url_split(NULL, 0, auth, sizeof(auth), hostname, sizeof(hostname), &port, - pathbuf, sizeof(pathbuf), uri); - ff_url_join(hoststr, sizeof(hoststr), NULL, NULL, hostname, port, NULL); - path = pathbuf; - if (*path == '/') - path++; - - ff_url_join(lower_url, sizeof(lower_url), "tcp", NULL, hostname, port, - NULL); -redo: - if (s->rw_timeout != -1) { - snprintf(opts_format, sizeof(opts_format), "%d", s->rw_timeout); - av_dict_set(&opts, "timeout", opts_format, 0); - } /* if option is not given, don't pass it and let tcp use its own default */ - ret = ffurl_open(&s->hd, lower_url, AVIO_FLAG_READ_WRITE, - &h->interrupt_callback, &opts); - av_dict_free(&opts); - if (ret < 0) - return ret; - - authstr = ff_http_auth_create_response(&s->proxy_auth_state, auth, - path, "CONNECT"); - snprintf(s->buffer, sizeof(s->buffer), - "CONNECT %s HTTP/1.1\r\n" - "Host: %s\r\n" - "Connection: close\r\n" - "%s%s" - "\r\n", - path, - hoststr, - authstr ? "Proxy-" : "", authstr ? authstr : ""); - av_freep(&authstr); - - if ((ret = ffurl_write(s->hd, s->buffer, strlen(s->buffer))) < 0) - goto fail; - - s->buf_ptr = s->buffer; - s->buf_end = s->buffer; - s->line_count = 0; - s->filesize = -1; - cur_auth_type = s->proxy_auth_state.auth_type; - - /* Note: This uses buffering, potentially reading more than the - * HTTP header. If tunneling a protocol where the server starts - * the conversation, we might buffer part of that here, too. - * Reading that requires using the proper ffurl_read() function - * on this URLContext, not using the fd directly (as the tls - * protocol does). This shouldn't be an issue for tls though, - * since the client starts the conversation there, so there - * is no extra data that we might buffer up here. - */ - ret = http_read_header(h, &new_loc); - if (ret < 0) - goto fail; - - attempts++; - if (s->http_code == 407 && - (cur_auth_type == HTTP_AUTH_NONE || s->proxy_auth_state.stale) && - s->proxy_auth_state.auth_type != HTTP_AUTH_NONE && attempts < 2) { - ffurl_closep(&s->hd); - goto redo; - } - - if (s->http_code < 400) - return 0; - ret = AVERROR(EIO); - -fail: - http_proxy_close(h); - return ret; -} - -static int http_proxy_write(URLContext *h, const uint8_t *buf, int size) -{ - HTTPContext *s = h->priv_data; - return ffurl_write(s->hd, buf, size); -} - -URLProtocol ff_httpproxy_protocol = { - .name = "httpproxy", - .url_open = http_proxy_open, - .url_read = http_buf_read, - .url_write = http_proxy_write, - .url_close = http_proxy_close, - .url_get_file_handle = http_get_file_handle, - .priv_data_size = sizeof(HTTPContext), - .flags = URL_PROTOCOL_FLAG_NETWORK, -}; -#endif diff --git a/ffmpeg1/libavformat/http.h b/ffmpeg1/libavformat/http.h deleted file mode 100644 index a19ad8e..0000000 --- a/ffmpeg1/libavformat/http.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * HTTP definitions - * Copyright (c) 2010 Josh Allmann - * - * 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 AVFORMAT_HTTP_H -#define AVFORMAT_HTTP_H - -#include "url.h" - -/** - * Initialize the authentication state based on another HTTP URLContext. - * This can be used to pre-initialize the authentication parameters if - * they are known beforehand, to avoid having to do an initial failing - * request just to get the parameters. - * - * @param dest URL context whose authentication state gets updated - * @param src URL context whose authentication state gets copied - */ -void ff_http_init_auth_state(URLContext *dest, const URLContext *src); - -/** - * Send a new HTTP request, reusing the old connection. - * - * @param h pointer to the resource - * @param uri uri used to perform the request - * @return a negative value if an error condition occurred, 0 - * otherwise - */ -int ff_http_do_new_request(URLContext *h, const char *uri); - -#endif /* AVFORMAT_HTTP_H */ diff --git a/ffmpeg1/libavformat/httpauth.c b/ffmpeg1/libavformat/httpauth.c deleted file mode 100644 index 5ca48b9..0000000 --- a/ffmpeg1/libavformat/httpauth.c +++ /dev/null @@ -1,287 +0,0 @@ -/* - * HTTP authentication - * Copyright (c) 2010 Martin Storsjo - * - * 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 "httpauth.h" -#include "libavutil/base64.h" -#include "libavutil/avstring.h" -#include "internal.h" -#include "libavutil/random_seed.h" -#include "libavutil/md5.h" -#include "urldecode.h" -#include "avformat.h" - -static void handle_basic_params(HTTPAuthState *state, const char *key, - int key_len, char **dest, int *dest_len) -{ - if (!strncmp(key, "realm=", key_len)) { - *dest = state->realm; - *dest_len = sizeof(state->realm); - } -} - -static void handle_digest_params(HTTPAuthState *state, const char *key, - int key_len, char **dest, int *dest_len) -{ - DigestParams *digest = &state->digest_params; - - if (!strncmp(key, "realm=", key_len)) { - *dest = state->realm; - *dest_len = sizeof(state->realm); - } else if (!strncmp(key, "nonce=", key_len)) { - *dest = digest->nonce; - *dest_len = sizeof(digest->nonce); - } else if (!strncmp(key, "opaque=", key_len)) { - *dest = digest->opaque; - *dest_len = sizeof(digest->opaque); - } else if (!strncmp(key, "algorithm=", key_len)) { - *dest = digest->algorithm; - *dest_len = sizeof(digest->algorithm); - } else if (!strncmp(key, "qop=", key_len)) { - *dest = digest->qop; - *dest_len = sizeof(digest->qop); - } else if (!strncmp(key, "stale=", key_len)) { - *dest = digest->stale; - *dest_len = sizeof(digest->stale); - } -} - -static void handle_digest_update(HTTPAuthState *state, const char *key, - int key_len, char **dest, int *dest_len) -{ - DigestParams *digest = &state->digest_params; - - if (!strncmp(key, "nextnonce=", key_len)) { - *dest = digest->nonce; - *dest_len = sizeof(digest->nonce); - } -} - -static void choose_qop(char *qop, int size) -{ - char *ptr = strstr(qop, "auth"); - char *end = ptr + strlen("auth"); - - if (ptr && (!*end || av_isspace(*end) || *end == ',') && - (ptr == qop || av_isspace(ptr[-1]) || ptr[-1] == ',')) { - av_strlcpy(qop, "auth", size); - } else { - qop[0] = 0; - } -} - -void ff_http_auth_handle_header(HTTPAuthState *state, const char *key, - const char *value) -{ - if (!strcmp(key, "WWW-Authenticate") || !strcmp(key, "Proxy-Authenticate")) { - const char *p; - if (av_stristart(value, "Basic ", &p) && - state->auth_type <= HTTP_AUTH_BASIC) { - state->auth_type = HTTP_AUTH_BASIC; - state->realm[0] = 0; - state->stale = 0; - ff_parse_key_value(p, (ff_parse_key_val_cb) handle_basic_params, - state); - } else if (av_stristart(value, "Digest ", &p) && - state->auth_type <= HTTP_AUTH_DIGEST) { - state->auth_type = HTTP_AUTH_DIGEST; - memset(&state->digest_params, 0, sizeof(DigestParams)); - state->realm[0] = 0; - state->stale = 0; - ff_parse_key_value(p, (ff_parse_key_val_cb) handle_digest_params, - state); - choose_qop(state->digest_params.qop, - sizeof(state->digest_params.qop)); - if (!av_strcasecmp(state->digest_params.stale, "true")) - state->stale = 1; - } - } else if (!strcmp(key, "Authentication-Info")) { - ff_parse_key_value(value, (ff_parse_key_val_cb) handle_digest_update, - state); - } -} - - -static void update_md5_strings(struct AVMD5 *md5ctx, ...) -{ - va_list vl; - - va_start(vl, md5ctx); - while (1) { - const char* str = va_arg(vl, const char*); - if (!str) - break; - av_md5_update(md5ctx, str, strlen(str)); - } - va_end(vl); -} - -/* Generate a digest reply, according to RFC 2617. */ -static char *make_digest_auth(HTTPAuthState *state, const char *username, - const char *password, const char *uri, - const char *method) -{ - DigestParams *digest = &state->digest_params; - int len; - uint32_t cnonce_buf[2]; - char cnonce[17]; - char nc[9]; - int i; - char A1hash[33], A2hash[33], response[33]; - struct AVMD5 *md5ctx; - uint8_t hash[16]; - char *authstr; - - digest->nc++; - snprintf(nc, sizeof(nc), "%08x", digest->nc); - - /* Generate a client nonce. */ - for (i = 0; i < 2; i++) - cnonce_buf[i] = av_get_random_seed(); - ff_data_to_hex(cnonce, (const uint8_t*) cnonce_buf, sizeof(cnonce_buf), 1); - cnonce[2*sizeof(cnonce_buf)] = 0; - - md5ctx = av_md5_alloc(); - if (!md5ctx) - return NULL; - - av_md5_init(md5ctx); - update_md5_strings(md5ctx, username, ":", state->realm, ":", password, NULL); - av_md5_final(md5ctx, hash); - ff_data_to_hex(A1hash, hash, 16, 1); - A1hash[32] = 0; - - if (!strcmp(digest->algorithm, "") || !strcmp(digest->algorithm, "MD5")) { - } else if (!strcmp(digest->algorithm, "MD5-sess")) { - av_md5_init(md5ctx); - update_md5_strings(md5ctx, A1hash, ":", digest->nonce, ":", cnonce, NULL); - av_md5_final(md5ctx, hash); - ff_data_to_hex(A1hash, hash, 16, 1); - A1hash[32] = 0; - } else { - /* Unsupported algorithm */ - av_free(md5ctx); - return NULL; - } - - av_md5_init(md5ctx); - update_md5_strings(md5ctx, method, ":", uri, NULL); - av_md5_final(md5ctx, hash); - ff_data_to_hex(A2hash, hash, 16, 1); - A2hash[32] = 0; - - av_md5_init(md5ctx); - update_md5_strings(md5ctx, A1hash, ":", digest->nonce, NULL); - if (!strcmp(digest->qop, "auth") || !strcmp(digest->qop, "auth-int")) { - update_md5_strings(md5ctx, ":", nc, ":", cnonce, ":", digest->qop, NULL); - } - update_md5_strings(md5ctx, ":", A2hash, NULL); - av_md5_final(md5ctx, hash); - ff_data_to_hex(response, hash, 16, 1); - response[32] = 0; - - av_free(md5ctx); - - if (!strcmp(digest->qop, "") || !strcmp(digest->qop, "auth")) { - } else if (!strcmp(digest->qop, "auth-int")) { - /* qop=auth-int not supported */ - return NULL; - } else { - /* Unsupported qop value. */ - return NULL; - } - - len = strlen(username) + strlen(state->realm) + strlen(digest->nonce) + - strlen(uri) + strlen(response) + strlen(digest->algorithm) + - strlen(digest->opaque) + strlen(digest->qop) + strlen(cnonce) + - strlen(nc) + 150; - - authstr = av_malloc(len); - if (!authstr) - return NULL; - snprintf(authstr, len, "Authorization: Digest "); - - /* TODO: Escape the quoted strings properly. */ - av_strlcatf(authstr, len, "username=\"%s\"", username); - av_strlcatf(authstr, len, ",realm=\"%s\"", state->realm); - av_strlcatf(authstr, len, ",nonce=\"%s\"", digest->nonce); - av_strlcatf(authstr, len, ",uri=\"%s\"", uri); - av_strlcatf(authstr, len, ",response=\"%s\"", response); - if (digest->algorithm[0]) - av_strlcatf(authstr, len, ",algorithm=%s", digest->algorithm); - if (digest->opaque[0]) - av_strlcatf(authstr, len, ",opaque=\"%s\"", digest->opaque); - if (digest->qop[0]) { - av_strlcatf(authstr, len, ",qop=\"%s\"", digest->qop); - av_strlcatf(authstr, len, ",cnonce=\"%s\"", cnonce); - av_strlcatf(authstr, len, ",nc=%s", nc); - } - - av_strlcatf(authstr, len, "\r\n"); - - return authstr; -} - -char *ff_http_auth_create_response(HTTPAuthState *state, const char *auth, - const char *path, const char *method) -{ - char *authstr = NULL; - - /* Clear the stale flag, we assume the auth is ok now. It is reset - * by the server headers if there's a new issue. */ - state->stale = 0; - if (!auth || !strchr(auth, ':')) - return NULL; - - if (state->auth_type == HTTP_AUTH_BASIC) { - int auth_b64_len, len; - char *ptr, *decoded_auth = ff_urldecode(auth); - - if (!decoded_auth) - return NULL; - - auth_b64_len = AV_BASE64_SIZE(strlen(decoded_auth)); - len = auth_b64_len + 30; - - authstr = av_malloc(len); - if (!authstr) { - av_free(decoded_auth); - return NULL; - } - - snprintf(authstr, len, "Authorization: Basic "); - ptr = authstr + strlen(authstr); - av_base64_encode(ptr, auth_b64_len, decoded_auth, strlen(decoded_auth)); - av_strlcat(ptr, "\r\n", len - (ptr - authstr)); - av_free(decoded_auth); - } else if (state->auth_type == HTTP_AUTH_DIGEST) { - char *username = ff_urldecode(auth), *password; - - if (!username) - return NULL; - - if ((password = strchr(username, ':'))) { - *password++ = 0; - authstr = make_digest_auth(state, username, password, path, method); - } - av_free(username); - } - return authstr; -} diff --git a/ffmpeg1/libavformat/httpauth.h b/ffmpeg1/libavformat/httpauth.h deleted file mode 100644 index fc17c94..0000000 --- a/ffmpeg1/libavformat/httpauth.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * HTTP authentication - * Copyright (c) 2010 Martin Storsjo - * - * 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 AVFORMAT_HTTPAUTH_H -#define AVFORMAT_HTTPAUTH_H - -/** - * Authentication types, ordered from weakest to strongest. - */ -typedef enum HTTPAuthType { - HTTP_AUTH_NONE = 0, /**< No authentication specified */ - HTTP_AUTH_BASIC, /**< HTTP 1.0 Basic auth from RFC 1945 - * (also in RFC 2617) */ - HTTP_AUTH_DIGEST, /**< HTTP 1.1 Digest auth from RFC 2617 */ -} HTTPAuthType; - -typedef struct DigestParams { - char nonce[300]; /**< Server specified nonce */ - char algorithm[10]; /**< Server specified digest algorithm */ - char qop[30]; /**< Quality of protection, containing the one - * that we've chosen to use, from the - * alternatives that the server offered. */ - char opaque[300]; /**< A server-specified string that should be - * included in authentication responses, not - * included in the actual digest calculation. */ - char stale[10]; /**< The server indicated that the auth was ok, - * but needs to be redone with a new, non-stale - * nonce. */ - int nc; /**< Nonce count, the number of earlier replies - * where this particular nonce has been used. */ -} DigestParams; - -/** - * HTTP Authentication state structure. Must be zero-initialized - * before used with the functions below. - */ -typedef struct HTTPAuthState { - /** - * The currently chosen auth type. - */ - HTTPAuthType auth_type; - /** - * Authentication realm - */ - char realm[200]; - /** - * The parameters specifiec to digest authentication. - */ - DigestParams digest_params; - /** - * Auth ok, but needs to be resent with a new nonce. - */ - int stale; -} HTTPAuthState; - -void ff_http_auth_handle_header(HTTPAuthState *state, const char *key, - const char *value); -char *ff_http_auth_create_response(HTTPAuthState *state, const char *auth, - const char *path, const char *method); - -#endif /* AVFORMAT_HTTPAUTH_H */ diff --git a/ffmpeg1/libavformat/icodec.c b/ffmpeg1/libavformat/icodec.c deleted file mode 100644 index fa308da..0000000 --- a/ffmpeg1/libavformat/icodec.c +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Microsoft Windows ICO demuxer - * Copyright (c) 2011 Peter Ross (pross@xvid.org) - * - * 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 - */ - -/** - * @file - * Microsoft Windows ICO demuxer - */ - -#include "libavutil/intreadwrite.h" -#include "libavcodec/bytestream.h" -#include "libavcodec/bmp.h" -#include "avformat.h" -#include "internal.h" - -typedef struct { - int offset; - int size; - int nb_pal; -} IcoImage; - -typedef struct { - int current_image; - int nb_images; - IcoImage * images; -} IcoDemuxContext; - -static int probe(AVProbeData *p) -{ - if (AV_RL16(p->buf) == 0 && AV_RL16(p->buf + 2) == 1 && AV_RL16(p->buf + 4)) - return AVPROBE_SCORE_MAX / 3; - return 0; -} - -static int read_header(AVFormatContext *s) -{ - IcoDemuxContext *ico = s->priv_data; - AVIOContext *pb = s->pb; - int i, codec; - - avio_skip(pb, 4); - ico->nb_images = avio_rl16(pb); - - ico->images = av_malloc(ico->nb_images * sizeof(IcoImage)); - if (!ico->images) - return AVERROR(ENOMEM); - - for (i = 0; i < ico->nb_images; i++) { - AVStream *st; - int tmp; - - if (avio_seek(pb, 6 + i * 16, SEEK_SET) < 0) - break; - - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->width = avio_r8(pb); - st->codec->height = avio_r8(pb); - ico->images[i].nb_pal = avio_r8(pb); - if (ico->images[i].nb_pal == 255) - ico->images[i].nb_pal = 0; - - avio_skip(pb, 5); - - ico->images[i].size = avio_rl32(pb); - ico->images[i].offset = avio_rl32(pb); - - if (avio_seek(pb, ico->images[i].offset, SEEK_SET) < 0) - break; - - codec = avio_rl32(pb); - switch (codec) { - case MKTAG(0x89, 'P', 'N', 'G'): - st->codec->codec_id = AV_CODEC_ID_PNG; - st->codec->width = 0; - st->codec->height = 0; - break; - case 40: - if (ico->images[i].size < 40) - return AVERROR_INVALIDDATA; - st->codec->codec_id = AV_CODEC_ID_BMP; - tmp = avio_rl32(pb); - if (tmp) - st->codec->width = tmp; - tmp = avio_rl32(pb); - if (tmp) - st->codec->height = tmp / 2; - break; - default: - avpriv_request_sample(s, "codec %d", codec); - return AVERROR_INVALIDDATA; - } - } - - return 0; -} - -static int read_packet(AVFormatContext *s, AVPacket *pkt) -{ - IcoDemuxContext *ico = s->priv_data; - IcoImage *image; - AVIOContext *pb = s->pb; - AVStream *st = s->streams[0]; - int ret; - - if (ico->current_image >= ico->nb_images) - return AVERROR(EIO); - - image = &ico->images[ico->current_image]; - - if ((ret = avio_seek(pb, image->offset, SEEK_SET)) < 0) - return ret; - - if (s->streams[ico->current_image]->codec->codec_id == AV_CODEC_ID_PNG) { - if ((ret = av_get_packet(pb, pkt, image->size)) < 0) - return ret; - } else { - uint8_t *buf; - if ((ret = av_new_packet(pkt, 14 + image->size)) < 0) - return ret; - buf = pkt->data; - - /* add BMP header */ - bytestream_put_byte(&buf, 'B'); - bytestream_put_byte(&buf, 'M'); - bytestream_put_le32(&buf, pkt->size); - bytestream_put_le16(&buf, 0); - bytestream_put_le16(&buf, 0); - bytestream_put_le32(&buf, 0); - - if ((ret = avio_read(pb, buf, image->size)) < 0) - return ret; - - st->codec->bits_per_coded_sample = AV_RL16(buf + 14); - - if (AV_RL32(buf + 32)) - image->nb_pal = AV_RL32(buf + 32); - - if (st->codec->bits_per_coded_sample <= 8 && !image->nb_pal) { - image->nb_pal = 1 << st->codec->bits_per_coded_sample; - AV_WL32(buf + 32, image->nb_pal); - } - - AV_WL32(buf - 4, 14 + 40 + image->nb_pal * 4); - AV_WL32(buf + 8, AV_RL32(buf + 8) / 2); - } - - pkt->stream_index = ico->current_image++; - pkt->flags |= AV_PKT_FLAG_KEY; - - return 0; -} - -AVInputFormat ff_ico_demuxer = { - .name = "ico", - .long_name = NULL_IF_CONFIG_SMALL("Microsoft Windows ICO"), - .priv_data_size = sizeof(IcoDemuxContext), - .read_probe = probe, - .read_header = read_header, - .read_packet = read_packet, - .flags = AVFMT_NOTIMESTAMPS, -}; diff --git a/ffmpeg1/libavformat/icoenc.c b/ffmpeg1/libavformat/icoenc.c deleted file mode 100644 index 3e6a1ea..0000000 --- a/ffmpeg1/libavformat/icoenc.c +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Microsoft Windows ICO muxer - * Copyright (c) 2012 Michael Bradshaw - * - * 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 - */ - -/** - * @file - * Microsoft Windows ICO muxer - */ - -#include "libavutil/intreadwrite.h" -#include "libavutil/pixdesc.h" -#include "avformat.h" - -typedef struct { - int offset; - int size; - unsigned char width; - unsigned char height; - short bits; -} IcoImage; - -typedef struct { - int current_image; - int nb_images; - IcoImage *images; -} IcoMuxContext; - -static int ico_check_attributes(AVFormatContext *s, const AVCodecContext *c) -{ - if (c->codec_id == AV_CODEC_ID_BMP) { - if (c->pix_fmt == AV_PIX_FMT_PAL8 && AV_PIX_FMT_RGB32 != AV_PIX_FMT_BGRA) { - av_log(s, AV_LOG_ERROR, "Wrong endianness for bmp pixel format\n"); - return AVERROR(EINVAL); - } else if (c->pix_fmt != AV_PIX_FMT_PAL8 && - c->pix_fmt != AV_PIX_FMT_RGB555LE && - c->pix_fmt != AV_PIX_FMT_BGR24 && - c->pix_fmt != AV_PIX_FMT_BGRA) { - av_log(s, AV_LOG_ERROR, "BMP must be 1bit, 4bit, 8bit, 16bit, 24bit, or 32bit\n"); - return AVERROR(EINVAL); - } - } else if (c->codec_id == AV_CODEC_ID_PNG) { - if (c->pix_fmt != AV_PIX_FMT_RGBA) { - av_log(s, AV_LOG_ERROR, "PNG in ico requires pixel format to be rgba\n"); - return AVERROR(EINVAL); - } - } else { - av_log(s, AV_LOG_ERROR, "Unsupported codec %s\n", c->codec_name); - return AVERROR(EINVAL); - } - - if (c->width > 256 || - c->height > 256) { - av_log(s, AV_LOG_ERROR, "Unsupported dimensions %dx%d (dimensions cannot exceed 256x256)\n", c->width, c->height); - return AVERROR(EINVAL); - } - - return 0; -} - -static int ico_write_header(AVFormatContext *s) -{ - IcoMuxContext *ico = s->priv_data; - AVIOContext *pb = s->pb; - int ret; - int i; - - if (!pb->seekable) { - av_log(s, AV_LOG_ERROR, "Output is not seekable\n"); - return AVERROR(EINVAL); - } - - ico->current_image = 0; - ico->nb_images = s->nb_streams; - - avio_wl16(pb, 0); // reserved - avio_wl16(pb, 1); // 1 == icon - avio_skip(pb, 2); // skip the number of images - - for (i = 0; i < s->nb_streams; i++) { - if (ret = ico_check_attributes(s, s->streams[i]->codec)) - return ret; - - // Fill in later when writing trailer... - avio_skip(pb, 16); - } - - ico->images = av_mallocz(ico->nb_images * sizeof(IcoMuxContext)); - if (!ico->images) - return AVERROR(ENOMEM); - - avio_flush(pb); - - return 0; -} - -static int ico_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - IcoMuxContext *ico = s->priv_data; - IcoImage *image; - AVIOContext *pb = s->pb; - AVCodecContext *c = s->streams[pkt->stream_index]->codec; - int i; - - if (ico->current_image >= ico->nb_images) { - av_log(s, AV_LOG_ERROR, "ICO already contains %d images\n", ico->current_image); - return AVERROR(EIO); - } - - image = &ico->images[ico->current_image++]; - - image->offset = avio_tell(pb); - image->width = (c->width == 256) ? 0 : c->width; - image->height = (c->height == 256) ? 0 : c->height; - - if (c->codec_id == AV_CODEC_ID_PNG) { - image->bits = c->bits_per_coded_sample; - image->size = pkt->size; - - avio_write(pb, pkt->data, pkt->size); - } else { // BMP - if (AV_RL32(pkt->data + 14) != 40) { // must be BITMAPINFOHEADER - av_log(s, AV_LOG_ERROR, "Invalid BMP\n"); - return AVERROR(EINVAL); - } - - image->bits = AV_RL16(pkt->data + 28); // allows things like 1bit and 4bit images to be preserved - image->size = pkt->size - 14 + c->height * (c->width + 7) / 8; - - avio_write(pb, pkt->data + 14, 8); // Skip the BITMAPFILEHEADER header - avio_wl32(pb, AV_RL32(pkt->data + 22) * 2); // rewrite height as 2 * height - avio_write(pb, pkt->data + 26, pkt->size - 26); - - for (i = 0; i < c->height * (c->width + 7) / 8; ++i) - avio_w8(pb, 0x00); // Write bitmask (opaque) - } - - avio_flush(pb); - - return 0; -} - -static int ico_write_trailer(AVFormatContext *s) -{ - IcoMuxContext *ico = s->priv_data; - AVIOContext *pb = s->pb; - int i; - - avio_seek(pb, 4, SEEK_SET); - - avio_wl16(pb, ico->current_image); - - for (i = 0; i < ico->nb_images; i++) { - avio_w8(pb, ico->images[i].width); - avio_w8(pb, ico->images[i].height); - - if (s->streams[i]->codec->codec_id == AV_CODEC_ID_BMP && - s->streams[i]->codec->pix_fmt == AV_PIX_FMT_PAL8) { - avio_w8(pb, (ico->images[i].bits >= 8) ? 0 : 1 << ico->images[i].bits); - } else { - avio_w8(pb, 0); - } - - avio_w8(pb, 0); // reserved - avio_wl16(pb, 1); // color planes - avio_wl16(pb, ico->images[i].bits); - avio_wl32(pb, ico->images[i].size); - avio_wl32(pb, ico->images[i].offset); - } - - av_freep(&ico->images); - - return 0; -} - -AVOutputFormat ff_ico_muxer = { - .name = "ico", - .long_name = NULL_IF_CONFIG_SMALL("Microsoft Windows ICO"), - .priv_data_size = sizeof(IcoMuxContext), - .mime_type = "image/vnd.microsoft.icon", - .extensions = "ico", - .audio_codec = AV_CODEC_ID_NONE, - .video_codec = AV_CODEC_ID_BMP, - .write_header = ico_write_header, - .write_packet = ico_write_packet, - .write_trailer = ico_write_trailer, - .flags = AVFMT_NOTIMESTAMPS, -}; diff --git a/ffmpeg1/libavformat/id3v1.c b/ffmpeg1/libavformat/id3v1.c deleted file mode 100644 index d73adc7..0000000 --- a/ffmpeg1/libavformat/id3v1.c +++ /dev/null @@ -1,246 +0,0 @@ -/* - * ID3v1 header parser - * Copyright (c) 2003 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 "id3v1.h" -#include "libavcodec/avcodec.h" -#include "libavutil/dict.h" - -/* See Genre List at http://id3.org/id3v2.3.0 */ -const char * const ff_id3v1_genre_str[ID3v1_GENRE_MAX + 1] = { - [0] = "Blues", - [1] = "Classic Rock", - [2] = "Country", - [3] = "Dance", - [4] = "Disco", - [5] = "Funk", - [6] = "Grunge", - [7] = "Hip-Hop", - [8] = "Jazz", - [9] = "Metal", - [10] = "New Age", - [11] = "Oldies", - [12] = "Other", - [13] = "Pop", - [14] = "R&B", - [15] = "Rap", - [16] = "Reggae", - [17] = "Rock", - [18] = "Techno", - [19] = "Industrial", - [20] = "Alternative", - [21] = "Ska", - [22] = "Death Metal", - [23] = "Pranks", - [24] = "Soundtrack", - [25] = "Euro-Techno", - [26] = "Ambient", - [27] = "Trip-Hop", - [28] = "Vocal", - [29] = "Jazz+Funk", - [30] = "Fusion", - [31] = "Trance", - [32] = "Classical", - [33] = "Instrumental", - [34] = "Acid", - [35] = "House", - [36] = "Game", - [37] = "Sound Clip", - [38] = "Gospel", - [39] = "Noise", - [40] = "AlternRock", - [41] = "Bass", - [42] = "Soul", - [43] = "Punk", - [44] = "Space", - [45] = "Meditative", - [46] = "Instrumental Pop", - [47] = "Instrumental Rock", - [48] = "Ethnic", - [49] = "Gothic", - [50] = "Darkwave", - [51] = "Techno-Industrial", - [52] = "Electronic", - [53] = "Pop-Folk", - [54] = "Eurodance", - [55] = "Dream", - [56] = "Southern Rock", - [57] = "Comedy", - [58] = "Cult", - [59] = "Gangsta", - [60] = "Top 40", - [61] = "Christian Rap", - [62] = "Pop/Funk", - [63] = "Jungle", - [64] = "Native American", - [65] = "Cabaret", - [66] = "New Wave", - [67] = "Psychadelic", /* sic, the misspelling is used in the specification */ - [68] = "Rave", - [69] = "Showtunes", - [70] = "Trailer", - [71] = "Lo-Fi", - [72] = "Tribal", - [73] = "Acid Punk", - [74] = "Acid Jazz", - [75] = "Polka", - [76] = "Retro", - [77] = "Musical", - [78] = "Rock & Roll", - [79] = "Hard Rock", - [80] = "Folk", - [81] = "Folk-Rock", - [82] = "National Folk", - [83] = "Swing", - [84] = "Fast Fusion", - [85] = "Bebob", - [86] = "Latin", - [87] = "Revival", - [88] = "Celtic", - [89] = "Bluegrass", - [90] = "Avantgarde", - [91] = "Gothic Rock", - [92] = "Progressive Rock", - [93] = "Psychedelic Rock", - [94] = "Symphonic Rock", - [95] = "Slow Rock", - [96] = "Big Band", - [97] = "Chorus", - [98] = "Easy Listening", - [99] = "Acoustic", - [100] = "Humour", - [101] = "Speech", - [102] = "Chanson", - [103] = "Opera", - [104] = "Chamber Music", - [105] = "Sonata", - [106] = "Symphony", - [107] = "Booty Bass", - [108] = "Primus", - [109] = "Porn Groove", - [110] = "Satire", - [111] = "Slow Jam", - [112] = "Club", - [113] = "Tango", - [114] = "Samba", - [115] = "Folklore", - [116] = "Ballad", - [117] = "Power Ballad", - [118] = "Rhythmic Soul", - [119] = "Freestyle", - [120] = "Duet", - [121] = "Punk Rock", - [122] = "Drum Solo", - [123] = "A capella", - [124] = "Euro-House", - [125] = "Dance Hall", - [126] = "Goa", - [127] = "Drum & Bass", - [128] = "Club-House", - [129] = "Hardcore", - [130] = "Terror", - [131] = "Indie", - [132] = "BritPop", - [133] = "Negerpunk", - [134] = "Polsk Punk", - [135] = "Beat", - [136] = "Christian Gangsta", - [137] = "Heavy Metal", - [138] = "Black Metal", - [139] = "Crossover", - [140] = "Contemporary Christian", - [141] = "Christian Rock", - [142] = "Merengue", - [143] = "Salsa", - [144] = "Thrash Metal", - [145] = "Anime", - [146] = "JPop", - [147] = "SynthPop", -}; - -static void get_string(AVFormatContext *s, const char *key, - const uint8_t *buf, int buf_size) -{ - int i, c; - char *q, str[512]; - - q = str; - for(i = 0; i < buf_size; i++) { - c = buf[i]; - if (c == '\0') - break; - if ((q - str) >= sizeof(str) - 1) - break; - *q++ = c; - } - *q = '\0'; - - if (*str) - av_dict_set(&s->metadata, key, str, 0); -} - -/** - * Parse an ID3v1 tag - * - * @param buf ID3v1_TAG_SIZE long buffer containing the tag - */ -static int parse_tag(AVFormatContext *s, const uint8_t *buf) -{ - char str[5]; - int genre; - - if (!(buf[0] == 'T' && - buf[1] == 'A' && - buf[2] == 'G')) - return -1; - get_string(s, "title", buf + 3, 30); - get_string(s, "artist", buf + 33, 30); - get_string(s, "album", buf + 63, 30); - get_string(s, "date", buf + 93, 4); - get_string(s, "comment", buf + 97, 30); - if (buf[125] == 0 && buf[126] != 0) { - snprintf(str, sizeof(str), "%d", buf[126]); - av_dict_set(&s->metadata, "track", str, 0); - } - genre = buf[127]; - if (genre <= ID3v1_GENRE_MAX) - av_dict_set(&s->metadata, "genre", ff_id3v1_genre_str[genre], 0); - return 0; -} - -void ff_id3v1_read(AVFormatContext *s) -{ - int ret; - uint8_t buf[ID3v1_TAG_SIZE]; - int64_t filesize, position = avio_tell(s->pb); - - if (s->pb->seekable) { - /* XXX: change that */ - filesize = avio_size(s->pb); - if (filesize > 128) { - avio_seek(s->pb, filesize - 128, SEEK_SET); - ret = avio_read(s->pb, buf, ID3v1_TAG_SIZE); - if (ret == ID3v1_TAG_SIZE) { - parse_tag(s, buf); - } - avio_seek(s->pb, position, SEEK_SET); - } - } -} diff --git a/ffmpeg1/libavformat/id3v1.h b/ffmpeg1/libavformat/id3v1.h deleted file mode 100644 index d5dca35..0000000 --- a/ffmpeg1/libavformat/id3v1.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * ID3v1 header parser - * Copyright (c) 2003 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 AVFORMAT_ID3V1_H -#define AVFORMAT_ID3V1_H - -#include "avformat.h" - -#define ID3v1_TAG_SIZE 128 - -#define ID3v1_GENRE_MAX 147 - -/** - * ID3v1 genres - */ -extern const char * const ff_id3v1_genre_str[ID3v1_GENRE_MAX + 1]; - -/** - * Read an ID3v1 tag - */ -void ff_id3v1_read(AVFormatContext *s); - -#endif /* AVFORMAT_ID3V1_H */ diff --git a/ffmpeg1/libavformat/id3v2.c b/ffmpeg1/libavformat/id3v2.c deleted file mode 100644 index 3e347d1..0000000 --- a/ffmpeg1/libavformat/id3v2.c +++ /dev/null @@ -1,858 +0,0 @@ -/* - * Copyright (c) 2003 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 - */ - -/** - * @file - * ID3v2 header parser - * - * Specifications available at: - * http://id3.org/Developer_Information - */ - -#include "config.h" - -#if CONFIG_ZLIB -#include -#endif - -#include "id3v2.h" -#include "id3v1.h" -#include "libavutil/avstring.h" -#include "libavutil/intreadwrite.h" -#include "libavutil/dict.h" -#include "avio_internal.h" -#include "internal.h" - -const AVMetadataConv ff_id3v2_34_metadata_conv[] = { - { "TALB", "album"}, - { "TCOM", "composer"}, - { "TCON", "genre"}, - { "TCOP", "copyright"}, - { "TENC", "encoded_by"}, - { "TIT2", "title"}, - { "TLAN", "language"}, - { "TPE1", "artist"}, - { "TPE2", "album_artist"}, - { "TPE3", "performer"}, - { "TPOS", "disc"}, - { "TPUB", "publisher"}, - { "TRCK", "track"}, - { "TSSE", "encoder"}, - { 0 } -}; - -const AVMetadataConv ff_id3v2_4_metadata_conv[] = { - { "TDRL", "date"}, - { "TDRC", "date"}, - { "TDEN", "creation_time"}, - { "TSOA", "album-sort"}, - { "TSOP", "artist-sort"}, - { "TSOT", "title-sort"}, - { 0 } -}; - -static const AVMetadataConv id3v2_2_metadata_conv[] = { - { "TAL", "album"}, - { "TCO", "genre"}, - { "TT2", "title"}, - { "TEN", "encoded_by"}, - { "TP1", "artist"}, - { "TP2", "album_artist"}, - { "TP3", "performer"}, - { "TRK", "track"}, - { 0 } -}; - - -const char ff_id3v2_tags[][4] = { - "TALB", "TBPM", "TCOM", "TCON", "TCOP", "TDLY", "TENC", "TEXT", - "TFLT", "TIT1", "TIT2", "TIT3", "TKEY", "TLAN", "TLEN", "TMED", - "TOAL", "TOFN", "TOLY", "TOPE", "TOWN", "TPE1", "TPE2", "TPE3", - "TPE4", "TPOS", "TPUB", "TRCK", "TRSN", "TRSO", "TSRC", "TSSE", - { 0 }, -}; - -const char ff_id3v2_4_tags[][4] = { - "TDEN", "TDOR", "TDRC", "TDRL", "TDTG", "TIPL", "TMCL", "TMOO", - "TPRO", "TSOA", "TSOP", "TSOT", "TSST", - { 0 }, -}; - -const char ff_id3v2_3_tags[][4] = { - "TDAT", "TIME", "TORY", "TRDA", "TSIZ", "TYER", - { 0 }, -}; - -const char *ff_id3v2_picture_types[21] = { - "Other", - "32x32 pixels 'file icon'", - "Other file icon", - "Cover (front)", - "Cover (back)", - "Leaflet page", - "Media (e.g. label side of CD)", - "Lead artist/lead performer/soloist", - "Artist/performer", - "Conductor", - "Band/Orchestra", - "Composer", - "Lyricist/text writer", - "Recording Location", - "During recording", - "During performance", - "Movie/video screen capture", - "A bright coloured fish", - "Illustration", - "Band/artist logotype", - "Publisher/Studio logotype", -}; - -const CodecMime ff_id3v2_mime_tags[] = { - {"image/gif" , AV_CODEC_ID_GIF}, - {"image/jpeg", AV_CODEC_ID_MJPEG}, - {"image/jpg", AV_CODEC_ID_MJPEG}, - {"image/png" , AV_CODEC_ID_PNG}, - {"image/tiff", AV_CODEC_ID_TIFF}, - {"image/bmp", AV_CODEC_ID_BMP}, - {"JPG", AV_CODEC_ID_MJPEG}, /* ID3v2.2 */ - {"PNG" , AV_CODEC_ID_PNG}, /* ID3v2.2 */ - {"", AV_CODEC_ID_NONE}, -}; - -int ff_id3v2_match(const uint8_t *buf, const char * magic) -{ - return buf[0] == magic[0] && - buf[1] == magic[1] && - buf[2] == magic[2] && - buf[3] != 0xff && - buf[4] != 0xff && - (buf[6] & 0x80) == 0 && - (buf[7] & 0x80) == 0 && - (buf[8] & 0x80) == 0 && - (buf[9] & 0x80) == 0; -} - -int ff_id3v2_tag_len(const uint8_t * buf) -{ - int len = ((buf[6] & 0x7f) << 21) + - ((buf[7] & 0x7f) << 14) + - ((buf[8] & 0x7f) << 7) + - (buf[9] & 0x7f) + - ID3v2_HEADER_SIZE; - if (buf[5] & 0x10) - len += ID3v2_HEADER_SIZE; - return len; -} - -static unsigned int get_size(AVIOContext *s, int len) -{ - int v = 0; - while (len--) - v = (v << 7) + (avio_r8(s) & 0x7F); - return v; -} - -/** - * Free GEOB type extra metadata. - */ -static void free_geobtag(void *obj) -{ - ID3v2ExtraMetaGEOB *geob = obj; - av_free(geob->mime_type); - av_free(geob->file_name); - av_free(geob->description); - av_free(geob->data); - av_free(geob); -} - -/** - * Decode characters to UTF-8 according to encoding type. The decoded buffer is - * always null terminated. Stop reading when either *maxread bytes are read from - * pb or U+0000 character is found. - * - * @param dst Pointer where the address of the buffer with the decoded bytes is - * stored. Buffer must be freed by caller. - * @param maxread Pointer to maximum number of characters to read from the - * AVIOContext. After execution the value is decremented by the number of bytes - * actually read. - * @returns 0 if no error occurred, dst is uninitialized on error - */ -static int decode_str(AVFormatContext *s, AVIOContext *pb, int encoding, - uint8_t **dst, int *maxread) -{ - int ret; - uint8_t tmp; - uint32_t ch = 1; - int left = *maxread; - unsigned int (*get)(AVIOContext*) = avio_rb16; - AVIOContext *dynbuf; - - if ((ret = avio_open_dyn_buf(&dynbuf)) < 0) { - av_log(s, AV_LOG_ERROR, "Error opening memory stream\n"); - return ret; - } - - switch (encoding) { - - case ID3v2_ENCODING_ISO8859: - while (left && ch) { - ch = avio_r8(pb); - PUT_UTF8(ch, tmp, avio_w8(dynbuf, tmp);) - left--; - } - break; - - case ID3v2_ENCODING_UTF16BOM: - if ((left -= 2) < 0) { - av_log(s, AV_LOG_ERROR, "Cannot read BOM value, input too short\n"); - avio_close_dyn_buf(dynbuf, dst); - av_freep(dst); - return AVERROR_INVALIDDATA; - } - switch (avio_rb16(pb)) { - case 0xfffe: - get = avio_rl16; - case 0xfeff: - break; - default: - av_log(s, AV_LOG_ERROR, "Incorrect BOM value\n"); - avio_close_dyn_buf(dynbuf, dst); - av_freep(dst); - *maxread = left; - return AVERROR_INVALIDDATA; - } - // fall-through - - case ID3v2_ENCODING_UTF16BE: - while ((left > 1) && ch) { - GET_UTF16(ch, ((left -= 2) >= 0 ? get(pb) : 0), break;) - PUT_UTF8(ch, tmp, avio_w8(dynbuf, tmp);) - } - if (left < 0) - left += 2; /* did not read last char from pb */ - break; - - case ID3v2_ENCODING_UTF8: - while (left && ch) { - ch = avio_r8(pb); - avio_w8(dynbuf, ch); - left--; - } - break; - default: - av_log(s, AV_LOG_WARNING, "Unknown encoding\n"); - } - - if (ch) - avio_w8(dynbuf, 0); - - avio_close_dyn_buf(dynbuf, dst); - *maxread = left; - - return 0; -} - -/** - * Parse a text tag. - */ -static void read_ttag(AVFormatContext *s, AVIOContext *pb, int taglen, const char *key) -{ - uint8_t *dst; - int encoding, dict_flags = AV_DICT_DONT_OVERWRITE | AV_DICT_DONT_STRDUP_VAL; - unsigned genre; - - if (taglen < 1) - return; - - encoding = avio_r8(pb); - taglen--; /* account for encoding type byte */ - - if (decode_str(s, pb, encoding, &dst, &taglen) < 0) { - av_log(s, AV_LOG_ERROR, "Error reading frame %s, skipped\n", key); - return; - } - - if (!(strcmp(key, "TCON") && strcmp(key, "TCO")) - && (sscanf(dst, "(%d)", &genre) == 1 || sscanf(dst, "%d", &genre) == 1) - && genre <= ID3v1_GENRE_MAX) { - av_freep(&dst); - dst = av_strdup(ff_id3v1_genre_str[genre]); - } else if (!(strcmp(key, "TXXX") && strcmp(key, "TXX"))) { - /* dst now contains the key, need to get value */ - key = dst; - if (decode_str(s, pb, encoding, &dst, &taglen) < 0) { - av_log(s, AV_LOG_ERROR, "Error reading frame %s, skipped\n", key); - av_freep(&key); - return; - } - dict_flags |= AV_DICT_DONT_STRDUP_KEY; - } else if (!*dst) - av_freep(&dst); - - if (dst) - av_dict_set(&s->metadata, key, dst, dict_flags); -} - -/** - * Parse GEOB tag into a ID3v2ExtraMetaGEOB struct. - */ -static void read_geobtag(AVFormatContext *s, AVIOContext *pb, int taglen, char *tag, ID3v2ExtraMeta **extra_meta) -{ - ID3v2ExtraMetaGEOB *geob_data = NULL; - ID3v2ExtraMeta *new_extra = NULL; - char encoding; - unsigned int len; - - if (taglen < 1) - return; - - geob_data = av_mallocz(sizeof(ID3v2ExtraMetaGEOB)); - if (!geob_data) { - av_log(s, AV_LOG_ERROR, "Failed to alloc %zu bytes\n", sizeof(ID3v2ExtraMetaGEOB)); - return; - } - - new_extra = av_mallocz(sizeof(ID3v2ExtraMeta)); - if (!new_extra) { - av_log(s, AV_LOG_ERROR, "Failed to alloc %zu bytes\n", sizeof(ID3v2ExtraMeta)); - goto fail; - } - - /* read encoding type byte */ - encoding = avio_r8(pb); - taglen--; - - /* read MIME type (always ISO-8859) */ - if (decode_str(s, pb, ID3v2_ENCODING_ISO8859, &geob_data->mime_type, &taglen) < 0 - || taglen <= 0) - goto fail; - - /* read file name */ - if (decode_str(s, pb, encoding, &geob_data->file_name, &taglen) < 0 - || taglen <= 0) - goto fail; - - /* read content description */ - if (decode_str(s, pb, encoding, &geob_data->description, &taglen) < 0 - || taglen < 0) - goto fail; - - if (taglen) { - /* save encapsulated binary data */ - geob_data->data = av_malloc(taglen); - if (!geob_data->data) { - av_log(s, AV_LOG_ERROR, "Failed to alloc %d bytes\n", taglen); - goto fail; - } - if ((len = avio_read(pb, geob_data->data, taglen)) < taglen) - av_log(s, AV_LOG_WARNING, "Error reading GEOB frame, data truncated.\n"); - geob_data->datasize = len; - } else { - geob_data->data = NULL; - geob_data->datasize = 0; - } - - /* add data to the list */ - new_extra->tag = "GEOB"; - new_extra->data = geob_data; - new_extra->next = *extra_meta; - *extra_meta = new_extra; - - return; - -fail: - av_log(s, AV_LOG_ERROR, "Error reading frame %s, skipped\n", tag); - free_geobtag(geob_data); - av_free(new_extra); - return; -} - -static int is_number(const char *str) -{ - while (*str >= '0' && *str <= '9') str++; - return !*str; -} - -static AVDictionaryEntry* get_date_tag(AVDictionary *m, const char *tag) -{ - AVDictionaryEntry *t; - if ((t = av_dict_get(m, tag, NULL, AV_DICT_MATCH_CASE)) && - strlen(t->value) == 4 && is_number(t->value)) - return t; - return NULL; -} - -static void merge_date(AVDictionary **m) -{ - AVDictionaryEntry *t; - char date[17] = {0}; // YYYY-MM-DD hh:mm - - if (!(t = get_date_tag(*m, "TYER")) && - !(t = get_date_tag(*m, "TYE"))) - return; - av_strlcpy(date, t->value, 5); - av_dict_set(m, "TYER", NULL, 0); - av_dict_set(m, "TYE", NULL, 0); - - if (!(t = get_date_tag(*m, "TDAT")) && - !(t = get_date_tag(*m, "TDA"))) - goto finish; - snprintf(date + 4, sizeof(date) - 4, "-%.2s-%.2s", t->value + 2, t->value); - av_dict_set(m, "TDAT", NULL, 0); - av_dict_set(m, "TDA", NULL, 0); - - if (!(t = get_date_tag(*m, "TIME")) && - !(t = get_date_tag(*m, "TIM"))) - goto finish; - snprintf(date + 10, sizeof(date) - 10, " %.2s:%.2s", t->value, t->value + 2); - av_dict_set(m, "TIME", NULL, 0); - av_dict_set(m, "TIM", NULL, 0); - -finish: - if (date[0]) - av_dict_set(m, "date", date, 0); -} - -static void free_apic(void *obj) -{ - ID3v2ExtraMetaAPIC *apic = obj; - av_buffer_unref(&apic->buf); - av_freep(&apic->description); - av_freep(&apic); -} - -static void read_apic(AVFormatContext *s, AVIOContext *pb, int taglen, char *tag, ID3v2ExtraMeta **extra_meta) -{ - int enc, pic_type; - char mimetype[64]; - const CodecMime *mime = ff_id3v2_mime_tags; - enum AVCodecID id = AV_CODEC_ID_NONE; - ID3v2ExtraMetaAPIC *apic = NULL; - ID3v2ExtraMeta *new_extra = NULL; - int64_t end = avio_tell(pb) + taglen; - - if (taglen <= 4) - goto fail; - - new_extra = av_mallocz(sizeof(*new_extra)); - apic = av_mallocz(sizeof(*apic)); - if (!new_extra || !apic) - goto fail; - - enc = avio_r8(pb); - taglen--; - - /* mimetype */ - taglen -= avio_get_str(pb, taglen, mimetype, sizeof(mimetype)); - while (mime->id != AV_CODEC_ID_NONE) { - if (!av_strncasecmp(mime->str, mimetype, sizeof(mimetype))) { - id = mime->id; - break; - } - mime++; - } - if (id == AV_CODEC_ID_NONE) { - av_log(s, AV_LOG_WARNING, "Unknown attached picture mimetype: %s, skipping.\n", mimetype); - goto fail; - } - apic->id = id; - - /* picture type */ - pic_type = avio_r8(pb); - taglen--; - if (pic_type < 0 || pic_type >= FF_ARRAY_ELEMS(ff_id3v2_picture_types)) { - av_log(s, AV_LOG_WARNING, "Unknown attached picture type %d.\n", pic_type); - pic_type = 0; - } - apic->type = ff_id3v2_picture_types[pic_type]; - - /* description and picture data */ - if (decode_str(s, pb, enc, &apic->description, &taglen) < 0) { - av_log(s, AV_LOG_ERROR, "Error decoding attached picture description.\n"); - goto fail; - } - - apic->buf = av_buffer_alloc(taglen); - if (!apic->buf || !taglen || avio_read(pb, apic->buf->data, taglen) != taglen) - goto fail; - - new_extra->tag = "APIC"; - new_extra->data = apic; - new_extra->next = *extra_meta; - *extra_meta = new_extra; - - return; - -fail: - if (apic) - free_apic(apic); - av_freep(&new_extra); - avio_seek(pb, end, SEEK_SET); -} - -static void read_chapter(AVFormatContext *s, AVIOContext *pb, int taglen, char *tag, ID3v2ExtraMeta **extra_meta) -{ - AVRational time_base = {1, 1000}; - char title[1024]; - uint32_t start, end; - - taglen -= avio_get_str(pb, taglen, title, sizeof(title)); - if (taglen < 16) - return; - - start = avio_rb32(pb); - end = avio_rb32(pb); - taglen -= 27; - if (taglen > 0) { - char tag[4]; - - avio_skip(pb, 8); - avio_read(pb, tag, 4); - if (!memcmp(tag, "TIT2", 4)) { - taglen = FFMIN(taglen, avio_rb32(pb)); - if (taglen < 0) - return; - avio_skip(pb, 3); - avio_get_str(pb, taglen, title, sizeof(title)); - } - } - - avpriv_new_chapter(s, s->nb_chapters + 1, time_base, start, end, title); -} - -typedef struct ID3v2EMFunc { - const char *tag3; - const char *tag4; - void (*read)(AVFormatContext*, AVIOContext*, int, char*, ID3v2ExtraMeta **); - void (*free)(void *obj); -} ID3v2EMFunc; - -static const ID3v2EMFunc id3v2_extra_meta_funcs[] = { - { "GEO", "GEOB", read_geobtag, free_geobtag }, - { "PIC", "APIC", read_apic, free_apic }, - { "CHAP","CHAP", read_chapter, NULL }, - { NULL } -}; - -/** - * Get the corresponding ID3v2EMFunc struct for a tag. - * @param isv34 Determines if v2.2 or v2.3/4 strings are used - * @return A pointer to the ID3v2EMFunc struct if found, NULL otherwise. - */ -static const ID3v2EMFunc *get_extra_meta_func(const char *tag, int isv34) -{ - int i = 0; - while (id3v2_extra_meta_funcs[i].tag3) { - if (tag && !memcmp(tag, - (isv34 ? id3v2_extra_meta_funcs[i].tag4 : - id3v2_extra_meta_funcs[i].tag3), - (isv34 ? 4 : 3))) - return &id3v2_extra_meta_funcs[i]; - i++; - } - return NULL; -} - -static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t flags, ID3v2ExtraMeta **extra_meta) -{ - int isv34, unsync; - unsigned tlen; - char tag[5]; - int64_t next, end = avio_tell(s->pb) + len; - int taghdrlen; - const char *reason = NULL; - AVIOContext pb; - AVIOContext *pbx; - unsigned char *buffer = NULL; - int buffer_size = 0; - const ID3v2EMFunc *extra_func = NULL; - unsigned char *uncompressed_buffer = NULL; - int uncompressed_buffer_size = 0; - - av_log(s, AV_LOG_DEBUG, "id3v2 ver:%d flags:%02X len:%d\n", version, flags, len); - - switch (version) { - case 2: - if (flags & 0x40) { - reason = "compression"; - goto error; - } - isv34 = 0; - taghdrlen = 6; - break; - - case 3: - case 4: - isv34 = 1; - taghdrlen = 10; - break; - - default: - reason = "version"; - goto error; - } - - unsync = flags & 0x80; - - if (isv34 && flags & 0x40) { /* Extended header present, just skip over it */ - int extlen = get_size(s->pb, 4); - if (version == 4) - extlen -= 4; // in v2.4 the length includes the length field we just read - - if (extlen < 0) { - reason = "invalid extended header length"; - goto error; - } - avio_skip(s->pb, extlen); - len -= extlen + 4; - if (len < 0) { - reason = "extended header too long."; - goto error; - } - } - - while (len >= taghdrlen) { - unsigned int tflags = 0; - int tunsync = 0; - int tcomp = 0; - int tencr = 0; - unsigned long dlen; - - if (isv34) { - avio_read(s->pb, tag, 4); - tag[4] = 0; - if(version==3){ - tlen = avio_rb32(s->pb); - }else - tlen = get_size(s->pb, 4); - tflags = avio_rb16(s->pb); - tunsync = tflags & ID3v2_FLAG_UNSYNCH; - } else { - avio_read(s->pb, tag, 3); - tag[3] = 0; - tlen = avio_rb24(s->pb); - } - if (tlen > (1<<28)) - break; - len -= taghdrlen + tlen; - - if (len < 0) - break; - - next = avio_tell(s->pb) + tlen; - - if (!tlen) { - if (tag[0]) - av_log(s, AV_LOG_DEBUG, "Invalid empty frame %s, skipping.\n", tag); - continue; - } - - if (tflags & ID3v2_FLAG_DATALEN) { - if (tlen < 4) - break; - dlen = avio_rb32(s->pb); - tlen -= 4; - } else - dlen = tlen; - - tcomp = tflags & ID3v2_FLAG_COMPRESSION; - tencr = tflags & ID3v2_FLAG_ENCRYPTION; - - /* skip encrypted tags and, if no zlib, compressed tags */ - if (tencr || (!CONFIG_ZLIB && tcomp)) { - const char *type; - if (!tcomp) - type = "encrypted"; - else if (!tencr) - type = "compressed"; - else - type = "encrypted and compressed"; - - av_log(s, AV_LOG_WARNING, "Skipping %s ID3v2 frame %s.\n", type, tag); - avio_skip(s->pb, tlen); - /* check for text tag or supported special meta tag */ - } else if (tag[0] == 'T' || (extra_meta && (extra_func = get_extra_meta_func(tag, isv34)))) { - pbx = s->pb; - - if (unsync || tunsync || tcomp) { - av_fast_malloc(&buffer, &buffer_size, tlen); - if (!buffer) { - av_log(s, AV_LOG_ERROR, "Failed to alloc %d bytes\n", tlen); - goto seek; - } - } - if (unsync || tunsync) { - int64_t end = avio_tell(s->pb) + tlen; - uint8_t *b; - - b = buffer; - while (avio_tell(s->pb) < end && b - buffer < tlen) { - *b++ = avio_r8(s->pb); - if (*(b - 1) == 0xff && avio_tell(s->pb) < end - 1 && b - buffer < tlen) { - uint8_t val = avio_r8(s->pb); - *b++ = val ? val : avio_r8(s->pb); - } - } - ffio_init_context(&pb, buffer, b - buffer, 0, NULL, NULL, NULL, NULL); - tlen = b - buffer; - pbx = &pb; // read from sync buffer - } - -#if CONFIG_ZLIB - if (tcomp) { - int err; - - av_log(s, AV_LOG_DEBUG, "Compresssed frame %s tlen=%d dlen=%ld\n", tag, tlen, dlen); - - av_fast_malloc(&uncompressed_buffer, &uncompressed_buffer_size, dlen); - if (!uncompressed_buffer) { - av_log(s, AV_LOG_ERROR, "Failed to alloc %ld bytes\n", dlen); - goto seek; - } - - if (!(unsync || tunsync)) { - err = avio_read(s->pb, buffer, tlen); - if (err < 0) { - av_log(s, AV_LOG_ERROR, "Failed to read compressed tag\n"); - goto seek; - } - tlen = err; - } - - err = uncompress(uncompressed_buffer, &dlen, buffer, tlen); - if (err != Z_OK) { - av_log(s, AV_LOG_ERROR, "Failed to uncompress tag: %d\n", err); - goto seek; - } - ffio_init_context(&pb, uncompressed_buffer, dlen, 0, NULL, NULL, NULL, NULL); - tlen = dlen; - pbx = &pb; // read from sync buffer - } -#endif - if (tag[0] == 'T') - /* parse text tag */ - read_ttag(s, pbx, tlen, tag); - else - /* parse special meta tag */ - extra_func->read(s, pbx, tlen, tag, extra_meta); - } - else if (!tag[0]) { - if (tag[1]) - av_log(s, AV_LOG_WARNING, "invalid frame id, assuming padding\n"); - avio_skip(s->pb, tlen); - break; - } - /* Skip to end of tag */ -seek: - avio_seek(s->pb, next, SEEK_SET); - } - - if (version == 4 && flags & 0x10) /* Footer preset, always 10 bytes, skip over it */ - end += 10; - - error: - if (reason) - av_log(s, AV_LOG_INFO, "ID3v2.%d tag skipped, cannot handle %s\n", version, reason); - avio_seek(s->pb, end, SEEK_SET); - av_free(buffer); - av_free(uncompressed_buffer); - return; -} - -void ff_id3v2_read(AVFormatContext *s, const char *magic, ID3v2ExtraMeta **extra_meta) -{ - int len, ret; - uint8_t buf[ID3v2_HEADER_SIZE]; - int found_header; - int64_t off; - - do { - /* save the current offset in case there's nothing to read/skip */ - off = avio_tell(s->pb); - ret = avio_read(s->pb, buf, ID3v2_HEADER_SIZE); - if (ret != ID3v2_HEADER_SIZE) { - avio_seek(s->pb, off, SEEK_SET); - break; - } - found_header = ff_id3v2_match(buf, magic); - if (found_header) { - /* parse ID3v2 header */ - len = ((buf[6] & 0x7f) << 21) | - ((buf[7] & 0x7f) << 14) | - ((buf[8] & 0x7f) << 7) | - (buf[9] & 0x7f); - ff_id3v2_parse(s, len, buf[3], buf[5], extra_meta); - } else { - avio_seek(s->pb, off, SEEK_SET); - } - } while (found_header); - ff_metadata_conv(&s->metadata, NULL, ff_id3v2_34_metadata_conv); - ff_metadata_conv(&s->metadata, NULL, id3v2_2_metadata_conv); - ff_metadata_conv(&s->metadata, NULL, ff_id3v2_4_metadata_conv); - merge_date(&s->metadata); -} - -void ff_id3v2_free_extra_meta(ID3v2ExtraMeta **extra_meta) -{ - ID3v2ExtraMeta *current = *extra_meta, *next; - const ID3v2EMFunc *extra_func; - - while (current) { - if ((extra_func = get_extra_meta_func(current->tag, 1))) - extra_func->free(current->data); - next = current->next; - av_freep(¤t); - current = next; - } -} - -int ff_id3v2_parse_apic(AVFormatContext *s, ID3v2ExtraMeta **extra_meta) -{ - ID3v2ExtraMeta *cur; - - for (cur = *extra_meta; cur; cur = cur->next) { - ID3v2ExtraMetaAPIC *apic; - AVStream *st; - - if (strcmp(cur->tag, "APIC")) - continue; - apic = cur->data; - - if (!(st = avformat_new_stream(s, NULL))) - return AVERROR(ENOMEM); - - st->disposition |= AV_DISPOSITION_ATTACHED_PIC; - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = apic->id; - av_dict_set(&st->metadata, "title", apic->description, 0); - av_dict_set(&st->metadata, "comment", apic->type, 0); - - av_init_packet(&st->attached_pic); - st->attached_pic.buf = apic->buf; - st->attached_pic.data = apic->buf->data; - st->attached_pic.size = apic->buf->size; - st->attached_pic.stream_index = st->index; - st->attached_pic.flags |= AV_PKT_FLAG_KEY; - - apic->buf = NULL; - } - - return 0; -} diff --git a/ffmpeg1/libavformat/id3v2.h b/ffmpeg1/libavformat/id3v2.h deleted file mode 100644 index e893922..0000000 --- a/ffmpeg1/libavformat/id3v2.h +++ /dev/null @@ -1,163 +0,0 @@ -/* - * ID3v2 header parser - * Copyright (c) 2003 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 AVFORMAT_ID3V2_H -#define AVFORMAT_ID3V2_H - -#include -#include "avformat.h" -#include "internal.h" -#include "metadata.h" - -#define ID3v2_HEADER_SIZE 10 - -/** - * Default magic bytes for ID3v2 header: "ID3" - */ -#define ID3v2_DEFAULT_MAGIC "ID3" - -#define ID3v2_FLAG_DATALEN 0x0001 -#define ID3v2_FLAG_UNSYNCH 0x0002 -#define ID3v2_FLAG_ENCRYPTION 0x0004 -#define ID3v2_FLAG_COMPRESSION 0x0008 - -enum ID3v2Encoding { - ID3v2_ENCODING_ISO8859 = 0, - ID3v2_ENCODING_UTF16BOM = 1, - ID3v2_ENCODING_UTF16BE = 2, - ID3v2_ENCODING_UTF8 = 3, -}; - -typedef struct ID3v2EncContext { - int version; ///< ID3v2 minor version, either 3 or 4 - int64_t size_pos; ///< offset of the tag total size - int len; ///< size of the tag written so far -} ID3v2EncContext; - -typedef struct ID3v2ExtraMeta { - const char *tag; - void *data; - struct ID3v2ExtraMeta *next; -} ID3v2ExtraMeta; - -typedef struct ID3v2ExtraMetaGEOB { - uint32_t datasize; - uint8_t *mime_type; - uint8_t *file_name; - uint8_t *description; - uint8_t *data; -} ID3v2ExtraMetaGEOB; - -typedef struct ID3v2ExtraMetaAPIC { - AVBufferRef *buf; - const char *type; - uint8_t *description; - enum AVCodecID id; -} ID3v2ExtraMetaAPIC; - -/** - * Detect ID3v2 Header. - * @param buf must be ID3v2_HEADER_SIZE byte long - * @param magic magic bytes to identify the header. - * If in doubt, use ID3v2_DEFAULT_MAGIC. - */ -int ff_id3v2_match(const uint8_t *buf, const char *magic); - -/** - * Get the length of an ID3v2 tag. - * @param buf must be ID3v2_HEADER_SIZE bytes long and point to the start of an - * already detected ID3v2 tag - */ -int ff_id3v2_tag_len(const uint8_t *buf); - -/** - * Read an ID3v2 tag, including supported extra metadata - * @param extra_meta If not NULL, extra metadata is parsed into a list of - * ID3v2ExtraMeta structs and *extra_meta points to the head of the list - */ -void ff_id3v2_read(AVFormatContext *s, const char *magic, ID3v2ExtraMeta **extra_meta); - -/** - * Initialize an ID3v2 tag. - */ -void ff_id3v2_start(ID3v2EncContext *id3, AVIOContext *pb, int id3v2_version, - const char *magic); - -/** - * Convert and write all global metadata from s into an ID3v2 tag. - */ -int ff_id3v2_write_metadata(AVFormatContext *s, ID3v2EncContext *id3); - -/** - * Write an attached picture from pkt into an ID3v2 tag. - */ -int ff_id3v2_write_apic(AVFormatContext *s, ID3v2EncContext *id3, AVPacket *pkt); - -/** - * Finalize an opened ID3v2 tag. - */ -void ff_id3v2_finish(ID3v2EncContext *id3, AVIOContext *pb); - -/** - * Write an ID3v2 tag containing all global metadata from s. - * @param id3v2_version Subversion of ID3v2; supported values are 3 and 4 - * @param magic magic bytes to identify the header - * If in doubt, use ID3v2_DEFAULT_MAGIC. - */ -int ff_id3v2_write_simple(struct AVFormatContext *s, int id3v2_version, const char *magic); - -/** - * Free memory allocated parsing special (non-text) metadata. - * @param extra_meta Pointer to a pointer to the head of a ID3v2ExtraMeta list, *extra_meta is set to NULL. - */ -void ff_id3v2_free_extra_meta(ID3v2ExtraMeta **extra_meta); - -/** - * Create a stream for each APIC (attached picture) extracted from the - * ID3v2 header. - */ -int ff_id3v2_parse_apic(AVFormatContext *s, ID3v2ExtraMeta **extra_meta); - -extern const AVMetadataConv ff_id3v2_34_metadata_conv[]; -extern const AVMetadataConv ff_id3v2_4_metadata_conv[]; - -/** - * A list of text information frames allowed in both ID3 v2.3 and v2.4 - * http://www.id3.org/id3v2.4.0-frames - * http://www.id3.org/id3v2.4.0-changes - */ -extern const char ff_id3v2_tags[][4]; - -/** - * ID3v2.4-only text information frames. - */ -extern const char ff_id3v2_4_tags[][4]; - -/** - * ID3v2.3-only text information frames. - */ -extern const char ff_id3v2_3_tags[][4]; - -extern const CodecMime ff_id3v2_mime_tags[]; - -extern const char *ff_id3v2_picture_types[21]; - -#endif /* AVFORMAT_ID3V2_H */ diff --git a/ffmpeg1/libavformat/id3v2enc.c b/ffmpeg1/libavformat/id3v2enc.c deleted file mode 100644 index a10d679..0000000 --- a/ffmpeg1/libavformat/id3v2enc.c +++ /dev/null @@ -1,284 +0,0 @@ -/* - * ID3v2 header writer - * - * 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 -#include - -#include "libavutil/avstring.h" -#include "libavutil/dict.h" -#include "libavutil/intreadwrite.h" -#include "avformat.h" -#include "avio.h" -#include "id3v2.h" - -static void id3v2_put_size(AVIOContext *pb, int size) -{ - avio_w8(pb, size >> 21 & 0x7f); - avio_w8(pb, size >> 14 & 0x7f); - avio_w8(pb, size >> 7 & 0x7f); - avio_w8(pb, size & 0x7f); -} - -static int string_is_ascii(const uint8_t *str) -{ - while (*str && *str < 128) str++; - return !*str; -} - -static void id3v2_encode_string(AVIOContext *pb, const uint8_t *str, - enum ID3v2Encoding enc) -{ - int (*put)(AVIOContext*, const char*); - - if (enc == ID3v2_ENCODING_UTF16BOM) { - avio_wl16(pb, 0xFEFF); /* BOM */ - put = avio_put_str16le; - } else - put = avio_put_str; - - put(pb, str); -} - -/** - * Write a text frame with one (normal frames) or two (TXXX frames) strings - * according to encoding (only UTF-8 or UTF-16+BOM supported). - * @return number of bytes written or a negative error code. - */ -static int id3v2_put_ttag(ID3v2EncContext *id3, AVIOContext *avioc, const char *str1, const char *str2, - uint32_t tag, enum ID3v2Encoding enc) -{ - int len; - uint8_t *pb; - AVIOContext *dyn_buf; - if (avio_open_dyn_buf(&dyn_buf) < 0) - return AVERROR(ENOMEM); - - /* check if the strings are ASCII-only and use UTF16 only if - * they're not */ - if (enc == ID3v2_ENCODING_UTF16BOM && string_is_ascii(str1) && - (!str2 || string_is_ascii(str2))) - enc = ID3v2_ENCODING_ISO8859; - - avio_w8(dyn_buf, enc); - id3v2_encode_string(dyn_buf, str1, enc); - if (str2) - id3v2_encode_string(dyn_buf, str2, enc); - len = avio_close_dyn_buf(dyn_buf, &pb); - - avio_wb32(avioc, tag); - /* ID3v2.3 frame size is not synchsafe */ - if (id3->version == 3) - avio_wb32(avioc, len); - else - id3v2_put_size(avioc, len); - avio_wb16(avioc, 0); - avio_write(avioc, pb, len); - - av_freep(&pb); - return len + ID3v2_HEADER_SIZE; -} - -static int id3v2_check_write_tag(ID3v2EncContext *id3, AVIOContext *pb, AVDictionaryEntry *t, - const char table[][4], enum ID3v2Encoding enc) -{ - uint32_t tag; - int i; - - if (t->key[0] != 'T' || strlen(t->key) != 4) - return -1; - tag = AV_RB32(t->key); - for (i = 0; *table[i]; i++) - if (tag == AV_RB32(table[i])) - return id3v2_put_ttag(id3, pb, t->value, NULL, tag, enc); - return -1; -} - -static void id3v2_3_metadata_split_date(AVDictionary **pm) -{ - AVDictionaryEntry *mtag = NULL; - AVDictionary *dst = NULL; - const char *key, *value; - char year[5] = {0}, day_month[5] = {0}; - int i; - - while ((mtag = av_dict_get(*pm, "", mtag, AV_DICT_IGNORE_SUFFIX))) { - key = mtag->key; - if (!av_strcasecmp(key, "date")) { - /* split date tag using "YYYY-MM-DD" format into year and month/day segments */ - value = mtag->value; - i = 0; - while (value[i] >= '0' && value[i] <= '9') i++; - if (value[i] == '\0' || value[i] == '-') { - av_strlcpy(year, value, sizeof(year)); - av_dict_set(&dst, "TYER", year, 0); - - if (value[i] == '-' && - value[i+1] >= '0' && value[i+1] <= '1' && - value[i+2] >= '0' && value[i+2] <= '9' && - value[i+3] == '-' && - value[i+4] >= '0' && value[i+4] <= '3' && - value[i+5] >= '0' && value[i+5] <= '9' && - (value[i+6] == '\0' || value[i+6] == ' ')) { - snprintf(day_month, sizeof(day_month), "%.2s%.2s", value + i + 4, value + i + 1); - av_dict_set(&dst, "TDAT", day_month, 0); - } - } else - av_dict_set(&dst, key, value, 0); - } else - av_dict_set(&dst, key, mtag->value, 0); - } - av_dict_free(pm); - *pm = dst; -} - -void ff_id3v2_start(ID3v2EncContext *id3, AVIOContext *pb, int id3v2_version, - const char *magic) -{ - id3->version = id3v2_version; - - avio_wb32(pb, MKBETAG(magic[0], magic[1], magic[2], id3v2_version)); - avio_w8(pb, 0); - avio_w8(pb, 0); /* flags */ - - /* reserve space for size */ - id3->size_pos = avio_tell(pb); - avio_wb32(pb, 0); -} - -int ff_id3v2_write_metadata(AVFormatContext *s, ID3v2EncContext *id3) -{ - AVDictionaryEntry *t = NULL; - int enc = id3->version == 3 ? ID3v2_ENCODING_UTF16BOM : - ID3v2_ENCODING_UTF8; - - ff_metadata_conv(&s->metadata, ff_id3v2_34_metadata_conv, NULL); - if (id3->version == 3) - id3v2_3_metadata_split_date(&s->metadata); - else if (id3->version == 4) - ff_metadata_conv(&s->metadata, ff_id3v2_4_metadata_conv, NULL); - - while ((t = av_dict_get(s->metadata, "", t, AV_DICT_IGNORE_SUFFIX))) { - int ret; - - if ((ret = id3v2_check_write_tag(id3, s->pb, t, ff_id3v2_tags, enc)) > 0) { - id3->len += ret; - continue; - } - if ((ret = id3v2_check_write_tag(id3, s->pb, t, id3->version == 3 ? - ff_id3v2_3_tags : ff_id3v2_4_tags, enc)) > 0) { - id3->len += ret; - continue; - } - - /* unknown tag, write as TXXX frame */ - if ((ret = id3v2_put_ttag(id3, s->pb, t->key, t->value, MKBETAG('T', 'X', 'X', 'X'), enc)) < 0) - return ret; - id3->len += ret; - } - - return 0; -} - -int ff_id3v2_write_apic(AVFormatContext *s, ID3v2EncContext *id3, AVPacket *pkt) -{ - AVStream *st = s->streams[pkt->stream_index]; - AVDictionaryEntry *e; - - AVIOContext *dyn_buf; - uint8_t *buf; - const CodecMime *mime = ff_id3v2_mime_tags; - const char *mimetype = NULL, *desc = ""; - int enc = id3->version == 3 ? ID3v2_ENCODING_UTF16BOM : - ID3v2_ENCODING_UTF8; - int i, len, type = 0; - - /* get the mimetype*/ - while (mime->id != AV_CODEC_ID_NONE) { - if (mime->id == st->codec->codec_id) { - mimetype = mime->str; - break; - } - mime++; - } - if (!mimetype) { - av_log(s, AV_LOG_ERROR, "No mimetype is known for stream %d, cannot " - "write an attached picture.\n", st->index); - return AVERROR(EINVAL); - } - - /* get the picture type */ - e = av_dict_get(st->metadata, "comment", NULL, 0); - for (i = 0; e && i < FF_ARRAY_ELEMS(ff_id3v2_picture_types); i++) { - if (strstr(ff_id3v2_picture_types[i], e->value) == ff_id3v2_picture_types[i]) { - type = i; - break; - } - } - - /* get the description */ - if ((e = av_dict_get(st->metadata, "title", NULL, 0))) - desc = e->value; - - /* start writing */ - if (avio_open_dyn_buf(&dyn_buf) < 0) - return AVERROR(ENOMEM); - - avio_w8(dyn_buf, enc); - avio_put_str(dyn_buf, mimetype); - avio_w8(dyn_buf, type); - id3v2_encode_string(dyn_buf, desc, enc); - avio_write(dyn_buf, pkt->data, pkt->size); - len = avio_close_dyn_buf(dyn_buf, &buf); - - avio_wb32(s->pb, MKBETAG('A', 'P', 'I', 'C')); - if (id3->version == 3) - avio_wb32(s->pb, len); - else - id3v2_put_size(s->pb, len); - avio_wb16(s->pb, 0); - avio_write(s->pb, buf, len); - av_freep(&buf); - - id3->len += len + ID3v2_HEADER_SIZE; - - return 0; -} - -void ff_id3v2_finish(ID3v2EncContext *id3, AVIOContext *pb) -{ - int64_t cur_pos = avio_tell(pb); - avio_seek(pb, id3->size_pos, SEEK_SET); - id3v2_put_size(pb, id3->len); - avio_seek(pb, cur_pos, SEEK_SET); -} - -int ff_id3v2_write_simple(struct AVFormatContext *s, int id3v2_version, - const char *magic) -{ - ID3v2EncContext id3 = { 0 }; - int ret; - - ff_id3v2_start(&id3, s->pb, id3v2_version, magic); - if ((ret = ff_id3v2_write_metadata(s, &id3)) < 0) - return ret; - ff_id3v2_finish(&id3, s->pb); - - return 0; -} diff --git a/ffmpeg1/libavformat/idcin.c b/ffmpeg1/libavformat/idcin.c deleted file mode 100644 index 2a8af40..0000000 --- a/ffmpeg1/libavformat/idcin.c +++ /dev/null @@ -1,380 +0,0 @@ -/* - * id Quake II CIN File Demuxer - * Copyright (c) 2003 The ffmpeg Project - * - * 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 - */ - -/** - * @file - * id Quake II CIN file demuxer by Mike Melanson (melanson@pcisys.net) - * For more information about the id CIN format, visit: - * http://www.csse.monash.edu.au/~timf/ - * - * CIN is a somewhat quirky and ill-defined format. Here are some notes - * for anyone trying to understand the technical details of this format: - * - * The format has no definite file signature. This is problematic for a - * general-purpose media player that wants to automatically detect file - * types. However, a CIN file does start with 5 32-bit numbers that - * specify audio and video parameters. This demuxer gets around the lack - * of file signature by performing sanity checks on those parameters. - * Probabalistically, this is a reasonable solution since the number of - * valid combinations of the 5 parameters is a very small subset of the - * total 160-bit number space. - * - * Refer to the function idcin_probe() for the precise A/V parameters - * that this demuxer allows. - * - * Next, each audio and video frame has a duration of 1/14 sec. If the - * audio sample rate is a multiple of the common frequency 22050 Hz it will - * divide evenly by 14. However, if the sample rate is 11025 Hz: - * 11025 (samples/sec) / 14 (frames/sec) = 787.5 (samples/frame) - * The way the CIN stores audio in this case is by storing 787 sample - * frames in the first audio frame and 788 sample frames in the second - * audio frame. Therefore, the total number of bytes in an audio frame - * is given as: - * audio frame #0: 787 * (bytes/sample) * (# channels) bytes in frame - * audio frame #1: 788 * (bytes/sample) * (# channels) bytes in frame - * audio frame #2: 787 * (bytes/sample) * (# channels) bytes in frame - * audio frame #3: 788 * (bytes/sample) * (# channels) bytes in frame - * - * Finally, not all id CIN creation tools agree on the resolution of the - * color palette, apparently. Some creation tools specify red, green, and - * blue palette components in terms of 6-bit VGA color DAC values which - * range from 0..63. Other tools specify the RGB components as full 8-bit - * values that range from 0..255. Since there are no markers in the file to - * differentiate between the two variants, this demuxer uses the following - * heuristic: - * - load the 768 palette bytes from disk - * - assume that they will need to be shifted left by 2 bits to - * transform them from 6-bit values to 8-bit values - * - scan through all 768 palette bytes - * - if any bytes exceed 63, do not shift the bytes at all before - * transmitting them to the video decoder - */ - -#include "libavutil/channel_layout.h" -#include "libavutil/imgutils.h" -#include "libavutil/intreadwrite.h" -#include "avformat.h" -#include "internal.h" - -#define HUFFMAN_TABLE_SIZE (64 * 1024) -#define IDCIN_FPS 14 - -typedef struct IdcinDemuxContext { - int video_stream_index; - int audio_stream_index; - int audio_chunk_size1; - int audio_chunk_size2; - int block_align; - - /* demux state variables */ - int current_audio_chunk; - int next_chunk_is_video; - int audio_present; - int64_t first_pkt_pos; -} IdcinDemuxContext; - -static int idcin_probe(AVProbeData *p) -{ - unsigned int number; - - /* - * This is what you could call a "probabilistic" file check: id CIN - * files don't have a definite file signature. In lieu of such a marker, - * perform sanity checks on the 5 32-bit header fields: - * width, height: greater than 0, less than or equal to 1024 - * audio sample rate: greater than or equal to 8000, less than or - * equal to 48000, or 0 for no audio - * audio sample width (bytes/sample): 0 for no audio, or 1 or 2 - * audio channels: 0 for no audio, or 1 or 2 - */ - - /* check we have enough data to do all checks, otherwise the - 0-padding may cause a wrong recognition */ - if (p->buf_size < 20) - return 0; - - /* check the video width */ - number = AV_RL32(&p->buf[0]); - if ((number == 0) || (number > 1024)) - return 0; - - /* check the video height */ - number = AV_RL32(&p->buf[4]); - if ((number == 0) || (number > 1024)) - return 0; - - /* check the audio sample rate */ - number = AV_RL32(&p->buf[8]); - if ((number != 0) && ((number < 8000) | (number > 48000))) - return 0; - - /* check the audio bytes/sample */ - number = AV_RL32(&p->buf[12]); - if (number > 2) - return 0; - - /* check the audio channels */ - number = AV_RL32(&p->buf[16]); - if (number > 2) - return 0; - - /* return half certainly since this check is a bit sketchy */ - return AVPROBE_SCORE_MAX / 2; -} - -static int idcin_read_header(AVFormatContext *s) -{ - AVIOContext *pb = s->pb; - IdcinDemuxContext *idcin = s->priv_data; - AVStream *st; - unsigned int width, height; - unsigned int sample_rate, bytes_per_sample, channels; - int ret; - - /* get the 5 header parameters */ - width = avio_rl32(pb); - height = avio_rl32(pb); - sample_rate = avio_rl32(pb); - bytes_per_sample = avio_rl32(pb); - channels = avio_rl32(pb); - - if (s->pb->eof_reached) { - av_log(s, AV_LOG_ERROR, "incomplete header\n"); - return s->pb->error ? s->pb->error : AVERROR_EOF; - } - - if (av_image_check_size(width, height, 0, s) < 0) - return AVERROR_INVALIDDATA; - if (sample_rate > 0) { - if (sample_rate < 14 || sample_rate > INT_MAX) { - av_log(s, AV_LOG_ERROR, "invalid sample rate: %u\n", sample_rate); - return AVERROR_INVALIDDATA; - } - if (bytes_per_sample < 1 || bytes_per_sample > 2) { - av_log(s, AV_LOG_ERROR, "invalid bytes per sample: %u\n", - bytes_per_sample); - return AVERROR_INVALIDDATA; - } - if (channels < 1 || channels > 2) { - av_log(s, AV_LOG_ERROR, "invalid channels: %u\n", channels); - return AVERROR_INVALIDDATA; - } - idcin->audio_present = 1; - } else { - /* if sample rate is 0, assume no audio */ - idcin->audio_present = 0; - } - - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - avpriv_set_pts_info(st, 33, 1, IDCIN_FPS); - st->start_time = 0; - idcin->video_stream_index = st->index; - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = AV_CODEC_ID_IDCIN; - st->codec->codec_tag = 0; /* no fourcc */ - st->codec->width = width; - st->codec->height = height; - - /* load up the Huffman tables into extradata */ - st->codec->extradata_size = HUFFMAN_TABLE_SIZE; - st->codec->extradata = av_malloc(HUFFMAN_TABLE_SIZE); - ret = avio_read(pb, st->codec->extradata, HUFFMAN_TABLE_SIZE); - if (ret < 0) { - return ret; - } else if (ret != HUFFMAN_TABLE_SIZE) { - av_log(s, AV_LOG_ERROR, "incomplete header\n"); - return AVERROR(EIO); - } - - if (idcin->audio_present) { - idcin->audio_present = 1; - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - avpriv_set_pts_info(st, 63, 1, sample_rate); - st->start_time = 0; - idcin->audio_stream_index = st->index; - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_tag = 1; - st->codec->channels = channels; - st->codec->channel_layout = channels > 1 ? AV_CH_LAYOUT_STEREO : - AV_CH_LAYOUT_MONO; - st->codec->sample_rate = sample_rate; - st->codec->bits_per_coded_sample = bytes_per_sample * 8; - st->codec->bit_rate = sample_rate * bytes_per_sample * 8 * channels; - st->codec->block_align = idcin->block_align = bytes_per_sample * channels; - if (bytes_per_sample == 1) - st->codec->codec_id = AV_CODEC_ID_PCM_U8; - else - st->codec->codec_id = AV_CODEC_ID_PCM_S16LE; - - if (sample_rate % 14 != 0) { - idcin->audio_chunk_size1 = (sample_rate / 14) * - bytes_per_sample * channels; - idcin->audio_chunk_size2 = (sample_rate / 14 + 1) * - bytes_per_sample * channels; - } else { - idcin->audio_chunk_size1 = idcin->audio_chunk_size2 = - (sample_rate / 14) * bytes_per_sample * channels; - } - idcin->current_audio_chunk = 0; - } - - idcin->next_chunk_is_video = 1; - idcin->first_pkt_pos = avio_tell(s->pb); - - return 0; -} - -static int idcin_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - int ret; - unsigned int command; - unsigned int chunk_size; - IdcinDemuxContext *idcin = s->priv_data; - AVIOContext *pb = s->pb; - int i; - int palette_scale; - unsigned char r, g, b; - unsigned char palette_buffer[768]; - uint32_t palette[256]; - - if (url_feof(s->pb)) - return s->pb->error ? s->pb->error : AVERROR_EOF; - - if (idcin->next_chunk_is_video) { - command = avio_rl32(pb); - if (command == 2) { - return AVERROR(EIO); - } else if (command == 1) { - /* trigger a palette change */ - ret = avio_read(pb, palette_buffer, 768); - if (ret < 0) { - return ret; - } else if (ret != 768) { - av_log(s, AV_LOG_ERROR, "incomplete packet\n"); - return AVERROR(EIO); - } - /* scale the palette as necessary */ - palette_scale = 2; - for (i = 0; i < 768; i++) - if (palette_buffer[i] > 63) { - palette_scale = 0; - break; - } - - for (i = 0; i < 256; i++) { - r = palette_buffer[i * 3 ] << palette_scale; - g = palette_buffer[i * 3 + 1] << palette_scale; - b = palette_buffer[i * 3 + 2] << palette_scale; - palette[i] = (0xFFU << 24) | (r << 16) | (g << 8) | (b); - if (palette_scale == 2) - palette[i] |= palette[i] >> 6 & 0x30303; - } - } - - if (s->pb->eof_reached) { - av_log(s, AV_LOG_ERROR, "incomplete packet\n"); - return s->pb->error ? s->pb->error : AVERROR_EOF; - } - chunk_size = avio_rl32(pb); - if (chunk_size < 4 || chunk_size > INT_MAX - 4) { - av_log(s, AV_LOG_ERROR, "invalid chunk size: %u\n", chunk_size); - return AVERROR_INVALIDDATA; - } - /* skip the number of decoded bytes (always equal to width * height) */ - avio_skip(pb, 4); - if (chunk_size < 4) - return AVERROR_INVALIDDATA; - chunk_size -= 4; - ret= av_get_packet(pb, pkt, chunk_size); - if (ret < 0) - return ret; - else if (ret != chunk_size) { - av_log(s, AV_LOG_ERROR, "incomplete packet\n"); - av_free_packet(pkt); - return AVERROR(EIO); - } - if (command == 1) { - uint8_t *pal; - - pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, - AVPALETTE_SIZE); - if (!pal) { - av_free_packet(pkt); - return AVERROR(ENOMEM); - } - memcpy(pal, palette, AVPALETTE_SIZE); - pkt->flags |= AV_PKT_FLAG_KEY; - } - pkt->stream_index = idcin->video_stream_index; - pkt->duration = 1; - } else { - /* send out the audio chunk */ - if (idcin->current_audio_chunk) - chunk_size = idcin->audio_chunk_size2; - else - chunk_size = idcin->audio_chunk_size1; - ret= av_get_packet(pb, pkt, chunk_size); - if (ret < 0) - return ret; - pkt->stream_index = idcin->audio_stream_index; - pkt->duration = chunk_size / idcin->block_align; - - idcin->current_audio_chunk ^= 1; - } - - if (idcin->audio_present) - idcin->next_chunk_is_video ^= 1; - - return 0; -} - -static int idcin_read_seek(AVFormatContext *s, int stream_index, - int64_t timestamp, int flags) -{ - IdcinDemuxContext *idcin = s->priv_data; - - if (idcin->first_pkt_pos > 0) { - int ret = avio_seek(s->pb, idcin->first_pkt_pos, SEEK_SET); - if (ret < 0) - return ret; - ff_update_cur_dts(s, s->streams[idcin->video_stream_index], 0); - idcin->next_chunk_is_video = 1; - idcin->current_audio_chunk = 0; - return 0; - } - return -1; -} - -AVInputFormat ff_idcin_demuxer = { - .name = "idcin", - .long_name = NULL_IF_CONFIG_SMALL("id Cinematic"), - .priv_data_size = sizeof(IdcinDemuxContext), - .read_probe = idcin_probe, - .read_header = idcin_read_header, - .read_packet = idcin_read_packet, - .read_seek = idcin_read_seek, - .flags = AVFMT_NO_BYTE_SEEK, -}; diff --git a/ffmpeg1/libavformat/idroqdec.c b/ffmpeg1/libavformat/idroqdec.c deleted file mode 100644 index 6f843d7..0000000 --- a/ffmpeg1/libavformat/idroqdec.c +++ /dev/null @@ -1,237 +0,0 @@ -/* - * id RoQ (.roq) File Demuxer - * Copyright (c) 2003 The ffmpeg Project - * - * 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 - */ - -/** - * @file - * id RoQ format file demuxer - * by Mike Melanson (melanson@pcisys.net) - * for more information on the .roq file format, visit: - * http://www.csse.monash.edu.au/~timf/ - */ - -#include "libavutil/channel_layout.h" -#include "libavutil/intreadwrite.h" -#include "avformat.h" -#include "internal.h" -#include "avio_internal.h" - -#define RoQ_MAGIC_NUMBER 0x1084 -#define RoQ_CHUNK_PREAMBLE_SIZE 8 -#define RoQ_AUDIO_SAMPLE_RATE 22050 -#define RoQ_CHUNKS_TO_SCAN 30 - -#define RoQ_INFO 0x1001 -#define RoQ_QUAD_CODEBOOK 0x1002 -#define RoQ_QUAD_VQ 0x1011 -#define RoQ_SOUND_MONO 0x1020 -#define RoQ_SOUND_STEREO 0x1021 - -typedef struct RoqDemuxContext { - - int frame_rate; - int width; - int height; - int audio_channels; - - int video_stream_index; - int audio_stream_index; - - int64_t video_pts; - unsigned int audio_frame_count; - -} RoqDemuxContext; - -static int roq_probe(AVProbeData *p) -{ - if ((AV_RL16(&p->buf[0]) != RoQ_MAGIC_NUMBER) || - (AV_RL32(&p->buf[2]) != 0xFFFFFFFF)) - return 0; - - return AVPROBE_SCORE_MAX; -} - -static int roq_read_header(AVFormatContext *s) -{ - RoqDemuxContext *roq = s->priv_data; - AVIOContext *pb = s->pb; - unsigned char preamble[RoQ_CHUNK_PREAMBLE_SIZE]; - - /* get the main header */ - if (avio_read(pb, preamble, RoQ_CHUNK_PREAMBLE_SIZE) != - RoQ_CHUNK_PREAMBLE_SIZE) - return AVERROR(EIO); - roq->frame_rate = AV_RL16(&preamble[6]); - - /* init private context parameters */ - roq->width = roq->height = roq->audio_channels = roq->video_pts = - roq->audio_frame_count = 0; - roq->audio_stream_index = -1; - roq->video_stream_index = -1; - - s->ctx_flags |= AVFMTCTX_NOHEADER; - - return 0; -} - -static int roq_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - RoqDemuxContext *roq = s->priv_data; - AVIOContext *pb = s->pb; - int ret = 0; - unsigned int chunk_size; - unsigned int chunk_type; - unsigned int codebook_size; - unsigned char preamble[RoQ_CHUNK_PREAMBLE_SIZE]; - int packet_read = 0; - int64_t codebook_offset; - - while (!packet_read) { - - if (url_feof(s->pb)) - return AVERROR(EIO); - - /* get the next chunk preamble */ - if ((ret = avio_read(pb, preamble, RoQ_CHUNK_PREAMBLE_SIZE)) != - RoQ_CHUNK_PREAMBLE_SIZE) - return AVERROR(EIO); - - chunk_type = AV_RL16(&preamble[0]); - chunk_size = AV_RL32(&preamble[2]); - if(chunk_size > INT_MAX) - return AVERROR_INVALIDDATA; - - chunk_size = ffio_limit(pb, chunk_size); - - switch (chunk_type) { - - case RoQ_INFO: - if (roq->video_stream_index == -1) { - AVStream *st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - avpriv_set_pts_info(st, 63, 1, roq->frame_rate); - roq->video_stream_index = st->index; - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = AV_CODEC_ID_ROQ; - st->codec->codec_tag = 0; /* no fourcc */ - - if (avio_read(pb, preamble, RoQ_CHUNK_PREAMBLE_SIZE) != RoQ_CHUNK_PREAMBLE_SIZE) - return AVERROR(EIO); - st->codec->width = roq->width = AV_RL16(preamble); - st->codec->height = roq->height = AV_RL16(preamble + 2); - break; - } - /* don't care about this chunk anymore */ - avio_skip(pb, RoQ_CHUNK_PREAMBLE_SIZE); - break; - - case RoQ_QUAD_CODEBOOK: - /* packet needs to contain both this codebook and next VQ chunk */ - codebook_offset = avio_tell(pb) - RoQ_CHUNK_PREAMBLE_SIZE; - codebook_size = chunk_size; - avio_skip(pb, codebook_size); - if (avio_read(pb, preamble, RoQ_CHUNK_PREAMBLE_SIZE) != - RoQ_CHUNK_PREAMBLE_SIZE) - return AVERROR(EIO); - chunk_size = AV_RL32(&preamble[2]) + RoQ_CHUNK_PREAMBLE_SIZE * 2 + - codebook_size; - - /* rewind */ - avio_seek(pb, codebook_offset, SEEK_SET); - - /* load up the packet */ - ret= av_get_packet(pb, pkt, chunk_size); - if (ret != chunk_size) - return AVERROR(EIO); - pkt->stream_index = roq->video_stream_index; - pkt->pts = roq->video_pts++; - - packet_read = 1; - break; - - case RoQ_SOUND_MONO: - case RoQ_SOUND_STEREO: - if (roq->audio_stream_index == -1) { - AVStream *st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - avpriv_set_pts_info(st, 32, 1, RoQ_AUDIO_SAMPLE_RATE); - roq->audio_stream_index = st->index; - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = AV_CODEC_ID_ROQ_DPCM; - st->codec->codec_tag = 0; /* no tag */ - if (chunk_type == RoQ_SOUND_STEREO) { - st->codec->channels = 2; - st->codec->channel_layout = AV_CH_LAYOUT_STEREO; - } else { - st->codec->channels = 1; - st->codec->channel_layout = AV_CH_LAYOUT_MONO; - } - roq->audio_channels = st->codec->channels; - st->codec->sample_rate = RoQ_AUDIO_SAMPLE_RATE; - st->codec->bits_per_coded_sample = 16; - st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * - st->codec->bits_per_coded_sample; - st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample; - } - case RoQ_QUAD_VQ: - /* load up the packet */ - if (av_new_packet(pkt, chunk_size + RoQ_CHUNK_PREAMBLE_SIZE)) - return AVERROR(EIO); - /* copy over preamble */ - memcpy(pkt->data, preamble, RoQ_CHUNK_PREAMBLE_SIZE); - - if (chunk_type == RoQ_QUAD_VQ) { - pkt->stream_index = roq->video_stream_index; - pkt->pts = roq->video_pts++; - } else { - pkt->stream_index = roq->audio_stream_index; - pkt->pts = roq->audio_frame_count; - roq->audio_frame_count += (chunk_size / roq->audio_channels); - } - - pkt->pos= avio_tell(pb); - ret = avio_read(pb, pkt->data + RoQ_CHUNK_PREAMBLE_SIZE, - chunk_size); - if (ret != chunk_size) - ret = AVERROR(EIO); - - packet_read = 1; - break; - - default: - av_log(s, AV_LOG_ERROR, " unknown RoQ chunk (%04X)\n", chunk_type); - return AVERROR_INVALIDDATA; - } - } - - return ret; -} - -AVInputFormat ff_roq_demuxer = { - .name = "roq", - .long_name = NULL_IF_CONFIG_SMALL("id RoQ"), - .priv_data_size = sizeof(RoqDemuxContext), - .read_probe = roq_probe, - .read_header = roq_read_header, - .read_packet = roq_read_packet, -}; diff --git a/ffmpeg1/libavformat/idroqenc.c b/ffmpeg1/libavformat/idroqenc.c deleted file mode 100644 index 50c4280..0000000 --- a/ffmpeg1/libavformat/idroqenc.c +++ /dev/null @@ -1,46 +0,0 @@ -/* - * id RoQ (.roq) File muxer - * Copyright (c) 2007 Vitor Sessak - * - * 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 "rawenc.h" - - -static int roq_write_header(struct AVFormatContext *s) -{ - static const uint8_t header[] = { - 0x84, 0x10, 0xFF, 0xFF, 0xFF, 0xFF, 0x1E, 0x00 - }; - - avio_write(s->pb, header, 8); - avio_flush(s->pb); - - return 0; -} - -AVOutputFormat ff_roq_muxer = { - .name = "roq", - .long_name = NULL_IF_CONFIG_SMALL("raw id RoQ"), - .extensions = "roq", - .audio_codec = AV_CODEC_ID_ROQ_DPCM, - .video_codec = AV_CODEC_ID_ROQ, - .write_header = roq_write_header, - .write_packet = ff_raw_write_packet, -}; diff --git a/ffmpeg1/libavformat/iff.c b/ffmpeg1/libavformat/iff.c deleted file mode 100644 index 1efc147..0000000 --- a/ffmpeg1/libavformat/iff.c +++ /dev/null @@ -1,485 +0,0 @@ -/* - * Copyright (c) 2008 Jaikrishnan Menon - * Copyright (c) 2010 Peter Ross - * Copyright (c) 2010 Sebastian Vater - * - * 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 - */ - -/** - * @file - * IFF file demuxer - * by Jaikrishnan Menon - * for more information on the .iff file format, visit: - * http://wiki.multimedia.cx/index.php?title=IFF - */ - -#include "libavutil/avassert.h" -#include "libavutil/channel_layout.h" -#include "libavutil/intreadwrite.h" -#include "libavutil/dict.h" -#include "libavcodec/bytestream.h" -#include "avformat.h" -#include "internal.h" - -#define ID_8SVX MKTAG('8','S','V','X') -#define ID_16SV MKTAG('1','6','S','V') -#define ID_MAUD MKTAG('M','A','U','D') -#define ID_MHDR MKTAG('M','H','D','R') -#define ID_MDAT MKTAG('M','D','A','T') -#define ID_VHDR MKTAG('V','H','D','R') -#define ID_ATAK MKTAG('A','T','A','K') -#define ID_RLSE MKTAG('R','L','S','E') -#define ID_CHAN MKTAG('C','H','A','N') -#define ID_PBM MKTAG('P','B','M',' ') -#define ID_ILBM MKTAG('I','L','B','M') -#define ID_BMHD MKTAG('B','M','H','D') -#define ID_DGBL MKTAG('D','G','B','L') -#define ID_CAMG MKTAG('C','A','M','G') -#define ID_CMAP MKTAG('C','M','A','P') -#define ID_ACBM MKTAG('A','C','B','M') -#define ID_DEEP MKTAG('D','E','E','P') -#define ID_RGB8 MKTAG('R','G','B','8') -#define ID_RGBN MKTAG('R','G','B','N') - -#define ID_FORM MKTAG('F','O','R','M') -#define ID_ANNO MKTAG('A','N','N','O') -#define ID_AUTH MKTAG('A','U','T','H') -#define ID_CHRS MKTAG('C','H','R','S') -#define ID_COPYRIGHT MKTAG('(','c',')',' ') -#define ID_CSET MKTAG('C','S','E','T') -#define ID_FVER MKTAG('F','V','E','R') -#define ID_NAME MKTAG('N','A','M','E') -#define ID_TEXT MKTAG('T','E','X','T') -#define ID_ABIT MKTAG('A','B','I','T') -#define ID_BODY MKTAG('B','O','D','Y') -#define ID_DBOD MKTAG('D','B','O','D') -#define ID_DPEL MKTAG('D','P','E','L') -#define ID_DLOC MKTAG('D','L','O','C') -#define ID_TVDC MKTAG('T','V','D','C') - -#define LEFT 2 -#define RIGHT 4 -#define STEREO 6 - -/** - * This number of bytes if added at the beginning of each AVPacket - * which contain additional information about video properties - * which has to be shared between demuxer and decoder. - * This number may change between frames, e.g. the demuxer might - * set it to smallest possible size of 2 to indicate that there's - * no extradata changing in this frame. - */ -#define IFF_EXTRA_VIDEO_SIZE 41 - -typedef enum { - COMP_NONE, - COMP_FIB, - COMP_EXP -} svx8_compression_type; - -typedef struct { - int64_t body_pos; - int64_t body_end; - uint32_t body_size; - svx8_compression_type svx8_compression; - unsigned maud_bits; - unsigned maud_compression; - unsigned bitmap_compression; ///< delta compression method used - unsigned bpp; ///< bits per plane to decode (differs from bits_per_coded_sample if HAM) - unsigned ham; ///< 0 if non-HAM or number of hold bits (6 for bpp > 6, 4 otherwise) - unsigned flags; ///< 1 for EHB, 0 is no extra half darkening - unsigned transparency; ///< transparency color index in palette - unsigned masking; ///< masking method used - uint8_t tvdc[32]; ///< TVDC lookup table -} IffDemuxContext; - -/* Metadata string read */ -static int get_metadata(AVFormatContext *s, - const char *const tag, - const unsigned data_size) -{ - uint8_t *buf = ((data_size + 1) == 0) ? NULL : av_malloc(data_size + 1); - - if (!buf) - return AVERROR(ENOMEM); - - if (avio_read(s->pb, buf, data_size) < 0) { - av_free(buf); - return AVERROR(EIO); - } - buf[data_size] = 0; - av_dict_set(&s->metadata, tag, buf, AV_DICT_DONT_STRDUP_VAL); - return 0; -} - -static int iff_probe(AVProbeData *p) -{ - const uint8_t *d = p->buf; - - if ( AV_RL32(d) == ID_FORM && - (AV_RL32(d+8) == ID_8SVX || - AV_RL32(d+8) == ID_16SV || - AV_RL32(d+8) == ID_MAUD || - AV_RL32(d+8) == ID_PBM || - AV_RL32(d+8) == ID_ACBM || - AV_RL32(d+8) == ID_DEEP || - AV_RL32(d+8) == ID_ILBM || - AV_RL32(d+8) == ID_RGB8 || - AV_RL32(d+8) == ID_RGBN) ) - return AVPROBE_SCORE_MAX; - return 0; -} - -static const uint8_t deep_rgb24[] = {0, 0, 0, 3, 0, 1, 0, 8, 0, 2, 0, 8, 0, 3, 0, 8}; -static const uint8_t deep_rgba[] = {0, 0, 0, 4, 0, 1, 0, 8, 0, 2, 0, 8, 0, 3, 0, 8}; -static const uint8_t deep_bgra[] = {0, 0, 0, 4, 0, 3, 0, 8, 0, 2, 0, 8, 0, 1, 0, 8}; -static const uint8_t deep_argb[] = {0, 0, 0, 4, 0,17, 0, 8, 0, 1, 0, 8, 0, 2, 0, 8}; -static const uint8_t deep_abgr[] = {0, 0, 0, 4, 0,17, 0, 8, 0, 3, 0, 8, 0, 2, 0, 8}; - -static int iff_read_header(AVFormatContext *s) -{ - IffDemuxContext *iff = s->priv_data; - AVIOContext *pb = s->pb; - AVStream *st; - uint8_t *buf; - uint32_t chunk_id, data_size; - uint32_t screenmode = 0, num, den; - unsigned transparency = 0; - unsigned masking = 0; // no mask - uint8_t fmt[16]; - int fmt_size; - - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - - st->codec->channels = 1; - st->codec->channel_layout = AV_CH_LAYOUT_MONO; - avio_skip(pb, 8); - // codec_tag used by ByteRun1 decoder to distinguish progressive (PBM) and interlaced (ILBM) content - st->codec->codec_tag = avio_rl32(pb); - iff->bitmap_compression = -1; - iff->svx8_compression = -1; - iff->maud_bits = -1; - iff->maud_compression = -1; - - while(!url_feof(pb)) { - uint64_t orig_pos; - int res; - const char *metadata_tag = NULL; - chunk_id = avio_rl32(pb); - data_size = avio_rb32(pb); - orig_pos = avio_tell(pb); - - switch(chunk_id) { - case ID_VHDR: - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - - if (data_size < 14) - return AVERROR_INVALIDDATA; - avio_skip(pb, 12); - st->codec->sample_rate = avio_rb16(pb); - if (data_size >= 16) { - avio_skip(pb, 1); - iff->svx8_compression = avio_r8(pb); - } - break; - - case ID_MHDR: - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - - if (data_size < 32) - return AVERROR_INVALIDDATA; - avio_skip(pb, 4); - iff->maud_bits = avio_rb16(pb); - avio_skip(pb, 2); - num = avio_rb32(pb); - den = avio_rb16(pb); - if (!den) - return AVERROR_INVALIDDATA; - avio_skip(pb, 2); - st->codec->sample_rate = num / den; - st->codec->channels = avio_rb16(pb); - iff->maud_compression = avio_rb16(pb); - if (st->codec->channels == 1) - st->codec->channel_layout = AV_CH_LAYOUT_MONO; - else if (st->codec->channels == 2) - st->codec->channel_layout = AV_CH_LAYOUT_STEREO; - break; - - case ID_ABIT: - case ID_BODY: - case ID_DBOD: - case ID_MDAT: - iff->body_pos = avio_tell(pb); - iff->body_end = iff->body_pos + data_size; - iff->body_size = data_size; - break; - - case ID_CHAN: - if (data_size < 4) - return AVERROR_INVALIDDATA; - if (avio_rb32(pb) < 6) { - st->codec->channels = 1; - st->codec->channel_layout = AV_CH_LAYOUT_MONO; - } else { - st->codec->channels = 2; - st->codec->channel_layout = AV_CH_LAYOUT_STEREO; - } - break; - - case ID_CAMG: - if (data_size < 4) - return AVERROR_INVALIDDATA; - screenmode = avio_rb32(pb); - break; - - case ID_CMAP: - if (data_size < 3 || data_size > 768 || data_size % 3) { - av_log(s, AV_LOG_ERROR, "Invalid CMAP chunk size %d\n", - data_size); - return AVERROR_INVALIDDATA; - } - st->codec->extradata_size = data_size + IFF_EXTRA_VIDEO_SIZE; - st->codec->extradata = av_malloc(data_size + IFF_EXTRA_VIDEO_SIZE + FF_INPUT_BUFFER_PADDING_SIZE); - if (!st->codec->extradata) - return AVERROR(ENOMEM); - if (avio_read(pb, st->codec->extradata + IFF_EXTRA_VIDEO_SIZE, data_size) < 0) - return AVERROR(EIO); - break; - - case ID_BMHD: - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - if (data_size <= 8) - return AVERROR_INVALIDDATA; - st->codec->width = avio_rb16(pb); - st->codec->height = avio_rb16(pb); - avio_skip(pb, 4); // x, y offset - st->codec->bits_per_coded_sample = avio_r8(pb); - if (data_size >= 10) - masking = avio_r8(pb); - if (data_size >= 11) - iff->bitmap_compression = avio_r8(pb); - if (data_size >= 14) { - avio_skip(pb, 1); // padding - transparency = avio_rb16(pb); - } - if (data_size >= 16) { - st->sample_aspect_ratio.num = avio_r8(pb); - st->sample_aspect_ratio.den = avio_r8(pb); - } - break; - - case ID_DPEL: - if (data_size < 4 || (data_size & 3)) - return AVERROR_INVALIDDATA; - if ((fmt_size = avio_read(pb, fmt, sizeof(fmt))) < 0) - return fmt_size; - if (fmt_size == sizeof(deep_rgb24) && !memcmp(fmt, deep_rgb24, sizeof(deep_rgb24))) - st->codec->pix_fmt = AV_PIX_FMT_RGB24; - else if (fmt_size == sizeof(deep_rgba) && !memcmp(fmt, deep_rgba, sizeof(deep_rgba))) - st->codec->pix_fmt = AV_PIX_FMT_RGBA; - else if (fmt_size == sizeof(deep_bgra) && !memcmp(fmt, deep_bgra, sizeof(deep_bgra))) - st->codec->pix_fmt = AV_PIX_FMT_BGRA; - else if (fmt_size == sizeof(deep_argb) && !memcmp(fmt, deep_argb, sizeof(deep_argb))) - st->codec->pix_fmt = AV_PIX_FMT_ARGB; - else if (fmt_size == sizeof(deep_abgr) && !memcmp(fmt, deep_abgr, sizeof(deep_abgr))) - st->codec->pix_fmt = AV_PIX_FMT_ABGR; - else { - avpriv_request_sample(s, "color format %.16s", fmt); - return AVERROR_PATCHWELCOME; - } - break; - - case ID_DGBL: - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - if (data_size < 8) - return AVERROR_INVALIDDATA; - st->codec->width = avio_rb16(pb); - st->codec->height = avio_rb16(pb); - iff->bitmap_compression = avio_rb16(pb); - st->sample_aspect_ratio.num = avio_r8(pb); - st->sample_aspect_ratio.den = avio_r8(pb); - st->codec->bits_per_coded_sample = 24; - break; - - case ID_DLOC: - if (data_size < 4) - return AVERROR_INVALIDDATA; - st->codec->width = avio_rb16(pb); - st->codec->height = avio_rb16(pb); - break; - - case ID_TVDC: - if (data_size < sizeof(iff->tvdc)) - return AVERROR_INVALIDDATA; - res = avio_read(pb, iff->tvdc, sizeof(iff->tvdc)); - if (res < 0) - return res; - break; - - case ID_ANNO: - case ID_TEXT: metadata_tag = "comment"; break; - case ID_AUTH: metadata_tag = "artist"; break; - case ID_COPYRIGHT: metadata_tag = "copyright"; break; - case ID_NAME: metadata_tag = "title"; break; - } - - if (metadata_tag) { - if ((res = get_metadata(s, metadata_tag, data_size)) < 0) { - av_log(s, AV_LOG_ERROR, "cannot allocate metadata tag %s!\n", metadata_tag); - return res; - } - } - avio_skip(pb, data_size - (avio_tell(pb) - orig_pos) + (data_size & 1)); - } - - avio_seek(pb, iff->body_pos, SEEK_SET); - - switch(st->codec->codec_type) { - case AVMEDIA_TYPE_AUDIO: - avpriv_set_pts_info(st, 32, 1, st->codec->sample_rate); - - if (st->codec->codec_tag == ID_16SV) - st->codec->codec_id = AV_CODEC_ID_PCM_S16BE_PLANAR; - else if (st->codec->codec_tag == ID_MAUD) { - if (iff->maud_bits == 8 && !iff->maud_compression) { - st->codec->codec_id = AV_CODEC_ID_PCM_U8; - } else if (iff->maud_bits == 16 && !iff->maud_compression) { - st->codec->codec_id = AV_CODEC_ID_PCM_S16BE; - } else if (iff->maud_bits == 8 && iff->maud_compression == 2) { - st->codec->codec_id = AV_CODEC_ID_PCM_ALAW; - } else if (iff->maud_bits == 8 && iff->maud_compression == 3) { - st->codec->codec_id = AV_CODEC_ID_PCM_MULAW; - } else { - avpriv_request_sample(s, "compression %d and bit depth %d", iff->maud_compression, iff->maud_bits); - return AVERROR_PATCHWELCOME; - } - - st->codec->bits_per_coded_sample = - av_get_bits_per_sample(st->codec->codec_id); - - st->codec->block_align = - st->codec->bits_per_coded_sample * st->codec->channels / 8; - } else { - switch (iff->svx8_compression) { - case COMP_NONE: - st->codec->codec_id = AV_CODEC_ID_PCM_S8_PLANAR; - break; - case COMP_FIB: - st->codec->codec_id = AV_CODEC_ID_8SVX_FIB; - break; - case COMP_EXP: - st->codec->codec_id = AV_CODEC_ID_8SVX_EXP; - break; - default: - av_log(s, AV_LOG_ERROR, - "Unknown SVX8 compression method '%d'\n", iff->svx8_compression); - return -1; - } - } - - st->codec->bits_per_coded_sample = av_get_bits_per_sample(st->codec->codec_id); - st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * st->codec->bits_per_coded_sample; - st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample; - break; - - case AVMEDIA_TYPE_VIDEO: - iff->bpp = st->codec->bits_per_coded_sample; - if ((screenmode & 0x800 /* Hold And Modify */) && iff->bpp <= 8) { - iff->ham = iff->bpp > 6 ? 6 : 4; - st->codec->bits_per_coded_sample = 24; - } - iff->flags = (screenmode & 0x80 /* Extra HalfBrite */) && iff->bpp <= 8; - iff->masking = masking; - iff->transparency = transparency; - - if (!st->codec->extradata) { - st->codec->extradata_size = IFF_EXTRA_VIDEO_SIZE; - st->codec->extradata = av_malloc(IFF_EXTRA_VIDEO_SIZE + FF_INPUT_BUFFER_PADDING_SIZE); - if (!st->codec->extradata) - return AVERROR(ENOMEM); - } - av_assert0(st->codec->extradata_size >= IFF_EXTRA_VIDEO_SIZE); - buf = st->codec->extradata; - bytestream_put_be16(&buf, IFF_EXTRA_VIDEO_SIZE); - bytestream_put_byte(&buf, iff->bitmap_compression); - bytestream_put_byte(&buf, iff->bpp); - bytestream_put_byte(&buf, iff->ham); - bytestream_put_byte(&buf, iff->flags); - bytestream_put_be16(&buf, iff->transparency); - bytestream_put_byte(&buf, iff->masking); - bytestream_put_buffer(&buf, iff->tvdc, sizeof(iff->tvdc)); - st->codec->codec_id = AV_CODEC_ID_IFF_ILBM; - break; - default: - return -1; - } - - return 0; -} - -static int iff_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - IffDemuxContext *iff = s->priv_data; - AVIOContext *pb = s->pb; - AVStream *st = s->streams[0]; - int ret; - int64_t pos = avio_tell(pb); - - if (pos >= iff->body_end) - return AVERROR_EOF; - - if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - if (st->codec->codec_tag == ID_MAUD) { - ret = av_get_packet(pb, pkt, FFMIN(iff->body_end - pos, 1024 * st->codec->block_align)); - } else { - ret = av_get_packet(pb, pkt, iff->body_size); - } - } else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { - uint8_t *buf; - - if (av_new_packet(pkt, iff->body_size + 2) < 0) { - return AVERROR(ENOMEM); - } - - buf = pkt->data; - bytestream_put_be16(&buf, 2); - ret = avio_read(pb, buf, iff->body_size); - } else { - av_assert0(0); - } - - if (pos == iff->body_pos) - pkt->flags |= AV_PKT_FLAG_KEY; - if (ret < 0) - return ret; - pkt->stream_index = 0; - return ret; -} - -AVInputFormat ff_iff_demuxer = { - .name = "iff", - .long_name = NULL_IF_CONFIG_SMALL("IFF (Interchange File Format)"), - .priv_data_size = sizeof(IffDemuxContext), - .read_probe = iff_probe, - .read_header = iff_read_header, - .read_packet = iff_read_packet, - .flags = AVFMT_GENERIC_INDEX, -}; diff --git a/ffmpeg1/libavformat/ilbc.c b/ffmpeg1/libavformat/ilbc.c deleted file mode 100644 index 7a23b2f..0000000 --- a/ffmpeg1/libavformat/ilbc.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * iLBC storage file format - * Copyright (c) 2012 Martin Storsjo - * - * 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 "internal.h" - -static const char mode20_header[] = "#!iLBC20\n"; -static const char mode30_header[] = "#!iLBC30\n"; - -static int ilbc_write_header(AVFormatContext *s) -{ - AVIOContext *pb = s->pb; - AVCodecContext *enc; - - if (s->nb_streams != 1) { - av_log(s, AV_LOG_ERROR, "Unsupported number of streams\n"); - return AVERROR(EINVAL); - } - enc = s->streams[0]->codec; - - if (enc->codec_id != AV_CODEC_ID_ILBC) { - av_log(s, AV_LOG_ERROR, "Unsupported codec\n"); - return AVERROR(EINVAL); - } - - if (enc->block_align == 50) { - avio_write(pb, mode30_header, sizeof(mode30_header) - 1); - } else if (enc->block_align == 38) { - avio_write(pb, mode20_header, sizeof(mode20_header) - 1); - } else { - av_log(s, AV_LOG_ERROR, "Unsupported mode\n"); - return AVERROR(EINVAL); - } - avio_flush(pb); - return 0; -} - -static int ilbc_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - avio_write(s->pb, pkt->data, pkt->size); - avio_flush(s->pb); - return 0; -} - -static int ilbc_probe(AVProbeData *p) -{ - // Only check for "#!iLBC" which matches both formats - if (!memcmp(p->buf, mode20_header, 6)) - return AVPROBE_SCORE_MAX; - else - return 0; -} - -static int ilbc_read_header(AVFormatContext *s) -{ - AVIOContext *pb = s->pb; - AVStream *st; - uint8_t header[9]; - - avio_read(pb, header, 9); - - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - st->codec->codec_id = AV_CODEC_ID_ILBC; - st->codec->sample_rate = 8000; - st->codec->channels = 1; - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->start_time = 0; - avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); - if (!memcmp(header, mode20_header, sizeof(mode20_header) - 1)) { - st->codec->block_align = 38; - st->codec->bit_rate = 15200; - } else if (!memcmp(header, mode30_header, sizeof(mode30_header) - 1)) { - st->codec->block_align = 50; - st->codec->bit_rate = 13333; - } else { - av_log(s, AV_LOG_ERROR, "Unrecognized iLBC file header\n"); - return AVERROR_INVALIDDATA; - } - - return 0; -} - -static int ilbc_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - AVCodecContext *enc = s->streams[0]->codec; - int ret; - - if ((ret = av_new_packet(pkt, enc->block_align)) < 0) - return ret; - - pkt->stream_index = 0; - pkt->pos = avio_tell(s->pb); - pkt->duration = enc->block_align == 38 ? 160 : 240; - if ((ret = avio_read(s->pb, pkt->data, enc->block_align)) != enc->block_align) { - av_free_packet(pkt); - return ret < 0 ? ret : AVERROR(EIO); - } - - return 0; -} - -AVInputFormat ff_ilbc_demuxer = { - .name = "ilbc", - .long_name = NULL_IF_CONFIG_SMALL("iLBC storage"), - .read_probe = ilbc_probe, - .read_header = ilbc_read_header, - .read_packet = ilbc_read_packet, - .flags = AVFMT_GENERIC_INDEX, -}; - -AVOutputFormat ff_ilbc_muxer = { - .name = "ilbc", - .long_name = NULL_IF_CONFIG_SMALL("iLBC storage"), - .mime_type = "audio/iLBC", - .extensions = "lbc", - .audio_codec = AV_CODEC_ID_ILBC, - .write_header = ilbc_write_header, - .write_packet = ilbc_write_packet, - .flags = AVFMT_NOTIMESTAMPS, -}; diff --git a/ffmpeg1/libavformat/img2.c b/ffmpeg1/libavformat/img2.c deleted file mode 100644 index eee100a..0000000 --- a/ffmpeg1/libavformat/img2.c +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Image format - * Copyright (c) 2000, 2001, 2002 Fabrice Bellard - * Copyright (c) 2004 Michael Niedermayer - * - * 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 "libavutil/avstring.h" -#include "internal.h" - -typedef struct { - enum AVCodecID id; - const char *str; -} IdStrMap; - -static const IdStrMap img_tags[] = { - { AV_CODEC_ID_MJPEG, "jpeg" }, - { AV_CODEC_ID_MJPEG, "jpg" }, - { AV_CODEC_ID_MJPEG, "jps" }, - { AV_CODEC_ID_LJPEG, "ljpg" }, - { AV_CODEC_ID_JPEGLS, "jls" }, - { AV_CODEC_ID_PNG, "png" }, - { AV_CODEC_ID_PNG, "pns" }, - { AV_CODEC_ID_PNG, "mng" }, - { AV_CODEC_ID_PPM, "ppm" }, - { AV_CODEC_ID_PPM, "pnm" }, - { AV_CODEC_ID_PGM, "pgm" }, - { AV_CODEC_ID_PGMYUV, "pgmyuv" }, - { AV_CODEC_ID_PBM, "pbm" }, - { AV_CODEC_ID_PAM, "pam" }, - { AV_CODEC_ID_MPEG1VIDEO, "mpg1-img" }, - { AV_CODEC_ID_MPEG2VIDEO, "mpg2-img" }, - { AV_CODEC_ID_MPEG4, "mpg4-img" }, - { AV_CODEC_ID_FFV1, "ffv1-img" }, - { AV_CODEC_ID_RAWVIDEO, "y" }, - { AV_CODEC_ID_RAWVIDEO, "raw" }, - { AV_CODEC_ID_BMP, "bmp" }, - { AV_CODEC_ID_GIF, "gif" }, - { AV_CODEC_ID_TARGA, "tga" }, - { AV_CODEC_ID_TIFF, "tiff" }, - { AV_CODEC_ID_TIFF, "tif" }, - { AV_CODEC_ID_SGI, "sgi" }, - { AV_CODEC_ID_PTX, "ptx" }, - { AV_CODEC_ID_PCX, "pcx" }, - { AV_CODEC_ID_BRENDER_PIX, "pix" }, - { AV_CODEC_ID_SUNRAST, "sun" }, - { AV_CODEC_ID_SUNRAST, "ras" }, - { AV_CODEC_ID_SUNRAST, "rs" }, - { AV_CODEC_ID_SUNRAST, "im1" }, - { AV_CODEC_ID_SUNRAST, "im8" }, - { AV_CODEC_ID_SUNRAST, "im24" }, - { AV_CODEC_ID_SUNRAST, "im32" }, - { AV_CODEC_ID_SUNRAST, "sunras" }, - { AV_CODEC_ID_JPEG2000, "j2c" }, - { AV_CODEC_ID_JPEG2000, "j2k" }, - { AV_CODEC_ID_JPEG2000, "jp2" }, - { AV_CODEC_ID_JPEG2000, "jpc" }, - { AV_CODEC_ID_DPX, "dpx" }, - { AV_CODEC_ID_EXR, "exr" }, - { AV_CODEC_ID_PICTOR, "pic" }, - { AV_CODEC_ID_V210X, "yuv10" }, - { AV_CODEC_ID_XBM, "xbm" }, - { AV_CODEC_ID_XFACE, "xface" }, - { AV_CODEC_ID_XWD, "xwd" }, - { AV_CODEC_ID_NONE, NULL } -}; - -static enum AVCodecID av_str2id(const IdStrMap *tags, const char *str) -{ - str = strrchr(str, '.'); - if (!str) - return AV_CODEC_ID_NONE; - str++; - - while (tags->id) { - if (!av_strcasecmp(str, tags->str)) - return tags->id; - - tags++; - } - return AV_CODEC_ID_NONE; -} - -enum AVCodecID ff_guess_image2_codec(const char *filename) -{ - return av_str2id(img_tags, filename); -} diff --git a/ffmpeg1/libavformat/img2dec.c b/ffmpeg1/libavformat/img2dec.c deleted file mode 100644 index 882abb9..0000000 --- a/ffmpeg1/libavformat/img2dec.c +++ /dev/null @@ -1,498 +0,0 @@ -/* - * Image format - * Copyright (c) 2000, 2001, 2002 Fabrice Bellard - * Copyright (c) 2004 Michael Niedermayer - * - * 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 "libavutil/avstring.h" -#include "libavutil/log.h" -#include "libavutil/opt.h" -#include "libavutil/pixdesc.h" -#include "libavutil/parseutils.h" -#include "avformat.h" -#include "internal.h" -#if HAVE_GLOB -#include - -/* Locally define as 0 (bitwise-OR no-op) any missing glob options that - are non-posix glibc/bsd extensions. */ -#ifndef GLOB_NOMAGIC -#define GLOB_NOMAGIC 0 -#endif -#ifndef GLOB_BRACE -#define GLOB_BRACE 0 -#endif - -#endif /* HAVE_GLOB */ - -typedef struct { - const AVClass *class; /**< Class for private options. */ - int img_first; - int img_last; - int img_number; - int64_t pts; - int img_count; - int is_pipe; - int split_planes; /**< use independent file for each Y, U, V plane */ - char path[1024]; - char *pixel_format; /**< Set by a private option. */ - char *video_size; /**< Set by a private option. */ - char *framerate; /**< Set by a private option. */ - int loop; - enum { PT_GLOB_SEQUENCE, PT_GLOB, PT_SEQUENCE } pattern_type; - int use_glob; -#if HAVE_GLOB - glob_t globstate; -#endif - int start_number; - int start_number_range; - int frame_size; -} VideoDemuxData; - -static const int sizes[][2] = { - { 640, 480 }, - { 720, 480 }, - { 720, 576 }, - { 352, 288 }, - { 352, 240 }, - { 160, 128 }, - { 512, 384 }, - { 640, 352 }, - { 640, 240 }, -}; - -static int infer_size(int *width_ptr, int *height_ptr, int size) -{ - int i; - - for (i = 0; i < FF_ARRAY_ELEMS(sizes); i++) { - if ((sizes[i][0] * sizes[i][1]) == size) { - *width_ptr = sizes[i][0]; - *height_ptr = sizes[i][1]; - return 0; - } - } - - return -1; -} - -static int is_glob(const char *path) -{ -#if HAVE_GLOB - size_t span = 0; - const char *p = path; - - while (p = strchr(p, '%')) { - if (*(++p) == '%') { - ++p; - continue; - } - if (span = strspn(p, "*?[]{}")) - break; - } - /* Did we hit a glob char or get to the end? */ - return span != 0; -#else - return 0; -#endif -} - -/** - * Get index range of image files matched by path. - * - * @param pfirst_index pointer to index updated with the first number in the range - * @param plast_index pointer to index updated with the last number in the range - * @param path path which has to be matched by the image files in the range - * @param start_index minimum accepted value for the first index in the range - * @return -1 if no image file could be found - */ -static int find_image_range(int *pfirst_index, int *plast_index, - const char *path, int start_index, int start_index_range) -{ - char buf[1024]; - int range, last_index, range1, first_index; - - /* find the first image */ - for (first_index = start_index; first_index < start_index + start_index_range; first_index++) { - if (av_get_frame_filename(buf, sizeof(buf), path, first_index) < 0) { - *pfirst_index = - *plast_index = 1; - if (avio_check(buf, AVIO_FLAG_READ) > 0) - return 0; - return -1; - } - if (avio_check(buf, AVIO_FLAG_READ) > 0) - break; - } - if (first_index == start_index + start_index_range) - goto fail; - - /* find the last image */ - last_index = first_index; - for (;;) { - range = 0; - for (;;) { - if (!range) - range1 = 1; - else - range1 = 2 * range; - if (av_get_frame_filename(buf, sizeof(buf), path, - last_index + range1) < 0) - goto fail; - if (avio_check(buf, AVIO_FLAG_READ) <= 0) - break; - range = range1; - /* just in case... */ - if (range >= (1 << 30)) - goto fail; - } - /* we are sure than image last_index + range exists */ - if (!range) - break; - last_index += range; - } - *pfirst_index = first_index; - *plast_index = last_index; - return 0; - -fail: - return -1; -} - -static int img_read_probe(AVProbeData *p) -{ - if (p->filename && ff_guess_image2_codec(p->filename)) { - if (av_filename_number_test(p->filename)) - return AVPROBE_SCORE_MAX; - else if (is_glob(p->filename)) - return AVPROBE_SCORE_MAX; - else if (av_match_ext(p->filename, "raw") || av_match_ext(p->filename, "gif")) - return 5; - else - return AVPROBE_SCORE_MAX / 2; - } - return 0; -} - -static int img_read_header(AVFormatContext *s1) -{ - VideoDemuxData *s = s1->priv_data; - int first_index, last_index, ret = 0; - int width = 0, height = 0; - AVStream *st; - enum AVPixelFormat pix_fmt = AV_PIX_FMT_NONE; - AVRational framerate; - - s1->ctx_flags |= AVFMTCTX_NOHEADER; - - st = avformat_new_stream(s1, NULL); - if (!st) { - return AVERROR(ENOMEM); - } - - if (s->pixel_format && - (pix_fmt = av_get_pix_fmt(s->pixel_format)) == AV_PIX_FMT_NONE) { - av_log(s1, AV_LOG_ERROR, "No such pixel format: %s.\n", - s->pixel_format); - return AVERROR(EINVAL); - } - if (s->video_size && - (ret = av_parse_video_size(&width, &height, s->video_size)) < 0) { - av_log(s, AV_LOG_ERROR, - "Could not parse video size: %s.\n", s->video_size); - return ret; - } - if ((ret = av_parse_video_rate(&framerate, s->framerate)) < 0) { - av_log(s, AV_LOG_ERROR, - "Could not parse framerate: %s.\n", s->framerate); - return ret; - } - - av_strlcpy(s->path, s1->filename, sizeof(s->path)); - s->img_number = 0; - s->img_count = 0; - - /* find format */ - if (s1->iformat->flags & AVFMT_NOFILE) - s->is_pipe = 0; - else { - s->is_pipe = 1; - st->need_parsing = AVSTREAM_PARSE_FULL; - } - - avpriv_set_pts_info(st, 60, framerate.den, framerate.num); - - if (width && height) { - st->codec->width = width; - st->codec->height = height; - } - - if (!s->is_pipe) { - if (s->pattern_type == PT_GLOB_SEQUENCE) { - s->use_glob = is_glob(s->path); - if (s->use_glob) { - char *p = s->path, *q, *dup; - int gerr; - - av_log(s1, AV_LOG_WARNING, "Pattern type 'glob_sequence' is deprecated: " - "use pattern_type 'glob' instead\n"); -#if HAVE_GLOB - dup = q = av_strdup(p); - while (*q) { - /* Do we have room for the next char and a \ insertion? */ - if ((p - s->path) >= (sizeof(s->path) - 2)) - break; - if (*q == '%' && strspn(q + 1, "%*?[]{}")) - ++q; - else if (strspn(q, "\\*?[]{}")) - *p++ = '\\'; - *p++ = *q++; - } - *p = 0; - av_free(dup); - - gerr = glob(s->path, GLOB_NOCHECK|GLOB_BRACE|GLOB_NOMAGIC, NULL, &s->globstate); - if (gerr != 0) { - return AVERROR(ENOENT); - } - first_index = 0; - last_index = s->globstate.gl_pathc - 1; -#endif - } - } - if ((s->pattern_type == PT_GLOB_SEQUENCE && !s->use_glob) || s->pattern_type == PT_SEQUENCE) { - if (find_image_range(&first_index, &last_index, s->path, - s->start_number, s->start_number_range) < 0) { - av_log(s1, AV_LOG_ERROR, - "Could find no file with with path '%s' and index in the range %d-%d\n", - s->path, s->start_number, s->start_number + s->start_number_range - 1); - return AVERROR(ENOENT); - } - } else if (s->pattern_type == PT_GLOB) { -#if HAVE_GLOB - int gerr; - gerr = glob(s->path, GLOB_NOCHECK|GLOB_BRACE|GLOB_NOMAGIC, NULL, &s->globstate); - if (gerr != 0) { - return AVERROR(ENOENT); - } - first_index = 0; - last_index = s->globstate.gl_pathc - 1; - s->use_glob = 1; -#else - av_log(s1, AV_LOG_ERROR, - "Pattern type 'glob' was selected but globbing " - "is not supported by this libavformat build\n"); - return AVERROR(ENOSYS); -#endif - } else if (s->pattern_type != PT_GLOB_SEQUENCE) { - av_log(s1, AV_LOG_ERROR, - "Unknown value '%d' for pattern_type option\n", s->pattern_type); - return AVERROR(EINVAL); - } - s->img_first = first_index; - s->img_last = last_index; - s->img_number = first_index; - /* compute duration */ - st->start_time = 0; - st->duration = last_index - first_index + 1; - } - - if (s1->video_codec_id) { - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = s1->video_codec_id; - } else if (s1->audio_codec_id) { - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = s1->audio_codec_id; - } else { - const char *str = strrchr(s->path, '.'); - s->split_planes = str && !av_strcasecmp(str + 1, "y"); - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = ff_guess_image2_codec(s->path); - if (st->codec->codec_id == AV_CODEC_ID_LJPEG) - st->codec->codec_id = AV_CODEC_ID_MJPEG; - } - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && - pix_fmt != AV_PIX_FMT_NONE) - st->codec->pix_fmt = pix_fmt; - - return 0; -} - -static int img_read_packet(AVFormatContext *s1, AVPacket *pkt) -{ - VideoDemuxData *s = s1->priv_data; - char filename_bytes[1024]; - char *filename = filename_bytes; - int i; - int size[3] = { 0 }, ret[3] = { 0 }; - AVIOContext *f[3] = { NULL }; - AVCodecContext *codec = s1->streams[0]->codec; - - if (!s->is_pipe) { - /* loop over input */ - if (s->loop && s->img_number > s->img_last) { - s->img_number = s->img_first; - } - if (s->img_number > s->img_last) - return AVERROR_EOF; - if (s->use_glob) { -#if HAVE_GLOB - filename = s->globstate.gl_pathv[s->img_number]; -#endif - } else { - if (av_get_frame_filename(filename_bytes, sizeof(filename_bytes), - s->path, - s->img_number) < 0 && s->img_number > 1) - return AVERROR(EIO); - } - for (i = 0; i < 3; i++) { - if (avio_open2(&f[i], filename, AVIO_FLAG_READ, - &s1->interrupt_callback, NULL) < 0) { - if (i >= 1) - break; - av_log(s1, AV_LOG_ERROR, "Could not open file : %s\n", - filename); - return AVERROR(EIO); - } - size[i] = avio_size(f[i]); - - if (!s->split_planes) - break; - filename[strlen(filename) - 1] = 'U' + i; - } - - if (codec->codec_id == AV_CODEC_ID_RAWVIDEO && !codec->width) - infer_size(&codec->width, &codec->height, size[0]); - } else { - f[0] = s1->pb; - if (url_feof(f[0])) - return AVERROR(EIO); - if (s->frame_size > 0) { - size[0] = s->frame_size; - } else { - size[0] = 4096; - } - } - - if (av_new_packet(pkt, size[0] + size[1] + size[2]) < 0) - return AVERROR(ENOMEM); - pkt->stream_index = 0; - pkt->flags |= AV_PKT_FLAG_KEY; - if (!s->is_pipe) - pkt->pts = s->pts; - - pkt->size = 0; - for (i = 0; i < 3; i++) { - if (f[i]) { - ret[i] = avio_read(f[i], pkt->data + pkt->size, size[i]); - if (!s->is_pipe) - avio_close(f[i]); - if (ret[i] > 0) - pkt->size += ret[i]; - } - } - - if (ret[0] <= 0 || ret[1] < 0 || ret[2] < 0) { - av_free_packet(pkt); - return AVERROR(EIO); /* signal EOF */ - } else { - s->img_count++; - s->img_number++; - s->pts++; - return 0; - } -} - -static int img_read_close(struct AVFormatContext* s1) -{ - VideoDemuxData *s = s1->priv_data; -#if HAVE_GLOB - if (s->use_glob) { - globfree(&s->globstate); - } -#endif - return 0; -} - -static int img_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) -{ - VideoDemuxData *s1 = s->priv_data; - - if (timestamp < 0 || !s1->loop && timestamp > s1->img_last - s1->img_first) - return -1; - s1->img_number = timestamp%(s1->img_last - s1->img_first + 1) + s1->img_first; - s1->pts = timestamp; - return 0; -} - -#define OFFSET(x) offsetof(VideoDemuxData, x) -#define DEC AV_OPT_FLAG_DECODING_PARAM -static const AVOption options[] = { - { "framerate", "set the video framerate", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = "25"}, 0, 0, DEC }, - { "loop", "force loop over input file sequence", OFFSET(loop), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 1, DEC }, - - { "pattern_type", "set pattern type", OFFSET(pattern_type), AV_OPT_TYPE_INT, {.i64=PT_GLOB_SEQUENCE}, 0, INT_MAX, DEC, "pattern_type"}, - { "glob_sequence","select glob/sequence pattern type", 0, AV_OPT_TYPE_CONST, {.i64=PT_GLOB_SEQUENCE}, INT_MIN, INT_MAX, DEC, "pattern_type" }, - { "glob", "select glob pattern type", 0, AV_OPT_TYPE_CONST, {.i64=PT_GLOB }, INT_MIN, INT_MAX, DEC, "pattern_type" }, - { "sequence", "select sequence pattern type", 0, AV_OPT_TYPE_CONST, {.i64=PT_SEQUENCE }, INT_MIN, INT_MAX, DEC, "pattern_type" }, - - { "pixel_format", "set video pixel format", OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC }, - { "start_number", "set first number in the sequence", OFFSET(start_number), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, DEC }, - { "start_number_range", "set range for looking at the first sequence number", OFFSET(start_number_range), AV_OPT_TYPE_INT, {.i64 = 5}, 1, INT_MAX, DEC }, - { "video_size", "set video size", OFFSET(video_size), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC }, - { "frame_size", "force frame size in bytes", OFFSET(frame_size), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, INT_MAX, DEC }, - { NULL }, -}; - -#if CONFIG_IMAGE2_DEMUXER -static const AVClass img2_class = { - .class_name = "image2 demuxer", - .item_name = av_default_item_name, - .option = options, - .version = LIBAVUTIL_VERSION_INT, -}; -AVInputFormat ff_image2_demuxer = { - .name = "image2", - .long_name = NULL_IF_CONFIG_SMALL("image2 sequence"), - .priv_data_size = sizeof(VideoDemuxData), - .read_probe = img_read_probe, - .read_header = img_read_header, - .read_packet = img_read_packet, - .read_close = img_read_close, - .read_seek = img_read_seek, - .flags = AVFMT_NOFILE, - .priv_class = &img2_class, -}; -#endif -#if CONFIG_IMAGE2PIPE_DEMUXER -static const AVClass img2pipe_class = { - .class_name = "image2pipe demuxer", - .item_name = av_default_item_name, - .option = options, - .version = LIBAVUTIL_VERSION_INT, -}; -AVInputFormat ff_image2pipe_demuxer = { - .name = "image2pipe", - .long_name = NULL_IF_CONFIG_SMALL("piped image2 sequence"), - .priv_data_size = sizeof(VideoDemuxData), - .read_header = img_read_header, - .read_packet = img_read_packet, - .priv_class = &img2pipe_class, -}; -#endif diff --git a/ffmpeg1/libavformat/img2enc.c b/ffmpeg1/libavformat/img2enc.c deleted file mode 100644 index 67b5819..0000000 --- a/ffmpeg1/libavformat/img2enc.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Image format - * Copyright (c) 2000, 2001, 2002 Fabrice Bellard - * Copyright (c) 2004 Michael Niedermayer - * - * 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 "libavutil/intreadwrite.h" -#include "libavutil/avstring.h" -#include "libavutil/log.h" -#include "libavutil/opt.h" -#include "libavutil/pixdesc.h" -#include "avformat.h" -#include "avio_internal.h" -#include "internal.h" -#include "libavutil/opt.h" - -typedef struct { - const AVClass *class; /**< Class for private options. */ - int img_number; - int is_pipe; - int split_planes; /**< use independent file for each Y, U, V plane */ - char path[1024]; - int updatefirst; -} VideoMuxData; - -static int write_header(AVFormatContext *s) -{ - VideoMuxData *img = s->priv_data; - AVStream *st = s->streams[0]; - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(st->codec->pix_fmt); - const char *str; - - av_strlcpy(img->path, s->filename, sizeof(img->path)); - - /* find format */ - if (s->oformat->flags & AVFMT_NOFILE) - img->is_pipe = 0; - else - img->is_pipe = 1; - - str = strrchr(img->path, '.'); - img->split_planes = str - && !av_strcasecmp(str + 1, "y") - && s->nb_streams == 1 - && st->codec->codec_id == AV_CODEC_ID_RAWVIDEO - && desc - &&(desc->flags & PIX_FMT_PLANAR) - && desc->nb_components >= 3; - return 0; -} - -static int write_packet(AVFormatContext *s, AVPacket *pkt) -{ - VideoMuxData *img = s->priv_data; - AVIOContext *pb[4]; - char filename[1024]; - AVCodecContext *codec = s->streams[pkt->stream_index]->codec; - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(codec->pix_fmt); - int i; - - if (!img->is_pipe) { - if (av_get_frame_filename(filename, sizeof(filename), - img->path, img->img_number) < 0 && img->img_number > 1 && !img->updatefirst) { - av_log(s, AV_LOG_ERROR, - "Could not get frame filename number %d from pattern '%s' (either set updatefirst or use a pattern like %%03d within the filename pattern)\n", - img->img_number, img->path); - return AVERROR(EINVAL); - } - for (i = 0; i < 4; i++) { - if (avio_open2(&pb[i], filename, AVIO_FLAG_WRITE, - &s->interrupt_callback, NULL) < 0) { - av_log(s, AV_LOG_ERROR, "Could not open file : %s\n", filename); - return AVERROR(EIO); - } - - if (!img->split_planes || i+1 >= desc->nb_components) - break; - filename[strlen(filename) - 1] = ((int[]){'U','V','A','x'})[i]; - } - } else { - pb[0] = s->pb; - } - - if (img->split_planes) { - int ysize = codec->width * codec->height; - int usize = ((-codec->width)>>desc->log2_chroma_w) * ((-codec->height)>>desc->log2_chroma_h); - if (desc->comp[0].depth_minus1 >= 8) { - ysize *= 2; - usize *= 2; - } - avio_write(pb[0], pkt->data , ysize); - avio_write(pb[1], pkt->data + ysize , usize); - avio_write(pb[2], pkt->data + ysize + usize, usize); - avio_close(pb[1]); - avio_close(pb[2]); - if (desc->nb_components > 3) { - avio_write(pb[3], pkt->data + ysize + 2*usize, ysize); - avio_close(pb[3]); - } - } else { - avio_write(pb[0], pkt->data, pkt->size); - } - avio_flush(pb[0]); - if (!img->is_pipe) { - avio_close(pb[0]); - } - - img->img_number++; - return 0; -} - -#define OFFSET(x) offsetof(VideoMuxData, x) -#define ENC AV_OPT_FLAG_ENCODING_PARAM -static const AVOption muxoptions[] = { - { "updatefirst", "update the first image file", OFFSET(updatefirst), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, ENC }, - { "start_number", "set first number in the sequence", OFFSET(img_number), AV_OPT_TYPE_INT, { .i64 = 1 }, 1, INT_MAX, ENC }, - { NULL }, -}; - -#if CONFIG_IMAGE2_MUXER -static const AVClass img2mux_class = { - .class_name = "image2 muxer", - .item_name = av_default_item_name, - .option = muxoptions, - .version = LIBAVUTIL_VERSION_INT, -}; - -AVOutputFormat ff_image2_muxer = { - .name = "image2", - .long_name = NULL_IF_CONFIG_SMALL("image2 sequence"), - .extensions = "bmp,dpx,jls,jpeg,jpg,ljpg,pam,pbm,pcx,pgm,pgmyuv,png," - "ppm,sgi,tga,tif,tiff,jp2,j2c,xwd,sun,ras,rs,im1,im8,im24," - "sunras,xbm,xface", - .priv_data_size = sizeof(VideoMuxData), - .video_codec = AV_CODEC_ID_MJPEG, - .write_header = write_header, - .write_packet = write_packet, - .flags = AVFMT_NOTIMESTAMPS | AVFMT_NODIMENSIONS | AVFMT_NOFILE, - .priv_class = &img2mux_class, -}; -#endif -#if CONFIG_IMAGE2PIPE_MUXER -AVOutputFormat ff_image2pipe_muxer = { - .name = "image2pipe", - .long_name = NULL_IF_CONFIG_SMALL("piped image2 sequence"), - .priv_data_size = sizeof(VideoMuxData), - .video_codec = AV_CODEC_ID_MJPEG, - .write_header = write_header, - .write_packet = write_packet, - .flags = AVFMT_NOTIMESTAMPS | AVFMT_NODIMENSIONS -}; -#endif diff --git a/ffmpeg1/libavformat/ingenientdec.c b/ffmpeg1/libavformat/ingenientdec.c deleted file mode 100644 index 94c549c..0000000 --- a/ffmpeg1/libavformat/ingenientdec.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * RAW Ingenient MJPEG demuxer - * Copyright (c) 2005 Alex Beregszaszi - * - * 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 "rawdec.h" - -// http://www.artificis.hu/files/texts/ingenient.txt -static int ingenient_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - int ret, size, w, h, unk1, unk2; - - if (avio_rl32(s->pb) != MKTAG('M', 'J', 'P', 'G')) - return AVERROR(EIO); // FIXME - - size = avio_rl32(s->pb); - - w = avio_rl16(s->pb); - h = avio_rl16(s->pb); - - avio_skip(s->pb, 8); // zero + size (padded?) - avio_skip(s->pb, 2); - unk1 = avio_rl16(s->pb); - unk2 = avio_rl16(s->pb); - avio_skip(s->pb, 22); // ASCII timestamp - - av_log(s, AV_LOG_DEBUG, "Ingenient packet: size=%d, width=%d, height=%d, unk1=%d unk2=%d\n", - size, w, h, unk1, unk2); - - ret = av_get_packet(s->pb, pkt, size); - if (ret < 0) - return ret; - pkt->stream_index = 0; - return ret; -} - -FF_RAWVIDEO_DEMUXER_CLASS(ingenient) - -AVInputFormat ff_ingenient_demuxer = { - .name = "ingenient", - .long_name = NULL_IF_CONFIG_SMALL("raw Ingenient MJPEG"), - .priv_data_size = sizeof(FFRawVideoDemuxerContext), - .read_header = ff_raw_video_read_header, - .read_packet = ingenient_read_packet, - .flags = AVFMT_GENERIC_INDEX, - .extensions = "cgi", // FIXME - .raw_codec_id = AV_CODEC_ID_MJPEG, - .priv_class = &ingenient_demuxer_class, -}; diff --git a/ffmpeg1/libavformat/internal.h b/ffmpeg1/libavformat/internal.h deleted file mode 100644 index 4d56388..0000000 --- a/ffmpeg1/libavformat/internal.h +++ /dev/null @@ -1,395 +0,0 @@ -/* - * 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 AVFORMAT_INTERNAL_H -#define AVFORMAT_INTERNAL_H - -#include -#include "avformat.h" - -#define MAX_URL_SIZE 4096 - -#ifdef DEBUG -# define hex_dump_debug(class, buf, size) av_hex_dump_log(class, AV_LOG_DEBUG, buf, size) -#else -# define hex_dump_debug(class, buf, size) -#endif - -typedef struct AVCodecTag { - enum AVCodecID id; - unsigned int tag; -} AVCodecTag; - -typedef struct CodecMime{ - char str[32]; - enum AVCodecID id; -} CodecMime; - -#ifdef __GNUC__ -#define dynarray_add(tab, nb_ptr, elem)\ -do {\ - __typeof__(tab) _tab = (tab);\ - __typeof__(elem) _elem = (elem);\ - (void)sizeof(**_tab == _elem); /* check that types are compatible */\ - av_dynarray_add(_tab, nb_ptr, _elem);\ -} while(0) -#else -#define dynarray_add(tab, nb_ptr, elem)\ -do {\ - av_dynarray_add((tab), nb_ptr, (elem));\ -} while(0) -#endif - -struct tm *ff_brktimegm(time_t secs, struct tm *tm); - -char *ff_data_to_hex(char *buf, const uint8_t *src, int size, int lowercase); - -/** - * Parse a string of hexadecimal strings. Any space between the hexadecimal - * digits is ignored. - * - * @param data if non-null, the parsed data is written to this pointer - * @param p the string to parse - * @return the number of bytes written (or to be written, if data is null) - */ -int ff_hex_to_data(uint8_t *data, const char *p); - -void ff_program_add_stream_index(AVFormatContext *ac, int progid, unsigned int idx); - -/** - * Add packet to AVFormatContext->packet_buffer list, determining its - * interleaved position using compare() function argument. - * @return 0, or < 0 on error - */ -int ff_interleave_add_packet(AVFormatContext *s, AVPacket *pkt, - int (*compare)(AVFormatContext *, AVPacket *, AVPacket *)); - -void ff_read_frame_flush(AVFormatContext *s); - -#define NTP_OFFSET 2208988800ULL -#define NTP_OFFSET_US (NTP_OFFSET * 1000000ULL) - -/** Get the current time since NTP epoch in microseconds. */ -uint64_t ff_ntp_time(void); - -/** - * Assemble a URL string from components. This is the reverse operation - * of av_url_split. - * - * Note, this requires networking to be initialized, so the caller must - * ensure ff_network_init has been called. - * - * @see av_url_split - * - * @param str the buffer to fill with the url - * @param size the size of the str buffer - * @param proto the protocol identifier, if null, the separator - * after the identifier is left out, too - * @param authorization an optional authorization string, may be null. - * An empty string is treated the same as a null string. - * @param hostname the host name string - * @param port the port number, left out from the string if negative - * @param fmt a generic format string for everything to add after the - * host/port, may be null - * @return the number of characters written to the destination buffer - */ -int ff_url_join(char *str, int size, const char *proto, - const char *authorization, const char *hostname, - int port, const char *fmt, ...) av_printf_format(7, 8); - -/** - * Append the media-specific SDP fragment for the media stream c - * to the buffer buff. - * - * Note, the buffer needs to be initialized, since it is appended to - * existing content. - * - * @param buff the buffer to append the SDP fragment to - * @param size the size of the buff buffer - * @param st the AVStream of the media to describe - * @param idx the global stream index - * @param dest_addr the destination address of the media stream, may be NULL - * @param dest_type the destination address type, may be NULL - * @param port the destination port of the media stream, 0 if unknown - * @param ttl the time to live of the stream, 0 if not multicast - * @param fmt the AVFormatContext, which might contain options modifying - * the generated SDP - */ -void ff_sdp_write_media(char *buff, int size, AVStream *st, int idx, - const char *dest_addr, const char *dest_type, - int port, int ttl, AVFormatContext *fmt); - -/** - * Write a packet to another muxer than the one the user originally - * intended. Useful when chaining muxers, where one muxer internally - * writes a received packet to another muxer. - * - * @param dst the muxer to write the packet to - * @param dst_stream the stream index within dst to write the packet to - * @param pkt the packet to be written - * @param src the muxer the packet originally was intended for - * @return the value av_write_frame returned - */ -int ff_write_chained(AVFormatContext *dst, int dst_stream, AVPacket *pkt, - AVFormatContext *src); - -/** - * Get the length in bytes which is needed to store val as v. - */ -int ff_get_v_length(uint64_t val); - -/** - * Put val using a variable number of bytes. - */ -void ff_put_v(AVIOContext *bc, uint64_t val); - -/** - * Read a whole line of text from AVIOContext. Stop reading after reaching - * either a \\n, a \\0 or EOF. The returned string is always \\0-terminated, - * and may be truncated if the buffer is too small. - * - * @param s the read-only AVIOContext - * @param buf buffer to store the read line - * @param maxlen size of the buffer - * @return the length of the string written in the buffer, not including the - * final \\0 - */ -int ff_get_line(AVIOContext *s, char *buf, int maxlen); - -#define SPACE_CHARS " \t\r\n" - -/** - * Callback function type for ff_parse_key_value. - * - * @param key a pointer to the key - * @param key_len the number of bytes that belong to the key, including the '=' - * char - * @param dest return the destination pointer for the value in *dest, may - * be null to ignore the value - * @param dest_len the length of the *dest buffer - */ -typedef void (*ff_parse_key_val_cb)(void *context, const char *key, - int key_len, char **dest, int *dest_len); -/** - * Parse a string with comma-separated key=value pairs. The value strings - * may be quoted and may contain escaped characters within quoted strings. - * - * @param str the string to parse - * @param callback_get_buf function that returns where to store the - * unescaped value string. - * @param context the opaque context pointer to pass to callback_get_buf - */ -void ff_parse_key_value(const char *str, ff_parse_key_val_cb callback_get_buf, - void *context); - -/** - * Find stream index based on format-specific stream ID - * @return stream index, or < 0 on error - */ -int ff_find_stream_index(AVFormatContext *s, int id); - -/** - * Internal version of av_index_search_timestamp - */ -int ff_index_search_timestamp(const AVIndexEntry *entries, int nb_entries, - int64_t wanted_timestamp, int flags); - -/** - * Internal version of av_add_index_entry - */ -int ff_add_index_entry(AVIndexEntry **index_entries, - int *nb_index_entries, - unsigned int *index_entries_allocated_size, - int64_t pos, int64_t timestamp, int size, int distance, int flags); - -/** - * Add a new chapter. - * - * @param s media file handle - * @param id unique ID for this chapter - * @param start chapter start time in time_base units - * @param end chapter end time in time_base units - * @param title chapter title - * - * @return AVChapter or NULL on error - */ -AVChapter *avpriv_new_chapter(AVFormatContext *s, int id, AVRational time_base, - int64_t start, int64_t end, const char *title); - -/** - * Ensure the index uses less memory than the maximum specified in - * AVFormatContext.max_index_size by discarding entries if it grows - * too large. - */ -void ff_reduce_index(AVFormatContext *s, int stream_index); - -/** - * Convert a relative url into an absolute url, given a base url. - * - * @param buf the buffer where output absolute url is written - * @param size the size of buf - * @param base the base url, may be equal to buf. - * @param rel the new url, which is interpreted relative to base - */ -void ff_make_absolute_url(char *buf, int size, const char *base, - const char *rel); - -enum AVCodecID ff_guess_image2_codec(const char *filename); - -/** - * Convert a date string in ISO8601 format to Unix timestamp. - */ -int64_t ff_iso8601_to_unix_time(const char *datestr); - -/** - * Perform a binary search using av_index_search_timestamp() and - * AVInputFormat.read_timestamp(). - * - * @param target_ts target timestamp in the time base of the given stream - * @param stream_index stream number - */ -int ff_seek_frame_binary(AVFormatContext *s, int stream_index, - int64_t target_ts, int flags); - -/** - * Update cur_dts of all streams based on the given timestamp and AVStream. - * - * Stream ref_st unchanged, others set cur_dts in their native time base. - * Only needed for timestamp wrapping or if (dts not set and pts!=dts). - * @param timestamp new dts expressed in time_base of param ref_st - * @param ref_st reference stream giving time_base of param timestamp - */ -void ff_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp); - -/** - * Perform a binary search using read_timestamp(). - * - * @param target_ts target timestamp in the time base of the given stream - * @param stream_index stream number - */ -int64_t ff_gen_search(AVFormatContext *s, int stream_index, - int64_t target_ts, int64_t pos_min, - int64_t pos_max, int64_t pos_limit, - int64_t ts_min, int64_t ts_max, - int flags, int64_t *ts_ret, - int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t )); - -/** - * Set the time base and wrapping info for a given stream. This will be used - * to interpret the stream's timestamps. If the new time base is invalid - * (numerator or denominator are non-positive), it leaves the stream - * unchanged. - * - * @param s stream - * @param pts_wrap_bits number of bits effectively used by the pts - * (used for wrap control) - * @param pts_num time base numerator - * @param pts_den time base denominator - */ -void avpriv_set_pts_info(AVStream *s, int pts_wrap_bits, - unsigned int pts_num, unsigned int pts_den); - -/** - * Add side data to a packet for changing parameters to the given values. - * Parameters set to 0 aren't included in the change. - */ -int ff_add_param_change(AVPacket *pkt, int32_t channels, - uint64_t channel_layout, int32_t sample_rate, - int32_t width, int32_t height); - -/** - * Set the timebase for each stream from the corresponding codec timebase and - * print it. - */ -int ff_framehash_write_header(AVFormatContext *s); - -/** - * Read a transport packet from a media file. - * - * @param s media file handle - * @param pkt is filled - * @return 0 if OK, AVERROR_xxx on error - */ -int ff_read_packet(AVFormatContext *s, AVPacket *pkt); - -/** - * Interleave a packet per dts in an output media file. - * - * Packets with pkt->destruct == av_destruct_packet will be freed inside this - * function, so they cannot be used after it. Note that calling av_free_packet() - * on them is still safe. - * - * @param s media file handle - * @param out the interleaved packet will be output here - * @param pkt the input packet - * @param flush 1 if no further packets are available as input and all - * remaining packets should be output - * @return 1 if a packet was output, 0 if no packet could be output, - * < 0 if an error occurred - */ -int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, - AVPacket *pkt, int flush); - -void ff_free_stream(AVFormatContext *s, AVStream *st); - -/** - * Return the frame duration in seconds. Return 0 if not available. - */ -void ff_compute_frame_duration(int *pnum, int *pden, AVStream *st, - AVCodecParserContext *pc, AVPacket *pkt); - -int ff_get_audio_frame_size(AVCodecContext *enc, int size, int mux); - -unsigned int ff_codec_get_tag(const AVCodecTag *tags, enum AVCodecID id); - -enum AVCodecID ff_codec_get_id(const AVCodecTag *tags, unsigned int tag); - -/** - * Select a PCM codec based on the given parameters. - * - * @param bps bits-per-sample - * @param flt floating-point - * @param be big-endian - * @param sflags signed flags. each bit corresponds to one byte of bit depth. - * e.g. the 1st bit indicates if 8-bit should be signed or - * unsigned, the 2nd bit indicates if 16-bit should be signed or - * unsigned, etc... This is useful for formats such as WAVE where - * only 8-bit is unsigned and all other bit depths are signed. - * @return a PCM codec id or AV_CODEC_ID_NONE - */ -enum AVCodecID ff_get_pcm_codec_id(int bps, int flt, int be, int sflags); - -/** - * Chooses a timebase for muxing the specified stream. - * - * The choosen timebase allows sample accurate timestamps based - * on the framerate or sample rate for audio streams. It also is - * at least as precisse as 1/min_precission would be. - */ -AVRational ff_choose_timebase(AVFormatContext *s, AVStream *st, int min_precission); - -/** - * Generate standard extradata for AVC-Intra based on width/height and field order. - */ -void ff_generate_avci_extradata(AVStream *st); - -int ff_http_match_no_proxy(const char *no_proxy, const char *hostname); - -#endif /* AVFORMAT_INTERNAL_H */ diff --git a/ffmpeg1/libavformat/ipmovie.c b/ffmpeg1/libavformat/ipmovie.c deleted file mode 100644 index 676363b..0000000 --- a/ffmpeg1/libavformat/ipmovie.c +++ /dev/null @@ -1,656 +0,0 @@ -/* - * Interplay MVE File Demuxer - * Copyright (c) 2003 The ffmpeg Project - * - * 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 - */ - -/** - * @file - * Interplay MVE file demuxer - * by Mike Melanson (melanson@pcisys.net) - * For more information regarding the Interplay MVE file format, visit: - * http://www.pcisys.net/~melanson/codecs/ - * The aforementioned site also contains a command line utility for parsing - * IP MVE files so that you can get a good idea of the typical structure of - * such files. This demuxer is not the best example to use if you are trying - * to write your own as it uses a rather roundabout approach for splitting - * up and sending out the chunks. - */ - -#include "libavutil/channel_layout.h" -#include "libavutil/intreadwrite.h" -#include "avformat.h" -#include "internal.h" - -#define CHUNK_PREAMBLE_SIZE 4 -#define OPCODE_PREAMBLE_SIZE 4 - -#define CHUNK_INIT_AUDIO 0x0000 -#define CHUNK_AUDIO_ONLY 0x0001 -#define CHUNK_INIT_VIDEO 0x0002 -#define CHUNK_VIDEO 0x0003 -#define CHUNK_SHUTDOWN 0x0004 -#define CHUNK_END 0x0005 -/* these last types are used internally */ -#define CHUNK_DONE 0xFFFC -#define CHUNK_NOMEM 0xFFFD -#define CHUNK_EOF 0xFFFE -#define CHUNK_BAD 0xFFFF - -#define OPCODE_END_OF_STREAM 0x00 -#define OPCODE_END_OF_CHUNK 0x01 -#define OPCODE_CREATE_TIMER 0x02 -#define OPCODE_INIT_AUDIO_BUFFERS 0x03 -#define OPCODE_START_STOP_AUDIO 0x04 -#define OPCODE_INIT_VIDEO_BUFFERS 0x05 -#define OPCODE_UNKNOWN_06 0x06 -#define OPCODE_SEND_BUFFER 0x07 -#define OPCODE_AUDIO_FRAME 0x08 -#define OPCODE_SILENCE_FRAME 0x09 -#define OPCODE_INIT_VIDEO_MODE 0x0A -#define OPCODE_CREATE_GRADIENT 0x0B -#define OPCODE_SET_PALETTE 0x0C -#define OPCODE_SET_PALETTE_COMPRESSED 0x0D -#define OPCODE_UNKNOWN_0E 0x0E -#define OPCODE_SET_DECODING_MAP 0x0F -#define OPCODE_UNKNOWN_10 0x10 -#define OPCODE_VIDEO_DATA 0x11 -#define OPCODE_UNKNOWN_12 0x12 -#define OPCODE_UNKNOWN_13 0x13 -#define OPCODE_UNKNOWN_14 0x14 -#define OPCODE_UNKNOWN_15 0x15 - -#define PALETTE_COUNT 256 - -typedef struct IPMVEContext { - - unsigned char *buf; - int buf_size; - - uint64_t frame_pts_inc; - - unsigned int video_bpp; - unsigned int video_width; - unsigned int video_height; - int64_t video_pts; - uint32_t palette[256]; - int has_palette; - int changed; - - unsigned int audio_bits; - unsigned int audio_channels; - unsigned int audio_sample_rate; - enum AVCodecID audio_type; - unsigned int audio_frame_count; - - int video_stream_index; - int audio_stream_index; - - int64_t audio_chunk_offset; - int audio_chunk_size; - int64_t video_chunk_offset; - int video_chunk_size; - int64_t decode_map_chunk_offset; - int decode_map_chunk_size; - - int64_t next_chunk_offset; - -} IPMVEContext; - -static int load_ipmovie_packet(IPMVEContext *s, AVIOContext *pb, - AVPacket *pkt) { - - int chunk_type; - - if (s->audio_chunk_offset && s->audio_channels && s->audio_bits) { - if (s->audio_type == AV_CODEC_ID_NONE) { - av_log(NULL, AV_LOG_ERROR, "Can not read audio packet before" - "audio codec is known\n"); - return CHUNK_BAD; - } - - /* adjust for PCM audio by skipping chunk header */ - if (s->audio_type != AV_CODEC_ID_INTERPLAY_DPCM) { - s->audio_chunk_offset += 6; - s->audio_chunk_size -= 6; - } - - avio_seek(pb, s->audio_chunk_offset, SEEK_SET); - s->audio_chunk_offset = 0; - - if (s->audio_chunk_size != av_get_packet(pb, pkt, s->audio_chunk_size)) - return CHUNK_EOF; - - pkt->stream_index = s->audio_stream_index; - pkt->pts = s->audio_frame_count; - - /* audio frame maintenance */ - if (s->audio_type != AV_CODEC_ID_INTERPLAY_DPCM) - s->audio_frame_count += - (s->audio_chunk_size / s->audio_channels / (s->audio_bits / 8)); - else - s->audio_frame_count += - (s->audio_chunk_size - 6 - s->audio_channels) / s->audio_channels; - - av_dlog(NULL, "sending audio frame with pts %"PRId64" (%d audio frames)\n", - pkt->pts, s->audio_frame_count); - - chunk_type = CHUNK_VIDEO; - - } else if (s->decode_map_chunk_offset) { - - /* send both the decode map and the video data together */ - - if (av_new_packet(pkt, s->decode_map_chunk_size + s->video_chunk_size)) - return CHUNK_NOMEM; - - if (s->has_palette) { - uint8_t *pal; - - pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, - AVPALETTE_SIZE); - if (pal) { - memcpy(pal, s->palette, AVPALETTE_SIZE); - s->has_palette = 0; - } - } - - if (s->changed) { - ff_add_param_change(pkt, 0, 0, 0, s->video_width, s->video_height); - s->changed = 0; - } - pkt->pos= s->decode_map_chunk_offset; - avio_seek(pb, s->decode_map_chunk_offset, SEEK_SET); - s->decode_map_chunk_offset = 0; - - if (avio_read(pb, pkt->data, s->decode_map_chunk_size) != - s->decode_map_chunk_size) { - av_free_packet(pkt); - return CHUNK_EOF; - } - - avio_seek(pb, s->video_chunk_offset, SEEK_SET); - s->video_chunk_offset = 0; - - if (avio_read(pb, pkt->data + s->decode_map_chunk_size, - s->video_chunk_size) != s->video_chunk_size) { - av_free_packet(pkt); - return CHUNK_EOF; - } - - pkt->stream_index = s->video_stream_index; - pkt->pts = s->video_pts; - - av_dlog(NULL, "sending video frame with pts %"PRId64"\n", pkt->pts); - - s->video_pts += s->frame_pts_inc; - - chunk_type = CHUNK_VIDEO; - - } else { - - avio_seek(pb, s->next_chunk_offset, SEEK_SET); - chunk_type = CHUNK_DONE; - - } - - return chunk_type; -} - -/* This function loads and processes a single chunk in an IP movie file. - * It returns the type of chunk that was processed. */ -static int process_ipmovie_chunk(IPMVEContext *s, AVIOContext *pb, - AVPacket *pkt) -{ - unsigned char chunk_preamble[CHUNK_PREAMBLE_SIZE]; - int chunk_type; - int chunk_size; - unsigned char opcode_preamble[OPCODE_PREAMBLE_SIZE]; - unsigned char opcode_type; - unsigned char opcode_version; - int opcode_size; - unsigned char scratch[1024]; - int i, j; - int first_color, last_color; - int audio_flags; - unsigned char r, g, b; - unsigned int width, height; - - /* see if there are any pending packets */ - chunk_type = load_ipmovie_packet(s, pb, pkt); - if (chunk_type != CHUNK_DONE) - return chunk_type; - - /* read the next chunk, wherever the file happens to be pointing */ - if (url_feof(pb)) - return CHUNK_EOF; - if (avio_read(pb, chunk_preamble, CHUNK_PREAMBLE_SIZE) != - CHUNK_PREAMBLE_SIZE) - return CHUNK_BAD; - chunk_size = AV_RL16(&chunk_preamble[0]); - chunk_type = AV_RL16(&chunk_preamble[2]); - - av_dlog(NULL, "chunk type 0x%04X, 0x%04X bytes: ", chunk_type, chunk_size); - - switch (chunk_type) { - - case CHUNK_INIT_AUDIO: - av_dlog(NULL, "initialize audio\n"); - break; - - case CHUNK_AUDIO_ONLY: - av_dlog(NULL, "audio only\n"); - break; - - case CHUNK_INIT_VIDEO: - av_dlog(NULL, "initialize video\n"); - break; - - case CHUNK_VIDEO: - av_dlog(NULL, "video (and audio)\n"); - break; - - case CHUNK_SHUTDOWN: - av_dlog(NULL, "shutdown\n"); - break; - - case CHUNK_END: - av_dlog(NULL, "end\n"); - break; - - default: - av_dlog(NULL, "invalid chunk\n"); - chunk_type = CHUNK_BAD; - break; - - } - - while ((chunk_size > 0) && (chunk_type != CHUNK_BAD)) { - - /* read the next chunk, wherever the file happens to be pointing */ - if (url_feof(pb)) { - chunk_type = CHUNK_EOF; - break; - } - if (avio_read(pb, opcode_preamble, CHUNK_PREAMBLE_SIZE) != - CHUNK_PREAMBLE_SIZE) { - chunk_type = CHUNK_BAD; - break; - } - - opcode_size = AV_RL16(&opcode_preamble[0]); - opcode_type = opcode_preamble[2]; - opcode_version = opcode_preamble[3]; - - chunk_size -= OPCODE_PREAMBLE_SIZE; - chunk_size -= opcode_size; - if (chunk_size < 0) { - av_dlog(NULL, "chunk_size countdown just went negative\n"); - chunk_type = CHUNK_BAD; - break; - } - - av_dlog(NULL, " opcode type %02X, version %d, 0x%04X bytes: ", - opcode_type, opcode_version, opcode_size); - switch (opcode_type) { - - case OPCODE_END_OF_STREAM: - av_dlog(NULL, "end of stream\n"); - avio_skip(pb, opcode_size); - break; - - case OPCODE_END_OF_CHUNK: - av_dlog(NULL, "end of chunk\n"); - avio_skip(pb, opcode_size); - break; - - case OPCODE_CREATE_TIMER: - av_dlog(NULL, "create timer\n"); - if ((opcode_version > 0) || (opcode_size > 6)) { - av_dlog(NULL, "bad create_timer opcode\n"); - chunk_type = CHUNK_BAD; - break; - } - if (avio_read(pb, scratch, opcode_size) != - opcode_size) { - chunk_type = CHUNK_BAD; - break; - } - s->frame_pts_inc = ((uint64_t)AV_RL32(&scratch[0])) * AV_RL16(&scratch[4]); - av_dlog(NULL, " %.2f frames/second (timer div = %d, subdiv = %d)\n", - 1000000.0 / s->frame_pts_inc, AV_RL32(&scratch[0]), - AV_RL16(&scratch[4])); - break; - - case OPCODE_INIT_AUDIO_BUFFERS: - av_dlog(NULL, "initialize audio buffers\n"); - if ((opcode_version > 1) || (opcode_size > 10)) { - av_dlog(NULL, "bad init_audio_buffers opcode\n"); - chunk_type = CHUNK_BAD; - break; - } - if (avio_read(pb, scratch, opcode_size) != - opcode_size) { - chunk_type = CHUNK_BAD; - break; - } - s->audio_sample_rate = AV_RL16(&scratch[4]); - audio_flags = AV_RL16(&scratch[2]); - /* bit 0 of the flags: 0 = mono, 1 = stereo */ - s->audio_channels = (audio_flags & 1) + 1; - /* bit 1 of the flags: 0 = 8 bit, 1 = 16 bit */ - s->audio_bits = (((audio_flags >> 1) & 1) + 1) * 8; - /* bit 2 indicates compressed audio in version 1 opcode */ - if ((opcode_version == 1) && (audio_flags & 0x4)) - s->audio_type = AV_CODEC_ID_INTERPLAY_DPCM; - else if (s->audio_bits == 16) - s->audio_type = AV_CODEC_ID_PCM_S16LE; - else - s->audio_type = AV_CODEC_ID_PCM_U8; - av_dlog(NULL, "audio: %d bits, %d Hz, %s, %s format\n", - s->audio_bits, s->audio_sample_rate, - (s->audio_channels == 2) ? "stereo" : "mono", - (s->audio_type == AV_CODEC_ID_INTERPLAY_DPCM) ? - "Interplay audio" : "PCM"); - break; - - case OPCODE_START_STOP_AUDIO: - av_dlog(NULL, "start/stop audio\n"); - avio_skip(pb, opcode_size); - break; - - case OPCODE_INIT_VIDEO_BUFFERS: - av_dlog(NULL, "initialize video buffers\n"); - if ((opcode_version > 2) || (opcode_size > 8)) { - av_dlog(NULL, "bad init_video_buffers opcode\n"); - chunk_type = CHUNK_BAD; - break; - } - if (avio_read(pb, scratch, opcode_size) != - opcode_size) { - chunk_type = CHUNK_BAD; - break; - } - width = AV_RL16(&scratch[0]) * 8; - height = AV_RL16(&scratch[2]) * 8; - if (width != s->video_width) { - s->video_width = width; - s->changed++; - } - if (height != s->video_height) { - s->video_height = height; - s->changed++; - } - if (opcode_version < 2 || !AV_RL16(&scratch[6])) { - s->video_bpp = 8; - } else { - s->video_bpp = 16; - } - av_dlog(NULL, "video resolution: %d x %d\n", - s->video_width, s->video_height); - break; - - case OPCODE_UNKNOWN_06: - case OPCODE_UNKNOWN_0E: - case OPCODE_UNKNOWN_10: - case OPCODE_UNKNOWN_12: - case OPCODE_UNKNOWN_13: - case OPCODE_UNKNOWN_14: - case OPCODE_UNKNOWN_15: - av_dlog(NULL, "unknown (but documented) opcode %02X\n", opcode_type); - avio_skip(pb, opcode_size); - break; - - case OPCODE_SEND_BUFFER: - av_dlog(NULL, "send buffer\n"); - avio_skip(pb, opcode_size); - break; - - case OPCODE_AUDIO_FRAME: - av_dlog(NULL, "audio frame\n"); - - /* log position and move on for now */ - s->audio_chunk_offset = avio_tell(pb); - s->audio_chunk_size = opcode_size; - avio_skip(pb, opcode_size); - break; - - case OPCODE_SILENCE_FRAME: - av_dlog(NULL, "silence frame\n"); - avio_skip(pb, opcode_size); - break; - - case OPCODE_INIT_VIDEO_MODE: - av_dlog(NULL, "initialize video mode\n"); - avio_skip(pb, opcode_size); - break; - - case OPCODE_CREATE_GRADIENT: - av_dlog(NULL, "create gradient\n"); - avio_skip(pb, opcode_size); - break; - - case OPCODE_SET_PALETTE: - av_dlog(NULL, "set palette\n"); - /* check for the logical maximum palette size - * (3 * 256 + 4 bytes) */ - if (opcode_size > 0x304) { - av_dlog(NULL, "demux_ipmovie: set_palette opcode too large\n"); - chunk_type = CHUNK_BAD; - break; - } - if (avio_read(pb, scratch, opcode_size) != opcode_size) { - chunk_type = CHUNK_BAD; - break; - } - - /* load the palette into internal data structure */ - first_color = AV_RL16(&scratch[0]); - last_color = first_color + AV_RL16(&scratch[2]) - 1; - /* sanity check (since they are 16 bit values) */ - if ((first_color > 0xFF) || (last_color > 0xFF)) { - av_dlog(NULL, "demux_ipmovie: set_palette indexes out of range (%d -> %d)\n", - first_color, last_color); - chunk_type = CHUNK_BAD; - break; - } - j = 4; /* offset of first palette data */ - for (i = first_color; i <= last_color; i++) { - /* the palette is stored as a 6-bit VGA palette, thus each - * component is shifted up to a 8-bit range */ - r = scratch[j++] * 4; - g = scratch[j++] * 4; - b = scratch[j++] * 4; - s->palette[i] = (0xFFU << 24) | (r << 16) | (g << 8) | (b); - s->palette[i] |= s->palette[i] >> 6 & 0x30303; - } - s->has_palette = 1; - break; - - case OPCODE_SET_PALETTE_COMPRESSED: - av_dlog(NULL, "set palette compressed\n"); - avio_skip(pb, opcode_size); - break; - - case OPCODE_SET_DECODING_MAP: - av_dlog(NULL, "set decoding map\n"); - - /* log position and move on for now */ - s->decode_map_chunk_offset = avio_tell(pb); - s->decode_map_chunk_size = opcode_size; - avio_skip(pb, opcode_size); - break; - - case OPCODE_VIDEO_DATA: - av_dlog(NULL, "set video data\n"); - - /* log position and move on for now */ - s->video_chunk_offset = avio_tell(pb); - s->video_chunk_size = opcode_size; - avio_skip(pb, opcode_size); - break; - - default: - av_dlog(NULL, "*** unknown opcode type\n"); - chunk_type = CHUNK_BAD; - break; - - } - } - - /* make a note of where the stream is sitting */ - s->next_chunk_offset = avio_tell(pb); - - /* dispatch the first of any pending packets */ - if ((chunk_type == CHUNK_VIDEO) || (chunk_type == CHUNK_AUDIO_ONLY)) - chunk_type = load_ipmovie_packet(s, pb, pkt); - - return chunk_type; -} - -static const char signature[] = "Interplay MVE File\x1A\0\x1A"; - -static int ipmovie_probe(AVProbeData *p) -{ - const uint8_t *b = p->buf; - const uint8_t *b_end = p->buf + p->buf_size - sizeof(signature); - do { - if (b[0] == signature[0] && memcmp(b, signature, sizeof(signature)) == 0) - return AVPROBE_SCORE_MAX; - b++; - } while (b < b_end); - - return 0; -} - -static int ipmovie_read_header(AVFormatContext *s) -{ - IPMVEContext *ipmovie = s->priv_data; - AVIOContext *pb = s->pb; - AVPacket pkt; - AVStream *st; - unsigned char chunk_preamble[CHUNK_PREAMBLE_SIZE]; - int chunk_type, i; - uint8_t signature_buffer[sizeof(signature)]; - - avio_read(pb, signature_buffer, sizeof(signature_buffer)); - while (memcmp(signature_buffer, signature, sizeof(signature))) { - memmove(signature_buffer, signature_buffer + 1, sizeof(signature_buffer) - 1); - signature_buffer[sizeof(signature_buffer) - 1] = avio_r8(pb); - if (url_feof(pb)) - return AVERROR_EOF; - } - /* initialize private context members */ - ipmovie->video_pts = ipmovie->audio_frame_count = 0; - ipmovie->audio_chunk_offset = ipmovie->video_chunk_offset = - ipmovie->decode_map_chunk_offset = 0; - - /* on the first read, this will position the stream at the first chunk */ - ipmovie->next_chunk_offset = avio_tell(pb) + 4; - - for (i = 0; i < 256; i++) - ipmovie->palette[i] = 0xFFU << 24; - - /* process the first chunk which should be CHUNK_INIT_VIDEO */ - if (process_ipmovie_chunk(ipmovie, pb, &pkt) != CHUNK_INIT_VIDEO) - return AVERROR_INVALIDDATA; - - /* peek ahead to the next chunk-- if it is an init audio chunk, process - * it; if it is the first video chunk, this is a silent file */ - if (avio_read(pb, chunk_preamble, CHUNK_PREAMBLE_SIZE) != - CHUNK_PREAMBLE_SIZE) - return AVERROR(EIO); - chunk_type = AV_RL16(&chunk_preamble[2]); - avio_seek(pb, -CHUNK_PREAMBLE_SIZE, SEEK_CUR); - - if (chunk_type == CHUNK_VIDEO) - ipmovie->audio_type = AV_CODEC_ID_NONE; /* no audio */ - else if (process_ipmovie_chunk(ipmovie, pb, &pkt) != CHUNK_INIT_AUDIO) - return AVERROR_INVALIDDATA; - - /* initialize the stream decoders */ - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - avpriv_set_pts_info(st, 63, 1, 1000000); - ipmovie->video_stream_index = st->index; - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = AV_CODEC_ID_INTERPLAY_VIDEO; - st->codec->codec_tag = 0; /* no fourcc */ - st->codec->width = ipmovie->video_width; - st->codec->height = ipmovie->video_height; - st->codec->bits_per_coded_sample = ipmovie->video_bpp; - - if (ipmovie->audio_type) { - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - avpriv_set_pts_info(st, 32, 1, ipmovie->audio_sample_rate); - ipmovie->audio_stream_index = st->index; - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = ipmovie->audio_type; - st->codec->codec_tag = 0; /* no tag */ - st->codec->channels = ipmovie->audio_channels; - st->codec->channel_layout = st->codec->channels == 1 ? AV_CH_LAYOUT_MONO : - AV_CH_LAYOUT_STEREO; - st->codec->sample_rate = ipmovie->audio_sample_rate; - st->codec->bits_per_coded_sample = ipmovie->audio_bits; - st->codec->bit_rate = st->codec->channels * st->codec->sample_rate * - st->codec->bits_per_coded_sample; - if (st->codec->codec_id == AV_CODEC_ID_INTERPLAY_DPCM) - st->codec->bit_rate /= 2; - st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample; - } - - return 0; -} - -static int ipmovie_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - IPMVEContext *ipmovie = s->priv_data; - AVIOContext *pb = s->pb; - int ret; - - for (;;) { - ret = process_ipmovie_chunk(ipmovie, pb, pkt); - if (ret == CHUNK_BAD) - ret = AVERROR_INVALIDDATA; - else if (ret == CHUNK_EOF) - ret = AVERROR(EIO); - else if (ret == CHUNK_NOMEM) - ret = AVERROR(ENOMEM); - else if (ret == CHUNK_VIDEO) - ret = 0; - else if (ret == CHUNK_INIT_VIDEO || ret == CHUNK_INIT_AUDIO) - continue; - else - ret = -1; - - return ret; - } -} - -AVInputFormat ff_ipmovie_demuxer = { - .name = "ipmovie", - .long_name = NULL_IF_CONFIG_SMALL("Interplay MVE"), - .priv_data_size = sizeof(IPMVEContext), - .read_probe = ipmovie_probe, - .read_header = ipmovie_read_header, - .read_packet = ipmovie_read_packet, -}; diff --git a/ffmpeg1/libavformat/ircam.c b/ffmpeg1/libavformat/ircam.c deleted file mode 100644 index a267c18..0000000 --- a/ffmpeg1/libavformat/ircam.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * IRCAM common code - * Copyright (c) 2012 Paul B Mahol - * - * 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 "internal.h" - -const AVCodecTag ff_codec_ircam_le_tags[] = { - { AV_CODEC_ID_PCM_ALAW, 0x10001 }, - { AV_CODEC_ID_PCM_F32LE, 0x00004 }, - { AV_CODEC_ID_PCM_F64LE, 0x00008 }, - { AV_CODEC_ID_PCM_MULAW, 0x20001 }, - { AV_CODEC_ID_PCM_S16LE, 0x00002 }, - { AV_CODEC_ID_PCM_S24LE, 0x00003 }, - { AV_CODEC_ID_PCM_S32LE, 0x40004 }, - { AV_CODEC_ID_PCM_S8, 0x00001 }, - { AV_CODEC_ID_NONE, 0 }, -}; - -const AVCodecTag ff_codec_ircam_be_tags[] = { - { AV_CODEC_ID_PCM_ALAW, 0x10001 }, - { AV_CODEC_ID_PCM_F32BE, 0x00004 }, - { AV_CODEC_ID_PCM_F64BE, 0x00008 }, - { AV_CODEC_ID_PCM_MULAW, 0x20001 }, - { AV_CODEC_ID_PCM_S16BE, 0x00002 }, - { AV_CODEC_ID_PCM_S24BE, 0x00003 }, - { AV_CODEC_ID_PCM_S32BE, 0x40004 }, - { AV_CODEC_ID_PCM_S8, 0x00001 }, - { AV_CODEC_ID_NONE, 0 }, -}; diff --git a/ffmpeg1/libavformat/ircam.h b/ffmpeg1/libavformat/ircam.h deleted file mode 100644 index f7f9c84..0000000 --- a/ffmpeg1/libavformat/ircam.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * IRCAM common code - * Copyright (c) 2012 Paul B Mahol - * - * 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 AVFORMAT_IRCAM_H -#define AVFORMAT_IRCAM_H - -#include "internal.h" - -extern const AVCodecTag ff_codec_ircam_be_tags[]; -extern const AVCodecTag ff_codec_ircam_le_tags[]; - -#endif /* AVFORMAT_IRCAM_H */ diff --git a/ffmpeg1/libavformat/ircamdec.c b/ffmpeg1/libavformat/ircamdec.c deleted file mode 100644 index f9533ec..0000000 --- a/ffmpeg1/libavformat/ircamdec.c +++ /dev/null @@ -1,115 +0,0 @@ -/* - * IRCAM demuxer - * Copyright (c) 2012 Paul B Mahol - * - * 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 "libavutil/intreadwrite.h" -#include "avformat.h" -#include "internal.h" -#include "pcm.h" -#include "ircam.h" - -static int ircam_probe(AVProbeData *p) -{ - if ((p->buf[0] == 0x64 && p->buf[1] == 0xA3 && p->buf[3] == 0x00 && - p->buf[2] >= 1 && p->buf[2] <= 4) || - (p->buf[3] == 0x64 && p->buf[2] == 0xA3 && p->buf[0] == 0x00 && - p->buf[1] >= 1 && p->buf[1] <= 3) && - AV_RN32(p->buf + 4) && AV_RN32(p->buf + 8)) - return AVPROBE_SCORE_MAX / 4 * 3; - return 0; -} - -static const struct endianess { - uint32_t magic; - int is_le; -} table[] = { - { 0x64A30100, 0 }, - { 0x64A30200, 1 }, - { 0x64A30300, 0 }, - { 0x64A30400, 1 }, - { 0x0001A364, 1 }, - { 0x0002A364, 0 }, - { 0x0003A364, 1 }, -}; - -static int ircam_read_header(AVFormatContext *s) -{ - uint32_t magic, sample_rate, channels, tag; - const AVCodecTag *tags; - int le = -1, i; - AVStream *st; - - magic = avio_rl32(s->pb); - for (i = 0; i < 7; i++) { - if (magic == table[i].magic) { - le = table[i].is_le; - break; - } - } - - if (le == 1) { - sample_rate = av_int2float(avio_rl32(s->pb)); - channels = avio_rl32(s->pb); - tag = avio_rl32(s->pb); - tags = ff_codec_ircam_le_tags; - } else if (le == 0) { - sample_rate = av_int2float(avio_rb32(s->pb)); - channels = avio_rb32(s->pb); - tag = avio_rb32(s->pb); - tags = ff_codec_ircam_be_tags; - } else { - return AVERROR_INVALIDDATA; - } - - if (!channels || !sample_rate) - return AVERROR_INVALIDDATA; - - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->channels = channels; - st->codec->sample_rate = sample_rate; - - st->codec->codec_id = ff_codec_get_id(tags, tag); - if (st->codec->codec_id == AV_CODEC_ID_NONE) { - av_log(s, AV_LOG_ERROR, "unknown tag %X\n", tag); - return AVERROR_INVALIDDATA; - } - - st->codec->bits_per_coded_sample = av_get_bits_per_sample(st->codec->codec_id); - st->codec->block_align = st->codec->bits_per_coded_sample * st->codec->channels / 8; - avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); - avio_skip(s->pb, 1008); - - return 0; -} - -AVInputFormat ff_ircam_demuxer = { - .name = "ircam", - .long_name = NULL_IF_CONFIG_SMALL("Berkeley/IRCAM/CARL Sound Format"), - .read_probe = ircam_probe, - .read_header = ircam_read_header, - .read_packet = ff_pcm_read_packet, - .read_seek = ff_pcm_read_seek, - .extensions = "sf,ircam", - .flags = AVFMT_GENERIC_INDEX, -}; diff --git a/ffmpeg1/libavformat/ircamenc.c b/ffmpeg1/libavformat/ircamenc.c deleted file mode 100644 index 38f15fb..0000000 --- a/ffmpeg1/libavformat/ircamenc.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * IRCAM muxer - * Copyright (c) 2012 Paul B Mahol - * - * 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 "libavutil/intreadwrite.h" -#include "avformat.h" -#include "avio_internal.h" -#include "internal.h" -#include "rawenc.h" -#include "ircam.h" - -static int ircam_write_header(AVFormatContext *s) -{ - AVCodecContext *codec = s->streams[0]->codec; - uint32_t tag; - - if (s->nb_streams != 1) { - av_log(s, AV_LOG_ERROR, "only one stream is supported\n"); - return AVERROR(EINVAL); - } - - tag = ff_codec_get_tag(ff_codec_ircam_le_tags, codec->codec_id); - if (!tag) { - av_log(s, AV_LOG_ERROR, "unsupported codec\n"); - return AVERROR(EINVAL); - } - - avio_wl32(s->pb, 0x0001A364); - avio_wl32(s->pb, av_float2int(codec->sample_rate)); - avio_wl32(s->pb, codec->channels); - avio_wl32(s->pb, tag); - ffio_fill(s->pb, 0, 1008); - return 0; -} - -AVOutputFormat ff_ircam_muxer = { - .name = "ircam", - .extensions = "sf,ircam", - .long_name = NULL_IF_CONFIG_SMALL("Berkeley/IRCAM/CARL Sound Format"), - .audio_codec = AV_CODEC_ID_PCM_S16LE, - .video_codec = AV_CODEC_ID_NONE, - .write_header = ircam_write_header, - .write_packet = ff_raw_write_packet, - .codec_tag = (const AVCodecTag *const []){ ff_codec_ircam_le_tags, 0 }, -}; diff --git a/ffmpeg1/libavformat/isom.c b/ffmpeg1/libavformat/isom.c deleted file mode 100644 index 3f419a8..0000000 --- a/ffmpeg1/libavformat/isom.c +++ /dev/null @@ -1,571 +0,0 @@ -/* - * ISO Media common code - * Copyright (c) 2001 Fabrice Bellard - * Copyright (c) 2002 Francois Revol - * Copyright (c) 2006 Baptiste Coudurier - * - * 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 - */ - -//#define DEBUG - -#include "avformat.h" -#include "internal.h" -#include "isom.h" -#include "libavcodec/mpeg4audio.h" -#include "libavcodec/mpegaudiodata.h" - -/* http://www.mp4ra.org */ -/* ordered by muxing preference */ -const AVCodecTag ff_mp4_obj_type[] = { - { AV_CODEC_ID_MOV_TEXT , 0x08 }, - { AV_CODEC_ID_MPEG4 , 0x20 }, - { AV_CODEC_ID_H264 , 0x21 }, - { AV_CODEC_ID_AAC , 0x40 }, - { AV_CODEC_ID_MP4ALS , 0x40 }, /* 14496-3 ALS */ - { AV_CODEC_ID_MPEG2VIDEO , 0x61 }, /* MPEG2 Main */ - { AV_CODEC_ID_MPEG2VIDEO , 0x60 }, /* MPEG2 Simple */ - { AV_CODEC_ID_MPEG2VIDEO , 0x62 }, /* MPEG2 SNR */ - { AV_CODEC_ID_MPEG2VIDEO , 0x63 }, /* MPEG2 Spatial */ - { AV_CODEC_ID_MPEG2VIDEO , 0x64 }, /* MPEG2 High */ - { AV_CODEC_ID_MPEG2VIDEO , 0x65 }, /* MPEG2 422 */ - { AV_CODEC_ID_AAC , 0x66 }, /* MPEG2 AAC Main */ - { AV_CODEC_ID_AAC , 0x67 }, /* MPEG2 AAC Low */ - { AV_CODEC_ID_AAC , 0x68 }, /* MPEG2 AAC SSR */ - { AV_CODEC_ID_MP3 , 0x69 }, /* 13818-3 */ - { AV_CODEC_ID_MP2 , 0x69 }, /* 11172-3 */ - { AV_CODEC_ID_MPEG1VIDEO , 0x6A }, /* 11172-2 */ - { AV_CODEC_ID_MP3 , 0x6B }, /* 11172-3 */ - { AV_CODEC_ID_MJPEG , 0x6C }, /* 10918-1 */ - { AV_CODEC_ID_PNG , 0x6D }, - { AV_CODEC_ID_JPEG2000 , 0x6E }, /* 15444-1 */ - { AV_CODEC_ID_VC1 , 0xA3 }, - { AV_CODEC_ID_DIRAC , 0xA4 }, - { AV_CODEC_ID_AC3 , 0xA5 }, - { AV_CODEC_ID_DTS , 0xA9 }, /* mp4ra.org */ - { AV_CODEC_ID_VORBIS , 0xDD }, /* non standard, gpac uses it */ - { AV_CODEC_ID_DVD_SUBTITLE, 0xE0 }, /* non standard, see unsupported-embedded-subs-2.mp4 */ - { AV_CODEC_ID_QCELP , 0xE1 }, - { AV_CODEC_ID_MPEG4SYSTEMS, 0x01 }, - { AV_CODEC_ID_MPEG4SYSTEMS, 0x02 }, - { AV_CODEC_ID_NONE , 0 }, -}; - -const AVCodecTag ff_codec_movvideo_tags[] = { -/* { AV_CODEC_ID_, MKTAG('I', 'V', '5', '0') }, *//* Indeo 5.0 */ - - { AV_CODEC_ID_RAWVIDEO, MKTAG('r', 'a', 'w', ' ') }, /* Uncompressed RGB */ - { AV_CODEC_ID_RAWVIDEO, MKTAG('y', 'u', 'v', '2') }, /* Uncompressed YUV422 */ - { AV_CODEC_ID_RAWVIDEO, MKTAG('2', 'v', 'u', 'y') }, /* UNCOMPRESSED 8BIT 4:2:2 */ - { AV_CODEC_ID_RAWVIDEO, MKTAG('y', 'u', 'v', 's') }, /* same as 2vuy but byte swapped */ - - { AV_CODEC_ID_RAWVIDEO, MKTAG('L', '5', '5', '5') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('L', '5', '6', '5') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('B', '5', '6', '5') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('2', '4', 'B', 'G') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 'A') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 'A') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('A', 'B', 'G', 'R') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('b', '1', '6', 'g') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('b', '4', '8', 'r') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('b', 'x', 'b', 'g') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('b', 'x', 'r', 'g') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('b', 'x', 'y', 'v') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('N', 'O', '1', '6') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('D', 'V', 'O', 'O') }, /* Digital Voodoo SD 8 Bit */ - { AV_CODEC_ID_RAWVIDEO, MKTAG('R', '4', '2', '0') }, /* Radius DV YUV PAL */ - { AV_CODEC_ID_RAWVIDEO, MKTAG('R', '4', '1', '1') }, /* Radius DV YUV NTSC */ - - { AV_CODEC_ID_R10K, MKTAG('R', '1', '0', 'k') }, /* UNCOMPRESSED 10BIT RGB */ - { AV_CODEC_ID_R10K, MKTAG('R', '1', '0', 'g') }, /* UNCOMPRESSED 10BIT RGB */ - { AV_CODEC_ID_R210, MKTAG('r', '2', '1', '0') }, /* UNCOMPRESSED 10BIT RGB */ - { AV_CODEC_ID_AVUI, MKTAG('A', 'V', 'U', 'I') }, /* AVID Uncompressed deinterleaved UYVY422 */ - { AV_CODEC_ID_AVRP, MKTAG('A', 'V', 'r', 'p') }, /* Avid 1:1 10-bit RGB Packer */ - { AV_CODEC_ID_AVRP, MKTAG('S', 'U', 'D', 'S') }, /* Avid DS Uncompressed */ - { AV_CODEC_ID_V210, MKTAG('v', '2', '1', '0') }, /* UNCOMPRESSED 10BIT 4:2:2 */ - { AV_CODEC_ID_V210, MKTAG('b', 'x', 'y', '2') }, /* BOXX 10BIT 4:2:2 */ - { AV_CODEC_ID_V308, MKTAG('v', '3', '0', '8') }, /* UNCOMPRESSED 8BIT 4:4:4 */ - { AV_CODEC_ID_V408, MKTAG('v', '4', '0', '8') }, /* UNCOMPRESSED 8BIT 4:4:4:4 */ - { AV_CODEC_ID_V410, MKTAG('v', '4', '1', '0') }, /* UNCOMPRESSED 10BIT 4:4:4 */ - { AV_CODEC_ID_Y41P, MKTAG('Y', '4', '1', 'P') }, /* UNCOMPRESSED 12BIT 4:1:1 */ - { AV_CODEC_ID_YUV4, MKTAG('y', 'u', 'v', '4') }, /* libquicktime packed yuv420p */ - { AV_CODEC_ID_TARGA_Y216, MKTAG('Y', '2', '1', '6') }, - - { AV_CODEC_ID_MJPEG, MKTAG('j', 'p', 'e', 'g') }, /* PhotoJPEG */ - { AV_CODEC_ID_MJPEG, MKTAG('m', 'j', 'p', 'a') }, /* Motion-JPEG (format A) */ - { AV_CODEC_ID_MJPEG, MKTAG('A', 'V', 'D', 'J') }, /* MJPEG with alpha-channel (AVID JFIF meridien compressed) */ -/* { AV_CODEC_ID_MJPEG, MKTAG('A', 'V', 'R', 'n') }, *//* MJPEG with alpha-channel (AVID ABVB/Truevision NuVista) */ - { AV_CODEC_ID_MJPEG, MKTAG('d', 'm', 'b', '1') }, /* Motion JPEG OpenDML */ - { AV_CODEC_ID_MJPEGB, MKTAG('m', 'j', 'p', 'b') }, /* Motion-JPEG (format B) */ - - { AV_CODEC_ID_SVQ1, MKTAG('S', 'V', 'Q', '1') }, /* Sorenson Video v1 */ - { AV_CODEC_ID_SVQ1, MKTAG('s', 'v', 'q', '1') }, /* Sorenson Video v1 */ - { AV_CODEC_ID_SVQ1, MKTAG('s', 'v', 'q', 'i') }, /* Sorenson Video v1 (from QT specs)*/ - { AV_CODEC_ID_SVQ3, MKTAG('S', 'V', 'Q', '3') }, /* Sorenson Video v3 */ - - { AV_CODEC_ID_MPEG4, MKTAG('m', 'p', '4', 'v') }, - { AV_CODEC_ID_MPEG4, MKTAG('D', 'I', 'V', 'X') }, /* OpenDiVX *//* sample files at http://heroinewarrior.com/xmovie.php3 use this tag */ - { AV_CODEC_ID_MPEG4, MKTAG('X', 'V', 'I', 'D') }, - { AV_CODEC_ID_MPEG4, MKTAG('3', 'I', 'V', '2') }, /* experimental: 3IVX files before ivx D4 4.5.1 */ - - { AV_CODEC_ID_H263, MKTAG('h', '2', '6', '3') }, /* H263 */ - { AV_CODEC_ID_H263, MKTAG('s', '2', '6', '3') }, /* H263 ?? works */ - - { AV_CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'c', 'p') }, /* DV PAL */ - { AV_CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'c', ' ') }, /* DV NTSC */ - { AV_CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'p', 'p') }, /* DVCPRO PAL produced by FCP */ - { AV_CODEC_ID_DVVIDEO, MKTAG('d', 'v', '5', 'p') }, /* DVCPRO50 PAL produced by FCP */ - { AV_CODEC_ID_DVVIDEO, MKTAG('d', 'v', '5', 'n') }, /* DVCPRO50 NTSC produced by FCP */ - { AV_CODEC_ID_DVVIDEO, MKTAG('A', 'V', 'd', 'v') }, /* AVID DV */ - { AV_CODEC_ID_DVVIDEO, MKTAG('A', 'V', 'd', '1') }, /* AVID DV100 */ - { AV_CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', 'q') }, /* DVCPRO HD 720p50 */ - { AV_CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', 'p') }, /* DVCPRO HD 720p60 */ - { AV_CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', '1') }, - { AV_CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', '2') }, - { AV_CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', '4') }, - { AV_CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', '5') }, /* DVCPRO HD 50i produced by FCP */ - { AV_CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', '6') }, /* DVCPRO HD 60i produced by FCP */ - { AV_CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', '3') }, /* DVCPRO HD 30p produced by FCP */ - - { AV_CODEC_ID_VP3, MKTAG('V', 'P', '3', '1') }, /* On2 VP3 */ - { AV_CODEC_ID_RPZA, MKTAG('r', 'p', 'z', 'a') }, /* Apple Video (RPZA) */ - { AV_CODEC_ID_CINEPAK, MKTAG('c', 'v', 'i', 'd') }, /* Cinepak */ - { AV_CODEC_ID_8BPS, MKTAG('8', 'B', 'P', 'S') }, /* Planar RGB (8BPS) */ - { AV_CODEC_ID_SMC, MKTAG('s', 'm', 'c', ' ') }, /* Apple Graphics (SMC) */ - { AV_CODEC_ID_QTRLE, MKTAG('r', 'l', 'e', ' ') }, /* Apple Animation (RLE) */ - { AV_CODEC_ID_SGIRLE, MKTAG('r', 'l', 'e', '1') }, /* SGI RLE 8-bit */ - { AV_CODEC_ID_MSRLE, MKTAG('W', 'R', 'L', 'E') }, - { AV_CODEC_ID_QDRAW, MKTAG('q', 'd', 'r', 'w') }, /* QuickDraw */ - - { AV_CODEC_ID_RAWVIDEO, MKTAG('W', 'R', 'A', 'W') }, - - { AV_CODEC_ID_H264, MKTAG('a', 'v', 'c', '1') }, /* AVC-1/H.264 */ - { AV_CODEC_ID_H264, MKTAG('a', 'i', '5', 'p') }, /* AVC-Intra 50M 720p24/30/60 */ - { AV_CODEC_ID_H264, MKTAG('a', 'i', '5', 'q') }, /* AVC-Intra 50M 720p25/50 */ - { AV_CODEC_ID_H264, MKTAG('a', 'i', '5', '2') }, /* AVC-Intra 50M 1080p25/50 */ - { AV_CODEC_ID_H264, MKTAG('a', 'i', '5', '3') }, /* AVC-Intra 50M 1080p24/30/60 */ - { AV_CODEC_ID_H264, MKTAG('a', 'i', '5', '5') }, /* AVC-Intra 50M 1080i50 */ - { AV_CODEC_ID_H264, MKTAG('a', 'i', '5', '6') }, /* AVC-Intra 50M 1080i60 */ - { AV_CODEC_ID_H264, MKTAG('a', 'i', '1', 'p') }, /* AVC-Intra 100M 720p24/30/60 */ - { AV_CODEC_ID_H264, MKTAG('a', 'i', '1', 'q') }, /* AVC-Intra 100M 720p25/50 */ - { AV_CODEC_ID_H264, MKTAG('a', 'i', '1', '2') }, /* AVC-Intra 100M 1080p25/50 */ - { AV_CODEC_ID_H264, MKTAG('a', 'i', '1', '3') }, /* AVC-Intra 100M 1080p24/30/60 */ - { AV_CODEC_ID_H264, MKTAG('a', 'i', '1', '5') }, /* AVC-Intra 100M 1080i50 */ - { AV_CODEC_ID_H264, MKTAG('a', 'i', '1', '6') }, /* AVC-Intra 100M 1080i60 */ - { AV_CODEC_ID_H264, MKTAG('A', 'V', 'i', 'n') }, /* AVC-Intra with implicit SPS/PPS */ - - { AV_CODEC_ID_MPEG1VIDEO, MKTAG('m', '1', 'v', '1') }, /* Apple MPEG-1 Camcorder */ - { AV_CODEC_ID_MPEG1VIDEO, MKTAG('m', 'p', 'e', 'g') }, /* MPEG */ - { AV_CODEC_ID_MPEG1VIDEO, MKTAG('m', '1', 'v', ' ') }, - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('m', '2', 'v', '1') }, /* Apple MPEG-2 Camcorder */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '1') }, /* MPEG2 HDV 720p30 */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '2') }, /* MPEG2 HDV 1080i60 */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '3') }, /* MPEG2 HDV 1080i50 */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '4') }, /* MPEG2 HDV 720p24 */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '5') }, /* MPEG2 HDV 720p25 */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '6') }, /* MPEG2 HDV 1080p24 */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '7') }, /* MPEG2 HDV 1080p25 */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '8') }, /* MPEG2 HDV 1080p30 */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '9') }, /* MPEG2 HDV 720p60 JVC */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', 'a') }, /* MPEG2 HDV 720p50 */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '5', 'n') }, /* MPEG2 IMX NTSC 525/60 50mb/s produced by FCP */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '5', 'p') }, /* MPEG2 IMX PAL 625/50 50mb/s produced by FCP */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '4', 'n') }, /* MPEG2 IMX NTSC 525/60 40mb/s produced by FCP */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '4', 'p') }, /* MPEG2 IMX PAL 625/50 40mb/s produced by FCP */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '3', 'n') }, /* MPEG2 IMX NTSC 525/60 30mb/s produced by FCP */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '3', 'p') }, /* MPEG2 IMX PAL 625/50 30mb/s produced by FCP */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', '4') }, /* XDCAM HD422 720p24 CBR */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', '5') }, /* XDCAM HD422 720p25 CBR */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', '9') }, /* XDCAM HD422 720p60 CBR */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', 'a') }, /* XDCAM HD422 720p50 CBR */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', 'b') }, /* XDCAM HD422 1080i60 CBR */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', 'c') }, /* XDCAM HD422 1080i50 CBR */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', 'd') }, /* XDCAM HD422 1080p24 CBR */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', 'e') }, /* XDCAM HD422 1080p25 CBR */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', '5', 'f') }, /* XDCAM HD422 1080p30 CBR */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '1') }, /* XDCAM EX 720p30 VBR */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '2') }, /* XDCAM HD 1080i60 */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '3') }, /* XDCAM HD 1080i50 VBR */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '4') }, /* XDCAM EX 720p24 VBR */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '5') }, /* XDCAM EX 720p25 VBR */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '6') }, /* XDCAM HD 1080p24 VBR */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '7') }, /* XDCAM HD 1080p25 VBR */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '8') }, /* XDCAM HD 1080p30 VBR */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', '9') }, /* XDCAM EX 720p60 VBR */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'a') }, /* XDCAM EX 720p50 VBR */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'b') }, /* XDCAM EX 1080i60 VBR */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'c') }, /* XDCAM EX 1080i50 VBR */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'd') }, /* XDCAM EX 1080p24 VBR */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'e') }, /* XDCAM EX 1080p25 VBR */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'f') }, /* XDCAM EX 1080p30 VBR */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'h', 'd') }, /* XDCAM HD 540p */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'h', '2') }, /* XDCAM HD422 540p */ - { AV_CODEC_ID_MPEG2VIDEO, MKTAG('A', 'V', 'm', 'p') }, /* AVID IMX PAL */ - - { AV_CODEC_ID_JPEG2000, MKTAG('m', 'j', 'p', '2') }, /* JPEG 2000 produced by FCP */ - - { AV_CODEC_ID_TARGA, MKTAG('t', 'g', 'a', ' ') }, /* Truevision Targa */ - { AV_CODEC_ID_TIFF, MKTAG('t', 'i', 'f', 'f') }, /* TIFF embedded in MOV */ - { AV_CODEC_ID_GIF, MKTAG('g', 'i', 'f', ' ') }, /* embedded gif files as frames (usually one "click to play movie" frame) */ - { AV_CODEC_ID_PNG, MKTAG('p', 'n', 'g', ' ') }, - { AV_CODEC_ID_PNG, MKTAG('M', 'N', 'G', ' ') }, - - { AV_CODEC_ID_VC1, MKTAG('v', 'c', '-', '1') }, /* SMPTE RP 2025 */ - { AV_CODEC_ID_CAVS, MKTAG('a', 'v', 's', '2') }, - - { AV_CODEC_ID_DIRAC, MKTAG('d', 'r', 'a', 'c') }, - { AV_CODEC_ID_DNXHD, MKTAG('A', 'V', 'd', 'n') }, /* AVID DNxHD */ - { AV_CODEC_ID_H263, MKTAG('H', '2', '6', '3') }, - { AV_CODEC_ID_MSMPEG4V3, MKTAG('3', 'I', 'V', 'D') }, /* 3ivx DivX Doctor */ - { AV_CODEC_ID_RAWVIDEO, MKTAG('A', 'V', '1', 'x') }, /* AVID 1:1x */ - { AV_CODEC_ID_RAWVIDEO, MKTAG('A', 'V', 'u', 'p') }, - { AV_CODEC_ID_SGI, MKTAG('s', 'g', 'i', ' ') }, /* SGI */ - { AV_CODEC_ID_DPX, MKTAG('d', 'p', 'x', ' ') }, /* DPX */ - { AV_CODEC_ID_EXR, MKTAG('e', 'x', 'r', ' ') }, /* OpenEXR */ - - { AV_CODEC_ID_PRORES, MKTAG('a', 'p', 'c', 'h') }, /* Apple ProRes 422 High Quality */ - { AV_CODEC_ID_PRORES, MKTAG('a', 'p', 'c', 'n') }, /* Apple ProRes 422 Standard Definition */ - { AV_CODEC_ID_PRORES, MKTAG('a', 'p', 'c', 's') }, /* Apple ProRes 422 LT */ - { AV_CODEC_ID_PRORES, MKTAG('a', 'p', 'c', 'o') }, /* Apple ProRes 422 Proxy */ - { AV_CODEC_ID_PRORES, MKTAG('a', 'p', '4', 'h') }, /* Apple ProRes 4444 */ - { AV_CODEC_ID_FLIC, MKTAG('f', 'l', 'i', 'c') }, - - { AV_CODEC_ID_NONE, 0 }, -}; - -const AVCodecTag ff_codec_movaudio_tags[] = { - { AV_CODEC_ID_AAC, MKTAG('m', 'p', '4', 'a') }, - { AV_CODEC_ID_AC3, MKTAG('a', 'c', '-', '3') }, /* ETSI TS 102 366 Annex F */ - { AV_CODEC_ID_AC3, MKTAG('s', 'a', 'c', '3') }, /* Nero Recode */ - { AV_CODEC_ID_ADPCM_IMA_QT, MKTAG('i', 'm', 'a', '4') }, - { AV_CODEC_ID_ALAC, MKTAG('a', 'l', 'a', 'c') }, - { AV_CODEC_ID_AMR_NB, MKTAG('s', 'a', 'm', 'r') }, /* AMR-NB 3gp */ - { AV_CODEC_ID_AMR_WB, MKTAG('s', 'a', 'w', 'b') }, /* AMR-WB 3gp */ - { AV_CODEC_ID_DTS, MKTAG('d', 't', 's', 'c') }, /* DTS formats prior to DTS-HD */ - { AV_CODEC_ID_DTS, MKTAG('d', 't', 's', 'h') }, /* DTS-HD audio formats */ - { AV_CODEC_ID_DTS, MKTAG('d', 't', 's', 'l') }, /* DTS-HD Lossless formats */ - { AV_CODEC_ID_DTS, MKTAG('D', 'T', 'S', ' ') }, /* non-standard */ - { AV_CODEC_ID_EAC3, MKTAG('e', 'c', '-', '3') }, /* ETSI TS 102 366 Annex F (only valid in ISOBMFF) */ - { AV_CODEC_ID_DVAUDIO, MKTAG('v', 'd', 'v', 'a') }, - { AV_CODEC_ID_DVAUDIO, MKTAG('d', 'v', 'c', 'a') }, - { AV_CODEC_ID_GSM, MKTAG('a', 'g', 's', 'm') }, - { AV_CODEC_ID_ILBC, MKTAG('i', 'l', 'b', 'c') }, - { AV_CODEC_ID_MACE3, MKTAG('M', 'A', 'C', '3') }, - { AV_CODEC_ID_MACE6, MKTAG('M', 'A', 'C', '6') }, - { AV_CODEC_ID_MP1, MKTAG('.', 'm', 'p', '1') }, - { AV_CODEC_ID_MP2, MKTAG('.', 'm', 'p', '2') }, - { AV_CODEC_ID_MP3, MKTAG('.', 'm', 'p', '3') }, - { AV_CODEC_ID_MP3, 0x6D730055 }, - { AV_CODEC_ID_NELLYMOSER, MKTAG('n', 'm', 'o', 's') }, /* Flash Media Server */ - { AV_CODEC_ID_PCM_ALAW, MKTAG('a', 'l', 'a', 'w') }, - { AV_CODEC_ID_PCM_F32BE, MKTAG('f', 'l', '3', '2') }, - { AV_CODEC_ID_PCM_F32LE, MKTAG('f', 'l', '3', '2') }, - { AV_CODEC_ID_PCM_F64BE, MKTAG('f', 'l', '6', '4') }, - { AV_CODEC_ID_PCM_F64LE, MKTAG('f', 'l', '6', '4') }, - { AV_CODEC_ID_PCM_MULAW, MKTAG('u', 'l', 'a', 'w') }, - { AV_CODEC_ID_PCM_S16BE, MKTAG('t', 'w', 'o', 's') }, - { AV_CODEC_ID_PCM_S16LE, MKTAG('s', 'o', 'w', 't') }, - { AV_CODEC_ID_PCM_S16LE, MKTAG('l', 'p', 'c', 'm') }, - { AV_CODEC_ID_PCM_S24BE, MKTAG('i', 'n', '2', '4') }, - { AV_CODEC_ID_PCM_S24LE, MKTAG('i', 'n', '2', '4') }, - { AV_CODEC_ID_PCM_S32BE, MKTAG('i', 'n', '3', '2') }, - { AV_CODEC_ID_PCM_S32LE, MKTAG('i', 'n', '3', '2') }, - { AV_CODEC_ID_PCM_S8, MKTAG('s', 'o', 'w', 't') }, - { AV_CODEC_ID_PCM_U8, MKTAG('r', 'a', 'w', ' ') }, - { AV_CODEC_ID_PCM_U8, MKTAG('N', 'O', 'N', 'E') }, - { AV_CODEC_ID_QCELP, MKTAG('Q', 'c', 'l', 'p') }, - { AV_CODEC_ID_QCELP, MKTAG('Q', 'c', 'l', 'q') }, - { AV_CODEC_ID_QCELP, MKTAG('s', 'q', 'c', 'p') }, /* ISO Media fourcc */ - { AV_CODEC_ID_QDM2, MKTAG('Q', 'D', 'M', '2') }, - { AV_CODEC_ID_QDMC, MKTAG('Q', 'D', 'M', 'C') }, - { AV_CODEC_ID_SPEEX, MKTAG('s', 'p', 'e', 'x') }, /* Flash Media Server */ - { AV_CODEC_ID_WMAV2, MKTAG('W', 'M', 'A', '2') }, - { AV_CODEC_ID_EVRC, MKTAG('s', 'e', 'v', 'c') }, /* 3GPP2 */ - { AV_CODEC_ID_SMV, MKTAG('s', 's', 'm', 'v') }, /* 3GPP2 */ - { AV_CODEC_ID_NONE, 0 }, -}; - -const AVCodecTag ff_codec_movsubtitle_tags[] = { - { AV_CODEC_ID_MOV_TEXT, MKTAG('t', 'e', 'x', 't') }, - { AV_CODEC_ID_MOV_TEXT, MKTAG('t', 'x', '3', 'g') }, - { AV_CODEC_ID_EIA_608, MKTAG('c', '6', '0', '8') }, - { AV_CODEC_ID_NONE, 0 }, -}; - -/* map numeric codes from mdhd atom to ISO 639 */ -/* cf. QTFileFormat.pdf p253, qtff.pdf p205 */ -/* http://developer.apple.com/documentation/mac/Text/Text-368.html */ -/* deprecated by putting the code as 3*5bit ascii */ -static const char mov_mdhd_language_map[][4] = { - /* 0-9 */ - "eng", "fra", "ger", "ita", "dut", "sve", "spa", "dan", "por", "nor", - "heb", "jpn", "ara", "fin", "gre", "ice", "mlt", "tur", "hr "/*scr*/, "chi"/*ace?*/, - "urd", "hin", "tha", "kor", "lit", "pol", "hun", "est", "lav", "", - "fo ", "", "rus", "chi", "", "iri", "alb", "ron", "ces", "slk", - "slv", "yid", "sr ", "mac", "bul", "ukr", "bel", "uzb", "kaz", "aze", - /*?*/ - "aze", "arm", "geo", "mol", "kir", "tgk", "tuk", "mon", "", "pus", - "kur", "kas", "snd", "tib", "nep", "san", "mar", "ben", "asm", "guj", - "pa ", "ori", "mal", "kan", "tam", "tel", "", "bur", "khm", "lao", - /* roman? arabic? */ - "vie", "ind", "tgl", "may", "may", "amh", "tir", "orm", "som", "swa", - /*==rundi?*/ - "", "run", "", "mlg", "epo", "", "", "", "", "", - /* 100 */ - "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", "", "", - "", "", "", "", "", "", "", "", "wel", "baq", - "cat", "lat", "que", "grn", "aym", "tat", "uig", "dzo", "jav" -}; - -int ff_mov_iso639_to_lang(const char lang[4], int mp4) -{ - int i, code = 0; - - /* old way, only for QT? */ - for (i = 0; lang[0] && !mp4 && i < FF_ARRAY_ELEMS(mov_mdhd_language_map); i++) { - if (!strcmp(lang, mov_mdhd_language_map[i])) - return i; - } - /* XXX:can we do that in mov too? */ - if (!mp4) - return -1; - /* handle undefined as such */ - if (lang[0] == '\0') - lang = "und"; - /* 5bit ascii */ - for (i = 0; i < 3; i++) { - uint8_t c = lang[i]; - c -= 0x60; - if (c > 0x1f) - return -1; - code <<= 5; - code |= c; - } - return code; -} - -int ff_mov_lang_to_iso639(unsigned code, char to[4]) -{ - int i; - memset(to, 0, 4); - /* is it the mangled iso code? */ - /* see http://www.geocities.com/xhelmboyx/quicktime/formats/mp4-layout.txt */ - if (code >= 0x400 && code != 0x7fff) { - for (i = 2; i >= 0; i--) { - to[i] = 0x60 + (code & 0x1f); - code >>= 5; - } - return 1; - } - /* old fashion apple lang code */ - if (code >= FF_ARRAY_ELEMS(mov_mdhd_language_map)) - return 0; - if (!mov_mdhd_language_map[code][0]) - return 0; - memcpy(to, mov_mdhd_language_map[code], 4); - return 1; -} - -int ff_mp4_read_descr_len(AVIOContext *pb) -{ - int len = 0; - int count = 4; - while (count--) { - int c = avio_r8(pb); - len = (len << 7) | (c & 0x7f); - if (!(c & 0x80)) - break; - } - return len; -} - -int ff_mp4_read_descr(AVFormatContext *fc, AVIOContext *pb, int *tag) -{ - int len; - *tag = avio_r8(pb); - len = ff_mp4_read_descr_len(pb); - av_dlog(fc, "MPEG4 description: tag=0x%02x len=%d\n", *tag, len); - return len; -} - -void ff_mp4_parse_es_descr(AVIOContext *pb, int *es_id) -{ - int flags; - if (es_id) *es_id = avio_rb16(pb); - else avio_rb16(pb); - flags = avio_r8(pb); - if (flags & 0x80) //streamDependenceFlag - avio_rb16(pb); - if (flags & 0x40) { //URL_Flag - int len = avio_r8(pb); - avio_skip(pb, len); - } - if (flags & 0x20) //OCRstreamFlag - avio_rb16(pb); -} - -static const AVCodecTag mp4_audio_types[] = { - { AV_CODEC_ID_MP3ON4, AOT_PS }, /* old mp3on4 draft */ - { AV_CODEC_ID_MP3ON4, AOT_L1 }, /* layer 1 */ - { AV_CODEC_ID_MP3ON4, AOT_L2 }, /* layer 2 */ - { AV_CODEC_ID_MP3ON4, AOT_L3 }, /* layer 3 */ - { AV_CODEC_ID_MP4ALS, AOT_ALS }, /* MPEG-4 ALS */ - { AV_CODEC_ID_NONE, AOT_NULL }, -}; - -int ff_mp4_read_dec_config_descr(AVFormatContext *fc, AVStream *st, AVIOContext *pb) -{ - int len, tag; - int object_type_id = avio_r8(pb); - avio_r8(pb); /* stream type */ - avio_rb24(pb); /* buffer size db */ - avio_rb32(pb); /* max bitrate */ - avio_rb32(pb); /* avg bitrate */ - - if(avcodec_is_open(st->codec)) { - av_log(fc, AV_LOG_DEBUG, "codec open in read_dec_config_descr\n"); - return -1; - } - - st->codec->codec_id= ff_codec_get_id(ff_mp4_obj_type, object_type_id); - av_dlog(fc, "esds object type id 0x%02x\n", object_type_id); - len = ff_mp4_read_descr(fc, pb, &tag); - if (tag == MP4DecSpecificDescrTag) { - av_dlog(fc, "Specific MPEG4 header len=%d\n", len); - if (!len || (uint64_t)len > (1<<30)) - return -1; - av_free(st->codec->extradata); - st->codec->extradata = av_mallocz(len + FF_INPUT_BUFFER_PADDING_SIZE); - if (!st->codec->extradata) - return AVERROR(ENOMEM); - avio_read(pb, st->codec->extradata, len); - st->codec->extradata_size = len; - if (st->codec->codec_id == AV_CODEC_ID_AAC) { - MPEG4AudioConfig cfg; - avpriv_mpeg4audio_get_config(&cfg, st->codec->extradata, - st->codec->extradata_size * 8, 1); - st->codec->channels = cfg.channels; - if (cfg.object_type == 29 && cfg.sampling_index < 3) // old mp3on4 - st->codec->sample_rate = avpriv_mpa_freq_tab[cfg.sampling_index]; - else if (cfg.ext_sample_rate) - st->codec->sample_rate = cfg.ext_sample_rate; - else - st->codec->sample_rate = cfg.sample_rate; - av_dlog(fc, "mp4a config channels %d obj %d ext obj %d " - "sample rate %d ext sample rate %d\n", st->codec->channels, - cfg.object_type, cfg.ext_object_type, - cfg.sample_rate, cfg.ext_sample_rate); - if (!(st->codec->codec_id = ff_codec_get_id(mp4_audio_types, - cfg.object_type))) - st->codec->codec_id = AV_CODEC_ID_AAC; - } - } - return 0; -} - -typedef struct MovChannelLayout { - int64_t channel_layout; - uint32_t layout_tag; -} MovChannelLayout; - -static const MovChannelLayout mov_channel_layout[] = { - { AV_CH_LAYOUT_MONO, (100<<16) | 1}, // kCAFChannelLayoutTag_Mono - { AV_CH_LAYOUT_STEREO, (101<<16) | 2}, // kCAFChannelLayoutTag_Stereo - { AV_CH_LAYOUT_STEREO, (102<<16) | 2}, // kCAFChannelLayoutTag_StereoHeadphones - { AV_CH_LAYOUT_2_1, (131<<16) | 3}, // kCAFChannelLayoutTag_ITU_2_1 - { AV_CH_LAYOUT_QUAD, (132<<16) | 4}, // kCAFChannelLayoutTag_ITU_2_2 - { AV_CH_LAYOUT_2_2, (132<<16) | 4}, // kCAFChannelLayoutTag_ITU_2_2 - { AV_CH_LAYOUT_QUAD, (108<<16) | 4}, // kCAFChannelLayoutTag_Quadraphonic - { AV_CH_LAYOUT_SURROUND, (113<<16) | 3}, // kCAFChannelLayoutTag_MPEG_3_0_A - { AV_CH_LAYOUT_4POINT0, (115<<16) | 4}, // kCAFChannelLayoutTag_MPEG_4_0_A - { AV_CH_LAYOUT_5POINT0_BACK, (117<<16) | 5}, // kCAFChannelLayoutTag_MPEG_5_0_A - { AV_CH_LAYOUT_5POINT0, (117<<16) | 5}, // kCAFChannelLayoutTag_MPEG_5_0_A - { AV_CH_LAYOUT_5POINT1_BACK, (121<<16) | 6}, // kCAFChannelLayoutTag_MPEG_5_1_A - { AV_CH_LAYOUT_5POINT1, (121<<16) | 6}, // kCAFChannelLayoutTag_MPEG_5_1_A - { AV_CH_LAYOUT_7POINT1, (128<<16) | 8}, // kCAFChannelLayoutTag_MPEG_7_1_C - { AV_CH_LAYOUT_7POINT1_WIDE, (126<<16) | 8}, // kCAFChannelLayoutTag_MPEG_7_1_A - { AV_CH_LAYOUT_5POINT1_BACK|AV_CH_LAYOUT_STEREO_DOWNMIX, (130<<16) | 8}, // kCAFChannelLayoutTag_SMPTE_DTV - { AV_CH_LAYOUT_STEREO|AV_CH_LOW_FREQUENCY, (133<<16) | 3}, // kCAFChannelLayoutTag_DVD_4 - { AV_CH_LAYOUT_2_1|AV_CH_LOW_FREQUENCY, (134<<16) | 4}, // kCAFChannelLayoutTag_DVD_5 - { AV_CH_LAYOUT_QUAD|AV_CH_LOW_FREQUENCY, (135<<16) | 4}, // kCAFChannelLayoutTag_DVD_6 - { AV_CH_LAYOUT_2_2|AV_CH_LOW_FREQUENCY, (135<<16) | 4}, // kCAFChannelLayoutTag_DVD_6 - { AV_CH_LAYOUT_SURROUND|AV_CH_LOW_FREQUENCY, (136<<16) | 4}, // kCAFChannelLayoutTag_DVD_10 - { AV_CH_LAYOUT_4POINT0|AV_CH_LOW_FREQUENCY, (137<<16) | 5}, // kCAFChannelLayoutTag_DVD_11 - { 0, 0}, -}; -#if 0 -int ff_mov_read_chan(AVFormatContext *s, AVStream *st, int64_t size) -{ - AVCodecContext *codec= st->codec; - uint32_t layout_tag; - AVIOContext *pb = s->pb; - const MovChannelLayout *layouts = mov_channel_layout; - - if (size < 12) - return AVERROR_INVALIDDATA; - - layout_tag = avio_rb32(pb); - size -= 4; - if (layout_tag == 0) { // kCAFChannelLayoutTag_UseChannelDescriptions - // Channel descriptions not implemented - av_log_ask_for_sample(s, "Unimplemented container channel layout.\n"); - avio_skip(pb, size); - return 0; - } - if (layout_tag == 0x10000) { // kCAFChannelLayoutTag_UseChannelBitmap - codec->channel_layout = avio_rb32(pb); - size -= 4; - avio_skip(pb, size); - return 0; - } - while (layouts->channel_layout) { - if (layout_tag == layouts->layout_tag) { - codec->channel_layout = layouts->channel_layout; - break; - } - layouts++; - } - if (!codec->channel_layout) - av_log(s, AV_LOG_WARNING, "Unknown container channel layout.\n"); - avio_skip(pb, size); - - return 0; -} -#endif - -void ff_mov_write_chan(AVIOContext *pb, int64_t channel_layout) -{ - const MovChannelLayout *layouts; - uint32_t layout_tag = 0; - - for (layouts = mov_channel_layout; layouts->channel_layout; layouts++) - if (channel_layout == layouts->channel_layout) { - layout_tag = layouts->layout_tag; - break; - } - - if (layout_tag) { - avio_wb32(pb, layout_tag); // mChannelLayoutTag - avio_wb32(pb, 0); // mChannelBitmap - } else { - avio_wb32(pb, 0x10000); // kCAFChannelLayoutTag_UseChannelBitmap - avio_wb32(pb, channel_layout); - } - avio_wb32(pb, 0); // mNumberChannelDescriptions -} - diff --git a/ffmpeg1/libavformat/isom.h b/ffmpeg1/libavformat/isom.h deleted file mode 100644 index 4154baf..0000000 --- a/ffmpeg1/libavformat/isom.h +++ /dev/null @@ -1,209 +0,0 @@ -/* - * ISO Media common code - * copyright (c) 2001 Fabrice Bellard - * copyright (c) 2002 Francois Revol - * copyright (c) 2006 Baptiste Coudurier - * - * 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 AVFORMAT_ISOM_H -#define AVFORMAT_ISOM_H - -#include "avio.h" -#include "internal.h" -#include "dv.h" - -/* isom.c */ -extern const AVCodecTag ff_mp4_obj_type[]; -extern const AVCodecTag ff_codec_movvideo_tags[]; -extern const AVCodecTag ff_codec_movaudio_tags[]; -extern const AVCodecTag ff_codec_movsubtitle_tags[]; - -int ff_mov_iso639_to_lang(const char lang[4], int mp4); -int ff_mov_lang_to_iso639(unsigned code, char to[4]); - -/* the QuickTime file format is quite convoluted... - * it has lots of index tables, each indexing something in another one... - * Here we just use what is needed to read the chunks - */ - -typedef struct MOVStts { - int count; - int duration; -} MOVStts; - -typedef struct MOVStsc { - int first; - int count; - int id; -} MOVStsc; - -typedef struct MOVDref { - uint32_t type; - char *path; - char *dir; - char volume[28]; - char filename[64]; - int16_t nlvl_to, nlvl_from; -} MOVDref; - -typedef struct MOVAtom { - uint32_t type; - int64_t size; /* total size (excluding the size and type fields) */ -} MOVAtom; - -struct MOVParseTableEntry; - -typedef struct MOVFragment { - unsigned track_id; - uint64_t base_data_offset; - uint64_t moof_offset; - unsigned stsd_id; - unsigned duration; - unsigned size; - unsigned flags; -} MOVFragment; - -typedef struct MOVTrackExt { - unsigned track_id; - unsigned stsd_id; - unsigned duration; - unsigned size; - unsigned flags; -} MOVTrackExt; - -typedef struct MOVSbgp { - unsigned int count; - unsigned int index; -} MOVSbgp; - -typedef struct MOVStreamContext { - AVIOContext *pb; - int pb_is_copied; - int ffindex; ///< AVStream index - int next_chunk; - unsigned int chunk_count; - int64_t *chunk_offsets; - unsigned int stts_count; - MOVStts *stts_data; - unsigned int ctts_count; - MOVStts *ctts_data; - unsigned int stsc_count; - MOVStsc *stsc_data; - unsigned int stps_count; - unsigned *stps_data; ///< partial sync sample for mpeg-2 open gop - int ctts_index; - int ctts_sample; - unsigned int sample_size; ///< may contain value calculated from stsd or value from stsz atom - unsigned int alt_sample_size; ///< always contains sample size from stsz atom - unsigned int sample_count; - int *sample_sizes; - int keyframe_absent; - unsigned int keyframe_count; - int *keyframes; - int time_scale; - int64_t empty_duration; ///< empty duration of the first edit list entry - int64_t start_time; ///< start time of the media - int64_t time_offset; ///< time offset of the edit list entries - int current_sample; - unsigned int bytes_per_frame; - unsigned int samples_per_frame; - int dv_audio_container; - int pseudo_stream_id; ///< -1 means demux all ids - int16_t audio_cid; ///< stsd audio compression id - unsigned drefs_count; - MOVDref *drefs; - int dref_id; - int timecode_track; - int wrong_dts; ///< dts are wrong due to huge ctts offset (iMovie files) - int width; ///< tkhd width - int height; ///< tkhd height - int dts_shift; ///< dts shift when ctts is negative - uint32_t palette[256]; - int has_palette; - int64_t data_size; - uint32_t tmcd_flags; ///< tmcd track flags - int64_t track_end; ///< used for dts generation in fragmented movie files - int start_pad; ///< amount of samples to skip due to enc-dec delay - unsigned int rap_group_count; - MOVSbgp *rap_group; -} MOVStreamContext; - -typedef struct MOVContext { - AVClass *avclass; - AVFormatContext *fc; - int time_scale; - int64_t duration; ///< duration of the longest track - int found_moov; ///< 'moov' atom has been found - int found_mdat; ///< 'mdat' atom has been found - DVDemuxContext *dv_demux; - AVFormatContext *dv_fctx; - int isom; ///< 1 if file is ISO Media (mp4/3gp) - MOVFragment fragment; ///< current fragment in moof atom - MOVTrackExt *trex_data; - unsigned trex_count; - int itunes_metadata; ///< metadata are itunes style - int chapter_track; - int use_absolute_path; - int ignore_editlist; - int64_t next_root_atom; ///< offset of the next root atom -} MOVContext; - -int ff_mp4_read_descr_len(AVIOContext *pb); -int ff_mp4_read_descr(AVFormatContext *fc, AVIOContext *pb, int *tag); -int ff_mp4_read_dec_config_descr(AVFormatContext *fc, AVStream *st, AVIOContext *pb); -void ff_mp4_parse_es_descr(AVIOContext *pb, int *es_id); - -#define MP4ODescrTag 0x01 -#define MP4IODescrTag 0x02 -#define MP4ESDescrTag 0x03 -#define MP4DecConfigDescrTag 0x04 -#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 AVCodecID ff_mov_get_lpcm_codec_id(int bps, int flags); - -int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries); -void ff_mov_write_chan(AVIOContext *pb, int64_t channel_layout); - -#endif /* AVFORMAT_ISOM_H */ diff --git a/ffmpeg1/libavformat/iss.c b/ffmpeg1/libavformat/iss.c deleted file mode 100644 index e4335b4..0000000 --- a/ffmpeg1/libavformat/iss.c +++ /dev/null @@ -1,144 +0,0 @@ -/* - * ISS (.iss) file demuxer - * Copyright (c) 2008 Jaikrishnan Menon - * - * 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 - */ - -/** - * @file - * Funcom ISS file demuxer - * @author Jaikrishnan Menon - * @see http://wiki.multimedia.cx/index.php?title=FunCom_ISS - */ - -#include "libavutil/channel_layout.h" -#include "avformat.h" -#include "internal.h" -#include "libavutil/avstring.h" - -#define ISS_SIG "IMA_ADPCM_Sound" -#define ISS_SIG_LEN 15 -#define MAX_TOKEN_SIZE 20 - -typedef struct { - int packet_size; - int sample_start_pos; -} IssDemuxContext; - -static void get_token(AVIOContext *s, char *buf, int maxlen) -{ - int i = 0; - char c; - - while ((c = avio_r8(s))) { - if(c == ' ') - break; - if (i < maxlen-1) - buf[i++] = c; - } - - if(!c) - avio_r8(s); - - buf[i] = 0; /* Ensure null terminated, but may be truncated */ -} - -static int iss_probe(AVProbeData *p) -{ - if (strncmp(p->buf, ISS_SIG, ISS_SIG_LEN)) - return 0; - - return AVPROBE_SCORE_MAX; -} - -static av_cold int iss_read_header(AVFormatContext *s) -{ - IssDemuxContext *iss = s->priv_data; - AVIOContext *pb = s->pb; - AVStream *st; - char token[MAX_TOKEN_SIZE]; - int stereo, rate_divisor; - - get_token(pb, token, sizeof(token)); //"IMA_ADPCM_Sound" - get_token(pb, token, sizeof(token)); //packet size - sscanf(token, "%d", &iss->packet_size); - get_token(pb, token, sizeof(token)); //File ID - get_token(pb, token, sizeof(token)); //out size - get_token(pb, token, sizeof(token)); //stereo - sscanf(token, "%d", &stereo); - get_token(pb, token, sizeof(token)); //Unknown1 - get_token(pb, token, sizeof(token)); //RateDivisor - sscanf(token, "%d", &rate_divisor); - get_token(pb, token, sizeof(token)); //Unknown2 - get_token(pb, token, sizeof(token)); //Version ID - get_token(pb, token, sizeof(token)); //Size - - if (iss->packet_size <= 0) { - av_log(s, AV_LOG_ERROR, "packet_size %d is invalid\n", iss->packet_size); - return AVERROR_INVALIDDATA; - } - - iss->sample_start_pos = avio_tell(pb); - - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = AV_CODEC_ID_ADPCM_IMA_ISS; - if (stereo) { - st->codec->channels = 2; - st->codec->channel_layout = AV_CH_LAYOUT_STEREO; - } else { - st->codec->channels = 1; - st->codec->channel_layout = AV_CH_LAYOUT_MONO; - } - st->codec->sample_rate = 44100; - if(rate_divisor > 0) - st->codec->sample_rate /= rate_divisor; - st->codec->bits_per_coded_sample = 4; - st->codec->bit_rate = st->codec->channels * st->codec->sample_rate - * st->codec->bits_per_coded_sample; - st->codec->block_align = iss->packet_size; - avpriv_set_pts_info(st, 32, 1, st->codec->sample_rate); - - return 0; -} - -static int iss_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - IssDemuxContext *iss = s->priv_data; - int ret = av_get_packet(s->pb, pkt, iss->packet_size); - - if(ret != iss->packet_size) - return AVERROR(EIO); - - pkt->stream_index = 0; - pkt->pts = avio_tell(s->pb) - iss->sample_start_pos; - if(s->streams[0]->codec->channels > 0) - pkt->pts /= s->streams[0]->codec->channels*2; - return 0; -} - -AVInputFormat ff_iss_demuxer = { - .name = "iss", - .long_name = NULL_IF_CONFIG_SMALL("Funcom ISS"), - .priv_data_size = sizeof(IssDemuxContext), - .read_probe = iss_probe, - .read_header = iss_read_header, - .read_packet = iss_read_packet, -}; diff --git a/ffmpeg1/libavformat/iv8.c b/ffmpeg1/libavformat/iv8.c deleted file mode 100644 index 38b7960..0000000 --- a/ffmpeg1/libavformat/iv8.c +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (c) 2009 Michael Niedermayer - * - * 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 "internal.h" - - -static int probe(AVProbeData *p) -{ - // the single file I have starts with that, I do not know if others do, too - if( p->buf[0] == 1 - && p->buf[1] == 1 - && p->buf[2] == 3 - && p->buf[3] == 0xB8 - && p->buf[4] == 0x80 - && p->buf[5] == 0x60 - ) - return AVPROBE_SCORE_MAX-2; - - return 0; -} - -static int read_header(AVFormatContext *s) -{ - AVStream *st; - - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = AV_CODEC_ID_MPEG4; - st->need_parsing = AVSTREAM_PARSE_FULL; - avpriv_set_pts_info(st, 64, 1, 90000); - - return 0; - -} - -static int read_packet(AVFormatContext *s, AVPacket *pkt) -{ - int ret, size, pts, type, flags; - int first_pkt = 0; - int frame_complete = 0; - - while (!frame_complete) { - - type = avio_rb16(s->pb); // 257 or 258 - size = avio_rb16(s->pb); - flags = avio_rb16(s->pb); //some flags, 0x80 indicates end of frame - avio_rb16(s->pb); //packet number - pts = avio_rb32(s->pb); - avio_rb32(s->pb); //6A 13 E3 88 - - frame_complete = flags & 0x80; - - size -= 12; - if (size < 1) - return -1; - - if (type == 258) { - avio_skip(s->pb, size); - frame_complete = 0; - continue; - } - - if (!first_pkt) { - ret = av_get_packet(s->pb, pkt, size); - if (ret < 0) - return ret; - first_pkt = 1; - pkt->pts = pts; - pkt->pos -= 16; - } else { - ret = av_append_packet(s->pb, pkt, size); - if (ret < 0) { - av_log(s, AV_LOG_ERROR, "failed to grow packet\n"); - av_free_packet(pkt); - return ret; - } - } - if (ret < size) { - av_log(s, AV_LOG_ERROR, "Truncated packet! Read %d of %d bytes\n", - ret, size); - pkt->flags |= AV_PKT_FLAG_CORRUPT; - break; - } - } - pkt->stream_index = 0; - - return 0; -} - -AVInputFormat ff_iv8_demuxer = { - .name = "iv8", - .long_name = NULL_IF_CONFIG_SMALL("IndigoVision 8000 video"), - .read_probe = probe, - .read_header = read_header, - .read_packet = read_packet, - .flags = AVFMT_GENERIC_INDEX, -}; diff --git a/ffmpeg1/libavformat/ivfdec.c b/ffmpeg1/libavformat/ivfdec.c deleted file mode 100644 index c0fdafb..0000000 --- a/ffmpeg1/libavformat/ivfdec.c +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2010 David Conrad - * - * 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 "internal.h" -#include "riff.h" -#include "libavutil/intreadwrite.h" - -static int probe(AVProbeData *p) -{ - if (AV_RL32(p->buf) == MKTAG('D','K','I','F') - && !AV_RL16(p->buf+4) && AV_RL16(p->buf+6) == 32) - return AVPROBE_SCORE_MAX-2; - - return 0; -} - -static int read_header(AVFormatContext *s) -{ - AVStream *st; - AVRational time_base; - - avio_rl32(s->pb); // DKIF - avio_rl16(s->pb); // version - avio_rl16(s->pb); // header size - - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - - - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_tag = avio_rl32(s->pb); - st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, st->codec->codec_tag); - st->codec->width = avio_rl16(s->pb); - st->codec->height = avio_rl16(s->pb); - time_base.den = avio_rl32(s->pb); - time_base.num = avio_rl32(s->pb); - st->duration = avio_rl64(s->pb); - - st->need_parsing = AVSTREAM_PARSE_HEADERS; - - if (!time_base.den || !time_base.num) { - av_log(s, AV_LOG_ERROR, "Invalid frame rate\n"); - return AVERROR_INVALIDDATA; - } - - avpriv_set_pts_info(st, 64, time_base.num, time_base.den); - - return 0; -} - -static int read_packet(AVFormatContext *s, AVPacket *pkt) -{ - int ret, size = avio_rl32(s->pb); - int64_t pts = avio_rl64(s->pb); - - ret = av_get_packet(s->pb, pkt, size); - pkt->stream_index = 0; - pkt->pts = pts; - pkt->pos -= 12; - - return ret; -} - -AVInputFormat ff_ivf_demuxer = { - .name = "ivf", - .long_name = NULL_IF_CONFIG_SMALL("On2 IVF"), - .read_probe = probe, - .read_header = read_header, - .read_packet = read_packet, - .flags = AVFMT_GENERIC_INDEX, - .codec_tag = (const AVCodecTag* const []){ ff_codec_bmp_tags, 0 }, -}; diff --git a/ffmpeg1/libavformat/ivfenc.c b/ffmpeg1/libavformat/ivfenc.c deleted file mode 100644 index ddb205b..0000000 --- a/ffmpeg1/libavformat/ivfenc.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2010 Reimar Döffinger - * - * 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 "libavutil/intreadwrite.h" - -static int ivf_write_header(AVFormatContext *s) -{ - AVCodecContext *ctx; - AVIOContext *pb = s->pb; - - if (s->nb_streams != 1) { - av_log(s, AV_LOG_ERROR, "Format supports only exactly one video stream\n"); - return AVERROR(EINVAL); - } - ctx = s->streams[0]->codec; - if (ctx->codec_type != AVMEDIA_TYPE_VIDEO || ctx->codec_id != AV_CODEC_ID_VP8) { - av_log(s, AV_LOG_ERROR, "Currently only VP8 is supported!\n"); - return AVERROR(EINVAL); - } - avio_write(pb, "DKIF", 4); - avio_wl16(pb, 0); // version - avio_wl16(pb, 32); // header length - avio_wl32(pb, ctx->codec_tag ? ctx->codec_tag : AV_RL32("VP80")); - avio_wl16(pb, ctx->width); - avio_wl16(pb, ctx->height); - avio_wl32(pb, s->streams[0]->time_base.den); - avio_wl32(pb, s->streams[0]->time_base.num); - avio_wl64(pb, s->streams[0]->duration); // TODO: duration or number of frames?!? - - return 0; -} - -static int ivf_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - AVIOContext *pb = s->pb; - avio_wl32(pb, pkt->size); - avio_wl64(pb, pkt->pts); - avio_write(pb, pkt->data, pkt->size); - avio_flush(pb); - - return 0; -} - -AVOutputFormat ff_ivf_muxer = { - .name = "ivf", - .long_name = NULL_IF_CONFIG_SMALL("On2 IVF"), - .extensions = "ivf", - .audio_codec = AV_CODEC_ID_NONE, - .video_codec = AV_CODEC_ID_VP8, - .write_header = ivf_write_header, - .write_packet = ivf_write_packet, -}; diff --git a/ffmpeg1/libavformat/jacosubdec.c b/ffmpeg1/libavformat/jacosubdec.c deleted file mode 100644 index 89e7e1b..0000000 --- a/ffmpeg1/libavformat/jacosubdec.c +++ /dev/null @@ -1,270 +0,0 @@ -/* - * Copyright (c) 2012 Clément BÅ“sch - * - * 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 - */ - -/** - * @file - * JACOsub subtitle demuxer - * @see http://unicorn.us.com/jacosub/jscripts.html - * @todo Support P[ALETTE] directive. - */ - -#include "avformat.h" -#include "internal.h" -#include "subtitles.h" -#include "libavcodec/internal.h" -#include "libavcodec/jacosub.h" -#include "libavutil/avstring.h" -#include "libavutil/bprint.h" -#include "libavutil/intreadwrite.h" - -typedef struct { - int shift; - unsigned timeres; - FFDemuxSubtitlesQueue q; -} JACOsubContext; - -static int timed_line(const char *ptr) -{ - char c; - return (sscanf(ptr, "%*u:%*u:%*u.%*u %*u:%*u:%*u.%*u %c", &c) == 1 || - sscanf(ptr, "@%*u @%*u %c", &c) == 1); -} - -static int jacosub_probe(AVProbeData *p) -{ - const char *ptr = p->buf; - const char *ptr_end = p->buf + p->buf_size; - - if (AV_RB24(ptr) == 0xEFBBBF) - ptr += 3; /* skip UTF-8 BOM */ - - while (ptr < ptr_end) { - while (jss_whitespace(*ptr)) - ptr++; - if (*ptr != '#' && *ptr != '\n') { - if (timed_line(ptr)) - return AVPROBE_SCORE_MAX/2 + 1; - return 0; - } - ptr += strcspn(ptr, "\n") + 1; - } - return 0; -} - -static const char * const cmds[] = { - "CLOCKPAUSE", - "DIRECTIVE", - "FONT", - "HRES", - "INCLUDE", - "PALETTE", - "QUANTIZE", - "RAMP", - "SHIFT", - "TIMERES", -}; - -static int get_jss_cmd(char k) -{ - int i; - - k = av_toupper(k); - for (i = 0; i < FF_ARRAY_ELEMS(cmds); i++) - if (k == cmds[i][0]) - return i; - return -1; -} - -static int jacosub_read_close(AVFormatContext *s) -{ - JACOsubContext *jacosub = s->priv_data; - ff_subtitles_queue_clean(&jacosub->q); - return 0; -} - -static const char *read_ts(JACOsubContext *jacosub, const char *buf, - int64_t *start, int *duration) -{ - int len; - unsigned hs, ms, ss, fs; // hours, minutes, seconds, frame start - unsigned he, me, se, fe; // hours, minutes, seconds, frame end - int ts_start, ts_end; - - /* timed format */ - if (sscanf(buf, "%u:%u:%u.%u %u:%u:%u.%u %n", - &hs, &ms, &ss, &fs, - &he, &me, &se, &fe, &len) == 8) { - ts_start = (hs*3600 + ms*60 + ss) * jacosub->timeres + fs; - ts_end = (he*3600 + me*60 + se) * jacosub->timeres + fe; - goto shift_and_ret; - } - - /* timestamps format */ - if (sscanf(buf, "@%u @%u %n", &ts_start, &ts_end, &len) == 2) - goto shift_and_ret; - - return NULL; - -shift_and_ret: - ts_start = (ts_start + jacosub->shift) * 100 / jacosub->timeres; - ts_end = (ts_end + jacosub->shift) * 100 / jacosub->timeres; - *start = ts_start; - *duration = ts_start + ts_end; - return buf + len; -} - -static int get_shift(int timeres, const char *buf) -{ - int sign = 1; - int a = 0, b = 0, c = 0, d = 0; -#define SSEP "%*1[.:]" - int n = sscanf(buf, "%d"SSEP"%d"SSEP"%d"SSEP"%d", &a, &b, &c, &d); -#undef SSEP - - if (*buf == '-' || a < 0) { - sign = -1; - a = FFABS(a); - } - - switch (n) { - case 4: return sign * ((a*3600 + b*60 + c) * timeres + d); - case 3: return sign * (( a*60 + b) * timeres + c); - case 2: return sign * (( a) * timeres + b); - } - - return 0; -} - -static int jacosub_read_header(AVFormatContext *s) -{ - AVBPrint header; - AVIOContext *pb = s->pb; - char line[JSS_MAX_LINESIZE]; - JACOsubContext *jacosub = s->priv_data; - int shift_set = 0; // only the first shift matters - int merge_line = 0; - int i, ret; - - AVStream *st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - avpriv_set_pts_info(st, 64, 1, 100); - st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE; - st->codec->codec_id = AV_CODEC_ID_JACOSUB; - - jacosub->timeres = 30; - - av_bprint_init(&header, 1024+FF_INPUT_BUFFER_PADDING_SIZE, 4096); - - while (!url_feof(pb)) { - int cmd_len; - const char *p = line; - int64_t pos = avio_tell(pb); - int len = ff_get_line(pb, line, sizeof(line)); - - p = jss_skip_whitespace(p); - - /* queue timed line */ - if (merge_line || timed_line(p)) { - AVPacket *sub; - - sub = ff_subtitles_queue_insert(&jacosub->q, line, len, merge_line); - if (!sub) - return AVERROR(ENOMEM); - sub->pos = pos; - merge_line = len > 1 && !strcmp(&line[len - 2], "\\\n"); - continue; - } - - /* skip all non-compiler commands and focus on the command */ - if (*p != '#') - continue; - p++; - i = get_jss_cmd(p[0]); - if (i == -1) - continue; - - /* trim command + spaces */ - cmd_len = strlen(cmds[i]); - if (av_strncasecmp(p, cmds[i], cmd_len) == 0) - p += cmd_len; - else - p++; - p = jss_skip_whitespace(p); - - /* handle commands which affect the whole script */ - switch (cmds[i][0]) { - case 'S': // SHIFT command affect the whole script... - if (!shift_set) { - jacosub->shift = get_shift(jacosub->timeres, p); - shift_set = 1; - } - av_bprintf(&header, "#S %s", p); - break; - case 'T': // ...but must be placed after TIMERES - jacosub->timeres = strtol(p, NULL, 10); - if (!jacosub->timeres) - jacosub->timeres = 30; - else - av_bprintf(&header, "#T %s", p); - break; - } - } - - /* general/essential directives in the extradata */ - ret = avpriv_bprint_to_extradata(st->codec, &header); - if (ret < 0) - return ret; - - /* SHIFT and TIMERES affect the whole script so packet timing can only be - * done in a second pass */ - for (i = 0; i < jacosub->q.nb_subs; i++) { - AVPacket *sub = &jacosub->q.subs[i]; - read_ts(jacosub, sub->data, &sub->pts, &sub->duration); - } - ff_subtitles_queue_finalize(&jacosub->q); - - return 0; -} - -static int jacosub_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - JACOsubContext *jacosub = s->priv_data; - return ff_subtitles_queue_read_packet(&jacosub->q, pkt); -} - -static int jacosub_read_seek(AVFormatContext *s, int stream_index, - int64_t min_ts, int64_t ts, int64_t max_ts, int flags) -{ - JACOsubContext *jacosub = s->priv_data; - return ff_subtitles_queue_seek(&jacosub->q, s, stream_index, - min_ts, ts, max_ts, flags); -} - -AVInputFormat ff_jacosub_demuxer = { - .name = "jacosub", - .long_name = NULL_IF_CONFIG_SMALL("JACOsub subtitle format"), - .priv_data_size = sizeof(JACOsubContext), - .read_probe = jacosub_probe, - .read_header = jacosub_read_header, - .read_packet = jacosub_read_packet, - .read_seek2 = jacosub_read_seek, - .read_close = jacosub_read_close, -}; diff --git a/ffmpeg1/libavformat/jacosubenc.c b/ffmpeg1/libavformat/jacosubenc.c deleted file mode 100644 index a11e45a..0000000 --- a/ffmpeg1/libavformat/jacosubenc.c +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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 "rawenc.h" - -static int jacosub_write_header(AVFormatContext *s) -{ - const AVCodecContext *avctx = s->streams[0]->codec; - - if (avctx->extradata_size) { - avio_write(s->pb, avctx->extradata, avctx->extradata_size - 1); - avio_flush(s->pb); - } - return 0; -} - -AVOutputFormat ff_jacosub_muxer = { - .name = "jacosub", - .long_name = NULL_IF_CONFIG_SMALL("JACOsub subtitle format"), - .mime_type = "text/x-jacosub", - .extensions = "jss,js", - .write_header = jacosub_write_header, - .write_packet = ff_raw_write_packet, - .flags = AVFMT_TS_NONSTRICT, - .subtitle_codec = AV_CODEC_ID_JACOSUB, -}; diff --git a/ffmpeg1/libavformat/jvdec.c b/ffmpeg1/libavformat/jvdec.c deleted file mode 100644 index e941492..0000000 --- a/ffmpeg1/libavformat/jvdec.c +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Bitmap Brothers JV demuxer - * Copyright (c) 2005, 2011 Peter Ross - * - * 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 - */ - -/** - * @file - * Bitmap Brothers JV demuxer - * @author Peter Ross - */ - -#include "libavutil/channel_layout.h" -#include "libavutil/intreadwrite.h" -#include "avformat.h" -#include "internal.h" - -#define JV_PREAMBLE_SIZE 5 - -typedef struct { - int audio_size; /** audio packet size (bytes) */ - int video_size; /** video packet size (bytes) */ - int palette_size; /** palette size (bytes) */ - int video_type; /** per-frame video compression type */ -} JVFrame; - -typedef struct { - JVFrame *frames; - enum { - JV_AUDIO = 0, - JV_VIDEO, - JV_PADDING - } state; - int64_t pts; -} JVDemuxContext; - -#define MAGIC " Compression by John M Phillips Copyright (C) 1995 The Bitmap Brothers Ltd." - -static int read_probe(AVProbeData *pd) -{ - if (pd->buf[0] == 'J' && pd->buf[1] == 'V' && strlen(MAGIC) <= pd->buf_size - 4 && - !memcmp(pd->buf + 4, MAGIC, strlen(MAGIC))) - return AVPROBE_SCORE_MAX; - return 0; -} - -static int read_header(AVFormatContext *s) -{ - JVDemuxContext *jv = s->priv_data; - AVIOContext *pb = s->pb; - AVStream *vst, *ast; - int64_t audio_pts = 0; - int64_t offset; - int i; - - avio_skip(pb, 80); - - ast = avformat_new_stream(s, NULL); - vst = avformat_new_stream(s, NULL); - if (!ast || !vst) - return AVERROR(ENOMEM); - - vst->codec->codec_type = AVMEDIA_TYPE_VIDEO; - vst->codec->codec_id = AV_CODEC_ID_JV; - vst->codec->codec_tag = 0; /* no fourcc */ - vst->codec->width = avio_rl16(pb); - vst->codec->height = avio_rl16(pb); - vst->duration = - vst->nb_frames = - ast->nb_index_entries = avio_rl16(pb); - avpriv_set_pts_info(vst, 64, avio_rl16(pb), 1000); - - avio_skip(pb, 4); - - ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; - ast->codec->codec_id = AV_CODEC_ID_PCM_U8; - ast->codec->codec_tag = 0; /* no fourcc */ - ast->codec->sample_rate = avio_rl16(pb); - ast->codec->channels = 1; - ast->codec->channel_layout = AV_CH_LAYOUT_MONO; - avpriv_set_pts_info(ast, 64, 1, ast->codec->sample_rate); - - avio_skip(pb, 10); - - ast->index_entries = av_malloc(ast->nb_index_entries * sizeof(*ast->index_entries)); - if (!ast->index_entries) - return AVERROR(ENOMEM); - - jv->frames = av_malloc(ast->nb_index_entries * sizeof(JVFrame)); - if (!jv->frames) - return AVERROR(ENOMEM); - - offset = 0x68 + ast->nb_index_entries * 16; - for(i = 0; i < ast->nb_index_entries; i++) { - AVIndexEntry *e = ast->index_entries + i; - JVFrame *jvf = jv->frames + i; - - /* total frame size including audio, video, palette data and padding */ - e->size = avio_rl32(pb); - e->timestamp = i; - e->pos = offset; - offset += e->size; - - jvf->audio_size = avio_rl32(pb); - jvf->video_size = avio_rl32(pb); - jvf->palette_size = avio_r8(pb) ? 768 : 0; - jvf->video_size = FFMIN(FFMAX(jvf->video_size, 0), - INT_MAX - JV_PREAMBLE_SIZE - jvf->palette_size); - if (avio_r8(pb)) - av_log(s, AV_LOG_WARNING, "unsupported audio codec\n"); - jvf->video_type = avio_r8(pb); - avio_skip(pb, 1); - - e->timestamp = jvf->audio_size ? audio_pts : AV_NOPTS_VALUE; - audio_pts += jvf->audio_size; - - e->flags = jvf->video_type != 1 ? AVINDEX_KEYFRAME : 0; - } - - jv->state = JV_AUDIO; - return 0; -} - -static int read_packet(AVFormatContext *s, AVPacket *pkt) -{ - JVDemuxContext *jv = s->priv_data; - AVIOContext *pb = s->pb; - AVStream *ast = s->streams[0]; - - while (!url_feof(s->pb) && jv->pts < ast->nb_index_entries) { - const AVIndexEntry *e = ast->index_entries + jv->pts; - const JVFrame *jvf = jv->frames + jv->pts; - - switch(jv->state) { - case JV_AUDIO: - jv->state++; - if (jvf->audio_size ) { - if (av_get_packet(s->pb, pkt, jvf->audio_size) < 0) - return AVERROR(ENOMEM); - pkt->stream_index = 0; - pkt->pts = e->timestamp; - pkt->flags |= AV_PKT_FLAG_KEY; - return 0; - } - case JV_VIDEO: - jv->state++; - if (jvf->video_size || jvf->palette_size) { - int size = jvf->video_size + jvf->palette_size; - if (av_new_packet(pkt, size + JV_PREAMBLE_SIZE)) - return AVERROR(ENOMEM); - - AV_WL32(pkt->data, jvf->video_size); - pkt->data[4] = jvf->video_type; - if ((size = avio_read(pb, pkt->data + JV_PREAMBLE_SIZE, size)) < 0) - return AVERROR(EIO); - - pkt->size = size + JV_PREAMBLE_SIZE; - pkt->stream_index = 1; - pkt->pts = jv->pts; - if (jvf->video_type != 1) - pkt->flags |= AV_PKT_FLAG_KEY; - return 0; - } - case JV_PADDING: - avio_skip(pb, FFMAX(e->size - jvf->audio_size - jvf->video_size - - jvf->palette_size, 0)); - jv->state = JV_AUDIO; - jv->pts++; - } - } - - return AVERROR(EIO); -} - -static int read_seek(AVFormatContext *s, int stream_index, - int64_t ts, int flags) -{ - JVDemuxContext *jv = s->priv_data; - AVStream *ast = s->streams[0]; - int i; - - if (flags & (AVSEEK_FLAG_BYTE|AVSEEK_FLAG_FRAME)) - return AVERROR(ENOSYS); - - switch(stream_index) { - case 0: - i = av_index_search_timestamp(ast, ts, flags); - break; - case 1: - i = ts; - break; - default: - return 0; - } - - if (i < 0 || i >= ast->nb_index_entries) - return 0; - if (avio_seek(s->pb, ast->index_entries[i].pos, SEEK_SET) < 0) - return -1; - - jv->state = JV_AUDIO; - jv->pts = i; - return 0; -} - -static int read_close(AVFormatContext *s) -{ - JVDemuxContext *jv = s->priv_data; - - av_freep(&jv->frames); - - return 0; -} - -AVInputFormat ff_jv_demuxer = { - .name = "jv", - .long_name = NULL_IF_CONFIG_SMALL("Bitmap Brothers JV"), - .priv_data_size = sizeof(JVDemuxContext), - .read_probe = read_probe, - .read_header = read_header, - .read_packet = read_packet, - .read_seek = read_seek, - .read_close = read_close, -}; diff --git a/ffmpeg1/libavformat/latmenc.c b/ffmpeg1/libavformat/latmenc.c deleted file mode 100644 index 9dfb4e4..0000000 --- a/ffmpeg1/libavformat/latmenc.c +++ /dev/null @@ -1,230 +0,0 @@ -/* - * LATM/LOAS muxer - * Copyright (c) 2011 Kieran Kunhya - * - * 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 - */ - -#include "libavcodec/get_bits.h" -#include "libavcodec/put_bits.h" -#include "libavcodec/avcodec.h" -#include "libavcodec/mpeg4audio.h" -#include "libavutil/opt.h" -#include "avformat.h" -#include "rawenc.h" - -#define MAX_EXTRADATA_SIZE 1024 - -typedef struct { - AVClass *av_class; - int off; - int channel_conf; - int object_type; - int counter; - int mod; - uint8_t buffer[0x1fff + MAX_EXTRADATA_SIZE + 1024]; -} LATMContext; - -static const AVOption options[] = { - {"smc-interval", "StreamMuxConfig interval.", - offsetof(LATMContext, mod), AV_OPT_TYPE_INT, {.i64 = 0x0014}, 0x0001, 0xffff, AV_OPT_FLAG_ENCODING_PARAM}, - {NULL}, -}; - -static const AVClass latm_muxer_class = { - .class_name = "LATM/LOAS muxer", - .item_name = av_default_item_name, - .option = options, - .version = LIBAVUTIL_VERSION_INT, -}; - -static int latm_decode_extradata(LATMContext *ctx, uint8_t *buf, int size) -{ - MPEG4AudioConfig m4ac; - - if (size > MAX_EXTRADATA_SIZE) { - av_log(ctx, AV_LOG_ERROR, "Extradata is larger than currently supported.\n"); - return AVERROR_INVALIDDATA; - } - ctx->off = avpriv_mpeg4audio_get_config(&m4ac, buf, size * 8, 1); - if (ctx->off < 0) - return ctx->off; - - if (ctx->object_type == AOT_ALS && (ctx->off & 7)) { - // as long as avpriv_mpeg4audio_get_config works correctly this is impossible - av_log(ctx, AV_LOG_ERROR, "BUG: ALS offset is not byte-aligned\n"); - return AVERROR_INVALIDDATA; - } - /* FIXME: are any formats not allowed in LATM? */ - - if (m4ac.object_type > AOT_SBR && m4ac.object_type != AOT_ALS) { - av_log(ctx, AV_LOG_ERROR, "Muxing MPEG-4 AOT %d in LATM is not supported\n", m4ac.object_type); - return AVERROR_INVALIDDATA; - } - ctx->channel_conf = m4ac.chan_config; - ctx->object_type = m4ac.object_type; - - return 0; -} - -static int latm_write_header(AVFormatContext *s) -{ - LATMContext *ctx = s->priv_data; - AVCodecContext *avctx = s->streams[0]->codec; - - if (avctx->codec_id == AV_CODEC_ID_AAC_LATM) - return 0; - - if (avctx->extradata_size > 0 && - latm_decode_extradata(ctx, avctx->extradata, avctx->extradata_size) < 0) - return AVERROR_INVALIDDATA; - - return 0; -} - -static void latm_write_frame_header(AVFormatContext *s, PutBitContext *bs) -{ - LATMContext *ctx = s->priv_data; - AVCodecContext *avctx = s->streams[0]->codec; - int header_size; - - /* AudioMuxElement */ - put_bits(bs, 1, !!ctx->counter); - - if (!ctx->counter) { - /* StreamMuxConfig */ - put_bits(bs, 1, 0); /* audioMuxVersion */ - put_bits(bs, 1, 1); /* allStreamsSameTimeFraming */ - put_bits(bs, 6, 0); /* numSubFrames */ - put_bits(bs, 4, 0); /* numProgram */ - put_bits(bs, 3, 0); /* numLayer */ - - /* AudioSpecificConfig */ - if (ctx->object_type == AOT_ALS) { - header_size = avctx->extradata_size-(ctx->off >> 3); - avpriv_copy_bits(bs, &avctx->extradata[ctx->off >> 3], header_size); - } else { - // + 3 assumes not scalable and dependsOnCoreCoder == 0, - // see decode_ga_specific_config in libavcodec/aacdec.c - avpriv_copy_bits(bs, avctx->extradata, ctx->off + 3); - - if (!ctx->channel_conf) { - GetBitContext gb; - init_get_bits(&gb, avctx->extradata, avctx->extradata_size * 8); - skip_bits_long(&gb, ctx->off + 3); - avpriv_copy_pce_data(bs, &gb); - } - } - - put_bits(bs, 3, 0); /* frameLengthType */ - put_bits(bs, 8, 0xff); /* latmBufferFullness */ - - put_bits(bs, 1, 0); /* otherDataPresent */ - put_bits(bs, 1, 0); /* crcCheckPresent */ - } - - ctx->counter++; - ctx->counter %= ctx->mod; -} - -static int latm_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - LATMContext *ctx = s->priv_data; - AVIOContext *pb = s->pb; - PutBitContext bs; - int i, len; - uint8_t loas_header[] = "\x56\xe0\x00"; - - if (s->streams[0]->codec->codec_id == AV_CODEC_ID_AAC_LATM) - return ff_raw_write_packet(s, pkt); - - if (pkt->size > 2 && pkt->data[0] == 0xff && (pkt->data[1] >> 4) == 0xf) { - av_log(s, AV_LOG_ERROR, "ADTS header detected - ADTS will not be incorrectly muxed into LATM\n"); - return AVERROR_INVALIDDATA; - } - - if (!s->streams[0]->codec->extradata) { - if(pkt->size > 2 && pkt->data[0] == 0x56 && (pkt->data[1] >> 4) == 0xe && - (AV_RB16(pkt->data + 1) & 0x1FFF) + 3 == pkt->size) - return ff_raw_write_packet(s, pkt); - else - return AVERROR_INVALIDDATA; - } - - if (pkt->size > 0x1fff) - goto too_large; - - init_put_bits(&bs, ctx->buffer, pkt->size+1024+MAX_EXTRADATA_SIZE); - - latm_write_frame_header(s, &bs); - - /* PayloadLengthInfo() */ - for (i = 0; i <= pkt->size-255; i+=255) - put_bits(&bs, 8, 255); - - put_bits(&bs, 8, pkt->size-i); - - /* The LATM payload is written unaligned */ - - /* PayloadMux() */ - if (pkt->size && (pkt->data[0] & 0xe1) == 0x81) { - // Convert byte-aligned DSE to non-aligned. - // Due to the input format encoding we know that - // it is naturally byte-aligned in the input stream, - // so there are no padding bits to account for. - // To avoid having to add padding bits and rearrange - // the whole stream we just remove the byte-align flag. - // This allows us to remux our FATE AAC samples into latm - // files that are still playable with minimal effort. - put_bits(&bs, 8, pkt->data[0] & 0xfe); - avpriv_copy_bits(&bs, pkt->data + 1, 8*pkt->size - 8); - } else - avpriv_copy_bits(&bs, pkt->data, 8*pkt->size); - - avpriv_align_put_bits(&bs); - flush_put_bits(&bs); - - len = put_bits_count(&bs) >> 3; - - if (len > 0x1fff) - goto too_large; - - loas_header[1] |= (len >> 8) & 0x1f; - loas_header[2] |= len & 0xff; - - avio_write(pb, loas_header, 3); - avio_write(pb, ctx->buffer, len); - - return 0; - -too_large: - av_log(s, AV_LOG_ERROR, "LATM packet size larger than maximum size 0x1fff\n"); - return AVERROR_INVALIDDATA; -} - -AVOutputFormat ff_latm_muxer = { - .name = "latm", - .long_name = NULL_IF_CONFIG_SMALL("LOAS/LATM"), - .mime_type = "audio/MP4A-LATM", - .extensions = "latm,loas", - .priv_data_size = sizeof(LATMContext), - .audio_codec = AV_CODEC_ID_AAC, - .video_codec = AV_CODEC_ID_NONE, - .write_header = latm_write_header, - .write_packet = latm_write_packet, - .priv_class = &latm_muxer_class, -}; diff --git a/ffmpeg1/libavformat/libavformat.pc b/ffmpeg1/libavformat/libavformat.pc deleted file mode 100644 index ec08118..0000000 --- a/ffmpeg1/libavformat/libavformat.pc +++ /dev/null @@ -1,14 +0,0 @@ -prefix=/usr/local -exec_prefix=${prefix} -libdir=${prefix}/lib -includedir=${prefix}/include - -Name: libavformat -Description: FFmpeg container format library -Version: 55.0.100 -Requires: -Requires.private: libavcodec = 55.1.100 -Conflicts: -Libs: -L${libdir} -lavformat -Libs.private: -ldl -lXfixes -lXext -lX11 -lxvidcore -lx264 -lvorbisenc -lvorbis -logg -ltheoraenc -ltheoradec -logg -lschroedinger-1.0 -lmp3lame -lfaac -lm -pthread -lz -Cflags: -I${includedir} diff --git a/ffmpeg1/libavformat/libavformat.v b/ffmpeg1/libavformat/libavformat.v deleted file mode 100644 index 0b47668..0000000 --- a/ffmpeg1/libavformat/libavformat.v +++ /dev/null @@ -1,37 +0,0 @@ -LIBAVFORMAT_$MAJOR { - global: av*; - #FIXME those are for ffserver - ff_inet_aton; - ff_socket_nonblock; - ffm_set_write_index; - ffm_read_write_index; - ffm_write_write_index; - ff_mpegts_parse_close; - ff_mpegts_parse_open; - ff_mpegts_parse_packet; - ff_rtsp_parse_line; - ff_rtp_get_local_rtp_port; - ff_rtp_get_local_rtcp_port; - ffio_open_dyn_packet_buf; - ffio_set_buf_size; - ffurl_close; - ffurl_open; - ffurl_read_complete; - ffurl_seek; - ffurl_size; - ffurl_write; - ffurl_protocol_next; - url_open; - url_close; - url_write; - #those are deprecated, remove on next bump - url_*; - ff_timefilter_destroy; - ff_timefilter_new; - ff_timefilter_update; - ff_timefilter_reset; - get_*; - put_*; - ff_codec_get_id; - local: *; -}; diff --git a/ffmpeg1/libavformat/libmodplug.c b/ffmpeg1/libavformat/libmodplug.c deleted file mode 100644 index aa8edcc..0000000 --- a/ffmpeg1/libavformat/libmodplug.c +++ /dev/null @@ -1,368 +0,0 @@ -/* - * 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 - */ - -/** -* @file -* ModPlug demuxer -* @todo better probing than extensions matching -*/ - -#include -#include "libavutil/avstring.h" -#include "libavutil/eval.h" -#include "libavutil/opt.h" -#include "avformat.h" -#include "internal.h" - -typedef struct ModPlugContext { - const AVClass *class; - ModPlugFile *f; - uint8_t *buf; ///< input file content - - /* options */ - int noise_reduction; - int reverb_depth; - int reverb_delay; - int bass_amount; - int bass_range; - int surround_depth; - int surround_delay; - - int max_size; ///< max file size to allocate - - /* optional video stream */ - double ts_per_packet; ///< used to define the pts/dts using packet_count; - int packet_count; ///< total number of audio packets - int print_textinfo; ///< bool flag for printing speed, tempo, order, ... - int video_stream; ///< 1 if the user want a video stream, otherwise 0 - int w; ///< video stream width in char (one char = 8x8px) - int h; ///< video stream height in char (one char = 8x8px) - int video_switch; ///< 1 if current packet is video, otherwise 0 - int fsize; ///< constant frame size - int linesize; ///< line size in bytes - char *color_eval; ///< color eval user input expression - AVExpr *expr; ///< parsed color eval expression -} ModPlugContext; - -static const char *var_names[] = { - "x", "y", - "w", "h", - "t", - "speed", "tempo", "order", "pattern", "row", - NULL -}; - -enum var_name { - VAR_X, VAR_Y, - VAR_W, VAR_H, - VAR_TIME, - VAR_SPEED, VAR_TEMPO, VAR_ORDER, VAR_PATTERN, VAR_ROW, - VAR_VARS_NB -}; - -#define FF_MODPLUG_MAX_FILE_SIZE (100 * 1<<20) // 100M -#define FF_MODPLUG_DEF_FILE_SIZE ( 5 * 1<<20) // 5M - -#define OFFSET(x) offsetof(ModPlugContext, x) -#define D AV_OPT_FLAG_DECODING_PARAM -static const AVOption options[] = { - {"noise_reduction", "Enable noise reduction 0(off)-1(on)", OFFSET(noise_reduction), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, D}, - {"reverb_depth", "Reverb level 0(quiet)-100(loud)", OFFSET(reverb_depth), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 100, D}, - {"reverb_delay", "Reverb delay in ms, usually 40-200ms", OFFSET(reverb_delay), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, D}, - {"bass_amount", "XBass level 0(quiet)-100(loud)", OFFSET(bass_amount), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 100, D}, - {"bass_range", "XBass cutoff in Hz 10-100", OFFSET(bass_range), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 100, D}, - {"surround_depth", "Surround level 0(quiet)-100(heavy)", OFFSET(surround_depth), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 100, D}, - {"surround_delay", "Surround delay in ms, usually 5-40ms", OFFSET(surround_delay), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, D}, - {"max_size", "Max file size supported (in bytes). Default is 5MB. Set to 0 for no limit (not recommended)", - OFFSET(max_size), AV_OPT_TYPE_INT, {.i64 = FF_MODPLUG_DEF_FILE_SIZE}, 0, FF_MODPLUG_MAX_FILE_SIZE, D}, - {"video_stream_expr", "Color formula", OFFSET(color_eval), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, D}, - {"video_stream", "Make demuxer output a video stream", OFFSET(video_stream), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, D}, - {"video_stream_w", "Video stream width in char (one char = 8x8px)", OFFSET(w), AV_OPT_TYPE_INT, {.i64 = 30}, 20, 512, D}, - {"video_stream_h", "Video stream height in char (one char = 8x8px)", OFFSET(h), AV_OPT_TYPE_INT, {.i64 = 30}, 20, 512, D}, - {"video_stream_ptxt", "Print speed, tempo, order, ... in video stream", OFFSET(print_textinfo), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, D}, - {NULL}, -}; - -#define SET_OPT_IF_REQUESTED(libopt, opt, flag) do { \ - if (modplug->opt) { \ - settings.libopt = modplug->opt; \ - settings.mFlags |= flag; \ - } \ -} while (0) - -#define ADD_META_MULTIPLE_ENTRIES(entry_name, fname) do { \ - if (n_## entry_name ##s) { \ - unsigned i, n = 0; \ - \ - for (i = 0; i < n_## entry_name ##s; i++) { \ - char item_name[64] = {0}; \ - fname(f, i, item_name); \ - if (!*item_name) \ - continue; \ - if (n) \ - av_dict_set(&s->metadata, #entry_name, "\n", AV_DICT_APPEND); \ - av_dict_set(&s->metadata, #entry_name, item_name, AV_DICT_APPEND); \ - n++; \ - } \ - \ - extra = av_asprintf(", %u/%u " #entry_name "%s", \ - n, n_## entry_name ##s, n > 1 ? "s" : ""); \ - if (!extra) \ - return AVERROR(ENOMEM); \ - av_dict_set(&s->metadata, "extra info", extra, AV_DICT_APPEND); \ - av_free(extra); \ - } \ -} while (0) - -static int modplug_load_metadata(AVFormatContext *s) -{ - ModPlugContext *modplug = s->priv_data; - ModPlugFile *f = modplug->f; - char *extra; - const char *name = ModPlug_GetName(f); - const char *msg = ModPlug_GetMessage(f); - - unsigned n_instruments = ModPlug_NumInstruments(f); - unsigned n_samples = ModPlug_NumSamples(f); - unsigned n_patterns = ModPlug_NumPatterns(f); - unsigned n_channels = ModPlug_NumChannels(f); - - if (name && *name) av_dict_set(&s->metadata, "name", name, 0); - if (msg && *msg) av_dict_set(&s->metadata, "message", msg, 0); - - extra = av_asprintf("%u pattern%s, %u channel%s", - n_patterns, n_patterns > 1 ? "s" : "", - n_channels, n_channels > 1 ? "s" : ""); - if (!extra) - return AVERROR(ENOMEM); - av_dict_set(&s->metadata, "extra info", extra, AV_DICT_DONT_STRDUP_VAL); - - ADD_META_MULTIPLE_ENTRIES(instrument, ModPlug_InstrumentName); - ADD_META_MULTIPLE_ENTRIES(sample, ModPlug_SampleName); - - return 0; -} - -#define AUDIO_PKT_SIZE 512 - -static int modplug_read_header(AVFormatContext *s) -{ - AVStream *st; - AVIOContext *pb = s->pb; - ModPlug_Settings settings; - ModPlugContext *modplug = s->priv_data; - int sz = avio_size(pb); - - if (sz < 0) { - av_log(s, AV_LOG_WARNING, "Could not determine file size\n"); - sz = modplug->max_size; - } else if (modplug->max_size && sz > modplug->max_size) { - sz = modplug->max_size; - av_log(s, AV_LOG_WARNING, "Max file size reach%s, allocating %dB " - "but demuxing is likely to fail due to incomplete buffer\n", - sz == FF_MODPLUG_DEF_FILE_SIZE ? " (see -max_size)" : "", sz); - } - - if (modplug->color_eval) { - int r = av_expr_parse(&modplug->expr, modplug->color_eval, var_names, - NULL, NULL, NULL, NULL, 0, s); - if (r < 0) - return r; - } - - modplug->buf = av_malloc(modplug->max_size); - if (!modplug->buf) - return AVERROR(ENOMEM); - sz = avio_read(pb, modplug->buf, sz); - - ModPlug_GetSettings(&settings); - settings.mChannels = 2; - settings.mBits = 16; - settings.mFrequency = 44100; - settings.mResamplingMode = MODPLUG_RESAMPLE_FIR; // best quality - settings.mLoopCount = 0; // prevents looping forever - - if (modplug->noise_reduction) settings.mFlags |= MODPLUG_ENABLE_NOISE_REDUCTION; - SET_OPT_IF_REQUESTED(mReverbDepth, reverb_depth, MODPLUG_ENABLE_REVERB); - SET_OPT_IF_REQUESTED(mReverbDelay, reverb_delay, MODPLUG_ENABLE_REVERB); - SET_OPT_IF_REQUESTED(mBassAmount, bass_amount, MODPLUG_ENABLE_MEGABASS); - SET_OPT_IF_REQUESTED(mBassRange, bass_range, MODPLUG_ENABLE_MEGABASS); - SET_OPT_IF_REQUESTED(mSurroundDepth, surround_depth, MODPLUG_ENABLE_SURROUND); - SET_OPT_IF_REQUESTED(mSurroundDelay, surround_delay, MODPLUG_ENABLE_SURROUND); - - if (modplug->reverb_depth) settings.mReverbDepth = modplug->reverb_depth; - if (modplug->reverb_delay) settings.mReverbDelay = modplug->reverb_delay; - if (modplug->bass_amount) settings.mBassAmount = modplug->bass_amount; - if (modplug->bass_range) settings.mBassRange = modplug->bass_range; - if (modplug->surround_depth) settings.mSurroundDepth = modplug->surround_depth; - if (modplug->surround_delay) settings.mSurroundDelay = modplug->surround_delay; - - ModPlug_SetSettings(&settings); - - modplug->f = ModPlug_Load(modplug->buf, sz); - if (!modplug->f) - return AVERROR_INVALIDDATA; - - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - avpriv_set_pts_info(st, 64, 1, 1000); - st->duration = ModPlug_GetLength(modplug->f); - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = AV_CODEC_ID_PCM_S16LE; - st->codec->channels = settings.mChannels; - st->codec->sample_rate = settings.mFrequency; - - // timebase = 1/1000, 2ch 16bits 44.1kHz-> 2*2*44100 - modplug->ts_per_packet = 1000*AUDIO_PKT_SIZE / (4*44100.); - - if (modplug->video_stream) { - AVStream *vst = avformat_new_stream(s, NULL); - if (!vst) - return AVERROR(ENOMEM); - avpriv_set_pts_info(vst, 64, 1, 1000); - vst->duration = st->duration; - vst->codec->codec_type = AVMEDIA_TYPE_VIDEO; - vst->codec->codec_id = AV_CODEC_ID_XBIN; - vst->codec->width = modplug->w << 3; - vst->codec->height = modplug->h << 3; - modplug->linesize = modplug->w * 3; - modplug->fsize = modplug->linesize * modplug->h; - } - - return modplug_load_metadata(s); -} - -static void write_text(uint8_t *dst, const char *s, int linesize, int x, int y) -{ - int i; - dst += y*linesize + x*3; - for (i = 0; s[i]; i++, dst += 3) { - dst[0] = 0x0; // count - 1 - dst[1] = s[i]; // char - dst[2] = 0x0f; // background / foreground - } -} - -#define PRINT_INFO(line, name, idvalue) do { \ - snprintf(intbuf, sizeof(intbuf), "%.0f", var_values[idvalue]); \ - write_text(pkt->data, name ":", modplug->linesize, 0+1, line+1); \ - write_text(pkt->data, intbuf, modplug->linesize, 10+1, line+1); \ -} while (0) - -static int modplug_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - ModPlugContext *modplug = s->priv_data; - - if (modplug->video_stream) { - modplug->video_switch ^= 1; // one video packet for one audio packet - if (modplug->video_switch) { - double var_values[VAR_VARS_NB]; - - var_values[VAR_W ] = modplug->w; - var_values[VAR_H ] = modplug->h; - var_values[VAR_TIME ] = modplug->packet_count * modplug->ts_per_packet; - var_values[VAR_SPEED ] = ModPlug_GetCurrentSpeed (modplug->f); - var_values[VAR_TEMPO ] = ModPlug_GetCurrentTempo (modplug->f); - var_values[VAR_ORDER ] = ModPlug_GetCurrentOrder (modplug->f); - var_values[VAR_PATTERN] = ModPlug_GetCurrentPattern(modplug->f); - var_values[VAR_ROW ] = ModPlug_GetCurrentRow (modplug->f); - - if (av_new_packet(pkt, modplug->fsize) < 0) - return AVERROR(ENOMEM); - pkt->stream_index = 1; - memset(pkt->data, 0, modplug->fsize); - - if (modplug->print_textinfo) { - char intbuf[32]; - PRINT_INFO(0, "speed", VAR_SPEED); - PRINT_INFO(1, "tempo", VAR_TEMPO); - PRINT_INFO(2, "order", VAR_ORDER); - PRINT_INFO(3, "pattern", VAR_PATTERN); - PRINT_INFO(4, "row", VAR_ROW); - PRINT_INFO(5, "ts", VAR_TIME); - } - - if (modplug->expr) { - int x, y; - for (y = 0; y < modplug->h; y++) { - for (x = 0; x < modplug->w; x++) { - double color; - var_values[VAR_X] = x; - var_values[VAR_Y] = y; - color = av_expr_eval(modplug->expr, var_values, NULL); - pkt->data[y*modplug->linesize + x*3 + 2] |= av_clip((int)color, 0, 0xf)<<4; - } - } - } - pkt->pts = pkt->dts = var_values[VAR_TIME]; - pkt->flags |= AV_PKT_FLAG_KEY; - return 0; - } - } - - if (av_new_packet(pkt, AUDIO_PKT_SIZE) < 0) - return AVERROR(ENOMEM); - - if (modplug->video_stream) - pkt->pts = pkt->dts = modplug->packet_count++ * modplug->ts_per_packet; - - pkt->size = ModPlug_Read(modplug->f, pkt->data, AUDIO_PKT_SIZE); - if (pkt->size <= 0) { - av_free_packet(pkt); - return pkt->size == 0 ? AVERROR_EOF : AVERROR(EIO); - } - return 0; -} - -static int modplug_read_close(AVFormatContext *s) -{ - ModPlugContext *modplug = s->priv_data; - ModPlug_Unload(modplug->f); - av_freep(&modplug->buf); - return 0; -} - -static int modplug_read_seek(AVFormatContext *s, int stream_idx, int64_t ts, int flags) -{ - ModPlugContext *modplug = s->priv_data; - ModPlug_Seek(modplug->f, (int)ts); - if (modplug->video_stream) - modplug->packet_count = ts / modplug->ts_per_packet; - return 0; -} - -static const AVClass modplug_class = { - .class_name = "ModPlug demuxer", - .item_name = av_default_item_name, - .option = options, - .version = LIBAVUTIL_VERSION_INT, -}; - -AVInputFormat ff_libmodplug_demuxer = { - .name = "libmodplug", - .long_name = NULL_IF_CONFIG_SMALL("ModPlug demuxer"), - .priv_data_size = sizeof(ModPlugContext), - .read_header = modplug_read_header, - .read_packet = modplug_read_packet, - .read_close = modplug_read_close, - .read_seek = modplug_read_seek, - .extensions = "669,abc,amf,ams,dbm,dmf,dsm,far,it,mdl,med,mid,mod,mt2,mtm,okt,psm,ptm,s3m,stm,ult,umx,xm" - ",itgz,itr,itz,mdgz,mdr,mdz,s3gz,s3r,s3z,xmgz,xmr,xmz", // compressed mods - .priv_class = &modplug_class, -}; diff --git a/ffmpeg1/libavformat/libnut.c b/ffmpeg1/libavformat/libnut.c deleted file mode 100644 index 838c55a..0000000 --- a/ffmpeg1/libavformat/libnut.c +++ /dev/null @@ -1,322 +0,0 @@ -/* - * NUT (de)muxing via libnut - * copyright (c) 2006 Oded Shimon - * - * 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 - */ - -/** - * @file - * NUT demuxing and muxing via libnut. - * @author Oded Shimon - */ - -#include "avformat.h" -#include "internal.h" -#include "riff.h" -#include - -#define ID_STRING "nut/multimedia container" -#define ID_LENGTH (strlen(ID_STRING) + 1) - -typedef struct { - nut_context_tt * nut; - nut_stream_header_tt * s; -} NUTContext; - -static const AVCodecTag nut_tags[] = { - { AV_CODEC_ID_MPEG4, MKTAG('m', 'p', '4', 'v') }, - { AV_CODEC_ID_MP3, MKTAG('m', 'p', '3', ' ') }, - { AV_CODEC_ID_VORBIS, MKTAG('v', 'r', 'b', 's') }, - { 0, 0 }, -}; - -#if CONFIG_LIBNUT_MUXER -static int av_write(void * h, size_t len, const uint8_t * buf) { - AVIOContext * bc = h; - avio_write(bc, buf, len); - //avio_flush(bc); - return len; -} - -static int nut_write_header(AVFormatContext * avf) { - NUTContext * priv = avf->priv_data; - AVIOContext * bc = avf->pb; - nut_muxer_opts_tt mopts = { - .output = { - .priv = bc, - .write = av_write, - }, - .alloc = { av_malloc, av_realloc, av_free }, - .write_index = 1, - .realtime_stream = 0, - .max_distance = 32768, - .fti = NULL, - }; - nut_stream_header_tt * s; - int i; - - priv->s = s = av_mallocz((avf->nb_streams + 1) * sizeof*s); - if(!s) - return AVERROR(ENOMEM); - - for (i = 0; i < avf->nb_streams; i++) { - AVCodecContext * codec = avf->streams[i]->codec; - int j; - int fourcc = 0; - int num, denom, ssize; - - s[i].type = codec->codec_type == AVMEDIA_TYPE_VIDEO ? NUT_VIDEO_CLASS : NUT_AUDIO_CLASS; - - if (codec->codec_tag) fourcc = codec->codec_tag; - else fourcc = ff_codec_get_tag(nut_tags, codec->codec_id); - - if (!fourcc) { - if (codec->codec_type == AVMEDIA_TYPE_VIDEO) fourcc = ff_codec_get_tag(ff_codec_bmp_tags, codec->codec_id); - if (codec->codec_type == AVMEDIA_TYPE_AUDIO) fourcc = ff_codec_get_tag(ff_codec_wav_tags, codec->codec_id); - } - - s[i].fourcc_len = 4; - s[i].fourcc = av_malloc(s[i].fourcc_len); - for (j = 0; j < s[i].fourcc_len; j++) s[i].fourcc[j] = (fourcc >> (j*8)) & 0xFF; - - ff_parse_specific_params(codec, &num, &ssize, &denom); - avpriv_set_pts_info(avf->streams[i], 60, denom, num); - - s[i].time_base.num = denom; - s[i].time_base.den = num; - - s[i].fixed_fps = 0; - s[i].decode_delay = codec->has_b_frames; - s[i].codec_specific_len = codec->extradata_size; - s[i].codec_specific = codec->extradata; - - if (codec->codec_type == AVMEDIA_TYPE_VIDEO) { - s[i].width = codec->width; - s[i].height = codec->height; - s[i].sample_width = 0; - s[i].sample_height = 0; - s[i].colorspace_type = 0; - } else { - s[i].samplerate_num = codec->sample_rate; - s[i].samplerate_denom = 1; - s[i].channel_count = codec->channels; - } - } - - s[avf->nb_streams].type = -1; - priv->nut = nut_muxer_init(&mopts, s, NULL); - - return 0; -} - -static int nut_write_packet(AVFormatContext * avf, AVPacket * pkt) { - NUTContext * priv = avf->priv_data; - nut_packet_tt p; - - p.len = pkt->size; - p.stream = pkt->stream_index; - p.pts = pkt->pts; - p.flags = pkt->flags & AV_PKT_FLAG_KEY ? NUT_FLAG_KEY : 0; - p.next_pts = 0; - - nut_write_frame_reorder(priv->nut, &p, pkt->data); - - return 0; -} - -static int nut_write_trailer(AVFormatContext * avf) { - AVIOContext * bc = avf->pb; - NUTContext * priv = avf->priv_data; - int i; - - nut_muxer_uninit_reorder(priv->nut); - avio_flush(bc); - - for(i = 0; priv->s[i].type != -1; i++ ) av_freep(&priv->s[i].fourcc); - av_freep(&priv->s); - - return 0; -} - -AVOutputFormat ff_libnut_muxer = { - .name = "libnut", - .long_name = "nut format", - .mime_type = "video/x-nut", - .extensions = "nut", - .priv_data_size = sizeof(NUTContext), - .audio_codec = AV_CODEC_ID_VORBIS, - .video_codec = AV_CODEC_ID_MPEG4, - .write_header = nut_write_header, - .write_packet = nut_write_packet, - .write_trailer = nut_write_trailer, - .flags = AVFMT_GLOBALHEADER, -}; -#endif /* CONFIG_LIBNUT_MUXER */ - -static int nut_probe(AVProbeData *p) { - if (!memcmp(p->buf, ID_STRING, ID_LENGTH)) return AVPROBE_SCORE_MAX; - - return 0; -} - -static size_t av_read(void * h, size_t len, uint8_t * buf) { - AVIOContext * bc = h; - return avio_read(bc, buf, len); -} - -static off_t av_seek(void * h, long long pos, int whence) { - AVIOContext * bc = h; - if (whence == SEEK_END) { - pos = avio_size(bc) + pos; - whence = SEEK_SET; - } - return avio_seek(bc, pos, whence); -} - -static int nut_read_header(AVFormatContext * avf) { - NUTContext * priv = avf->priv_data; - AVIOContext * bc = avf->pb; - nut_demuxer_opts_tt dopts = { - .input = { - .priv = bc, - .seek = av_seek, - .read = av_read, - .eof = NULL, - .file_pos = 0, - }, - .alloc = { av_malloc, av_realloc, av_free }, - .read_index = 1, - .cache_syncpoints = 1, - }; - nut_context_tt * nut = priv->nut = nut_demuxer_init(&dopts); - nut_stream_header_tt * s; - int ret, i; - - if(!nut) - return -1; - - if ((ret = nut_read_headers(nut, &s, NULL))) { - av_log(avf, AV_LOG_ERROR, " NUT error: %s\n", nut_error(ret)); - nut_demuxer_uninit(nut); - priv->nut = NULL; - return -1; - } - - priv->s = s; - - for (i = 0; s[i].type != -1 && i < 2; i++) { - AVStream * st = avformat_new_stream(avf, NULL); - int j; - - for (j = 0; j < s[i].fourcc_len && j < 8; j++) st->codec->codec_tag |= s[i].fourcc[j]<<(j*8); - - st->codec->has_b_frames = s[i].decode_delay; - - st->codec->extradata_size = s[i].codec_specific_len; - if (st->codec->extradata_size) { - st->codec->extradata = av_mallocz(st->codec->extradata_size); - if(!st->codec->extradata){ - nut_demuxer_uninit(nut); - priv->nut = NULL; - return AVERROR(ENOMEM); - } - memcpy(st->codec->extradata, s[i].codec_specific, st->codec->extradata_size); - } - - avpriv_set_pts_info(avf->streams[i], 60, s[i].time_base.num, s[i].time_base.den); - st->start_time = 0; - st->duration = s[i].max_pts; - - st->codec->codec_id = ff_codec_get_id(nut_tags, st->codec->codec_tag); - - switch(s[i].type) { - case NUT_AUDIO_CLASS: - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - if (st->codec->codec_id == AV_CODEC_ID_NONE) st->codec->codec_id = ff_codec_get_id(ff_codec_wav_tags, st->codec->codec_tag); - - st->codec->channels = s[i].channel_count; - st->codec->sample_rate = s[i].samplerate_num / s[i].samplerate_denom; - break; - case NUT_VIDEO_CLASS: - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - if (st->codec->codec_id == AV_CODEC_ID_NONE) st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, st->codec->codec_tag); - - st->codec->width = s[i].width; - st->codec->height = s[i].height; - st->sample_aspect_ratio.num = s[i].sample_width; - st->sample_aspect_ratio.den = s[i].sample_height; - break; - } - if (st->codec->codec_id == AV_CODEC_ID_NONE) av_log(avf, AV_LOG_ERROR, "Unknown codec?!\n"); - } - - return 0; -} - -static int nut_read_packet(AVFormatContext * avf, AVPacket * pkt) { - NUTContext * priv = avf->priv_data; - nut_packet_tt pd; - int ret; - - ret = nut_read_next_packet(priv->nut, &pd); - - if (ret || av_new_packet(pkt, pd.len) < 0) { - if (ret != NUT_ERR_EOF) - av_log(avf, AV_LOG_ERROR, " NUT error: %s\n", nut_error(ret)); - return -1; - } - - if (pd.flags & NUT_FLAG_KEY) pkt->flags |= AV_PKT_FLAG_KEY; - pkt->pts = pd.pts; - pkt->stream_index = pd.stream; - pkt->pos = avio_tell(avf->pb); - - ret = nut_read_frame(priv->nut, &pd.len, pkt->data); - - return ret; -} - -static int nut_read_seek(AVFormatContext * avf, int stream_index, int64_t target_ts, int flags) { - NUTContext * priv = avf->priv_data; - int active_streams[] = { stream_index, -1 }; - double time_pos = target_ts * priv->s[stream_index].time_base.num / (double)priv->s[stream_index].time_base.den; - - if (nut_seek(priv->nut, time_pos, 2*!(flags & AVSEEK_FLAG_BACKWARD), active_streams)) return -1; - - return 0; -} - -static int nut_read_close(AVFormatContext *s) { - NUTContext * priv = s->priv_data; - - nut_demuxer_uninit(priv->nut); - - return 0; -} - -AVInputFormat ff_libnut_demuxer = { - .name = "libnut", - .long_name = NULL_IF_CONFIG_SMALL("NUT format"), - .priv_data_size = sizeof(NUTContext), - .read_probe = nut_probe, - .read_header = nut_read_header, - .read_packet = nut_read_packet, - .read_close = nut_read_close, - .read_seek = nut_read_seek, - .extensions = "nut", -}; diff --git a/ffmpeg1/libavformat/librtmp.c b/ffmpeg1/libavformat/librtmp.c deleted file mode 100644 index 5b4c39d..0000000 --- a/ffmpeg1/libavformat/librtmp.c +++ /dev/null @@ -1,283 +0,0 @@ -/* - * RTMP network protocol - * Copyright (c) 2010 Howard Chu - * - * 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 - */ - -/** - * @file - * RTMP protocol based on http://rtmpdump.mplayerhq.hu/ librtmp - */ - -#include "libavutil/avstring.h" -#include "libavutil/mathematics.h" -#include "libavutil/opt.h" -#include "avformat.h" -#include "url.h" - -#include -#include - -typedef struct LibRTMPContext { - const AVClass *class; - RTMP rtmp; - char *app; - char *playpath; -} LibRTMPContext; - -static void rtmp_log(int level, const char *fmt, va_list args) -{ - switch (level) { - default: - case RTMP_LOGCRIT: level = AV_LOG_FATAL; break; - case RTMP_LOGERROR: level = AV_LOG_ERROR; break; - case RTMP_LOGWARNING: level = AV_LOG_WARNING; break; - case RTMP_LOGINFO: level = AV_LOG_INFO; break; - case RTMP_LOGDEBUG: level = AV_LOG_VERBOSE; break; - case RTMP_LOGDEBUG2: level = AV_LOG_DEBUG; break; - } - - av_vlog(NULL, level, fmt, args); - av_log(NULL, level, "\n"); -} - -static int rtmp_close(URLContext *s) -{ - LibRTMPContext *ctx = s->priv_data; - RTMP *r = &ctx->rtmp; - - RTMP_Close(r); - return 0; -} - -/** - * Open RTMP connection and verify that the stream can be played. - * - * URL syntax: rtmp://server[:port][/app][/playpath][ keyword=value]... - * where 'app' is first one or two directories in the path - * (e.g. /ondemand/, /flash/live/, etc.) - * and 'playpath' is a file name (the rest of the path, - * may be prefixed with "mp4:") - * - * Additional RTMP library options may be appended as - * space-separated key-value pairs. - */ -static int rtmp_open(URLContext *s, const char *uri, int flags) -{ - LibRTMPContext *ctx = s->priv_data; - RTMP *r = &ctx->rtmp; - int rc = 0, level; - char *filename = s->filename; - - switch (av_log_get_level()) { - default: - case AV_LOG_FATAL: level = RTMP_LOGCRIT; break; - case AV_LOG_ERROR: level = RTMP_LOGERROR; break; - case AV_LOG_WARNING: level = RTMP_LOGWARNING; break; - case AV_LOG_INFO: level = RTMP_LOGINFO; break; - case AV_LOG_VERBOSE: level = RTMP_LOGDEBUG; break; - case AV_LOG_DEBUG: level = RTMP_LOGDEBUG2; break; - } - RTMP_LogSetLevel(level); - RTMP_LogSetCallback(rtmp_log); - - if (ctx->app || ctx->playpath) { - int len = strlen(s->filename) + 1; - if (ctx->app) len += strlen(ctx->app) + sizeof(" app="); - if (ctx->playpath) len += strlen(ctx->playpath) + sizeof(" playpath="); - - if (!(filename = av_malloc(len))) - return AVERROR(ENOMEM); - - av_strlcpy(filename, s->filename, len); - if (ctx->app) { - av_strlcat(filename, " app=", len); - av_strlcat(filename, ctx->app, len); - } - if (ctx->playpath) { - av_strlcat(filename, " playpath=", len); - av_strlcat(filename, ctx->playpath, len); - } - } - - RTMP_Init(r); - if (!RTMP_SetupURL(r, filename)) { - rc = AVERROR_UNKNOWN; - goto fail; - } - - if (flags & AVIO_FLAG_WRITE) - RTMP_EnableWrite(r); - - if (!RTMP_Connect(r, NULL) || !RTMP_ConnectStream(r, 0)) { - rc = AVERROR_UNKNOWN; - goto fail; - } - - s->is_streamed = 1; - rc = 0; -fail: - if (filename != s->filename) - av_freep(&filename); - return rc; -} - -static int rtmp_write(URLContext *s, const uint8_t *buf, int size) -{ - LibRTMPContext *ctx = s->priv_data; - RTMP *r = &ctx->rtmp; - - return RTMP_Write(r, buf, size); -} - -static int rtmp_read(URLContext *s, uint8_t *buf, int size) -{ - LibRTMPContext *ctx = s->priv_data; - RTMP *r = &ctx->rtmp; - - return RTMP_Read(r, buf, size); -} - -static int rtmp_read_pause(URLContext *s, int pause) -{ - LibRTMPContext *ctx = s->priv_data; - RTMP *r = &ctx->rtmp; - - if (!RTMP_Pause(r, pause)) - return AVERROR_UNKNOWN; - return 0; -} - -static int64_t rtmp_read_seek(URLContext *s, int stream_index, - int64_t timestamp, int flags) -{ - LibRTMPContext *ctx = s->priv_data; - RTMP *r = &ctx->rtmp; - - if (flags & AVSEEK_FLAG_BYTE) - return AVERROR(ENOSYS); - - /* seeks are in milliseconds */ - if (stream_index < 0) - timestamp = av_rescale_rnd(timestamp, 1000, AV_TIME_BASE, - flags & AVSEEK_FLAG_BACKWARD ? AV_ROUND_DOWN : AV_ROUND_UP); - - if (!RTMP_SendSeek(r, timestamp)) - return AVERROR_UNKNOWN; - return timestamp; -} - -static int rtmp_get_file_handle(URLContext *s) -{ - LibRTMPContext *ctx = s->priv_data; - RTMP *r = &ctx->rtmp; - - return RTMP_Socket(r); -} - -#define OFFSET(x) offsetof(LibRTMPContext, x) -#define DEC AV_OPT_FLAG_DECODING_PARAM -#define ENC AV_OPT_FLAG_ENCODING_PARAM -static const AVOption options[] = { - {"rtmp_app", "Name of application to connect to on the RTMP server", OFFSET(app), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC}, - {"rtmp_playpath", "Stream identifier to play or to publish", OFFSET(playpath), AV_OPT_TYPE_STRING, {.str = NULL }, 0, 0, DEC|ENC}, - { NULL }, -}; - -#define RTMP_CLASS(flavor)\ -static const AVClass lib ## flavor ## _class = {\ - .class_name = "lib" #flavor " protocol",\ - .item_name = av_default_item_name,\ - .option = options,\ - .version = LIBAVUTIL_VERSION_INT,\ -}; - -RTMP_CLASS(rtmp) -URLProtocol ff_librtmp_protocol = { - .name = "rtmp", - .url_open = rtmp_open, - .url_read = rtmp_read, - .url_write = rtmp_write, - .url_close = rtmp_close, - .url_read_pause = rtmp_read_pause, - .url_read_seek = rtmp_read_seek, - .url_get_file_handle = rtmp_get_file_handle, - .priv_data_size = sizeof(LibRTMPContext), - .priv_data_class = &librtmp_class, - .flags = URL_PROTOCOL_FLAG_NETWORK, -}; - -RTMP_CLASS(rtmpt) -URLProtocol ff_librtmpt_protocol = { - .name = "rtmpt", - .url_open = rtmp_open, - .url_read = rtmp_read, - .url_write = rtmp_write, - .url_close = rtmp_close, - .url_read_pause = rtmp_read_pause, - .url_read_seek = rtmp_read_seek, - .url_get_file_handle = rtmp_get_file_handle, - .priv_data_size = sizeof(LibRTMPContext), - .priv_data_class = &librtmpt_class, - .flags = URL_PROTOCOL_FLAG_NETWORK, -}; - -RTMP_CLASS(rtmpe) -URLProtocol ff_librtmpe_protocol = { - .name = "rtmpe", - .url_open = rtmp_open, - .url_read = rtmp_read, - .url_write = rtmp_write, - .url_close = rtmp_close, - .url_read_pause = rtmp_read_pause, - .url_read_seek = rtmp_read_seek, - .url_get_file_handle = rtmp_get_file_handle, - .priv_data_size = sizeof(LibRTMPContext), - .priv_data_class = &librtmpe_class, - .flags = URL_PROTOCOL_FLAG_NETWORK, -}; - -RTMP_CLASS(rtmpte) -URLProtocol ff_librtmpte_protocol = { - .name = "rtmpte", - .url_open = rtmp_open, - .url_read = rtmp_read, - .url_write = rtmp_write, - .url_close = rtmp_close, - .url_read_pause = rtmp_read_pause, - .url_read_seek = rtmp_read_seek, - .url_get_file_handle = rtmp_get_file_handle, - .priv_data_size = sizeof(LibRTMPContext), - .priv_data_class = &librtmpte_class, - .flags = URL_PROTOCOL_FLAG_NETWORK, -}; - -RTMP_CLASS(rtmps) -URLProtocol ff_librtmps_protocol = { - .name = "rtmps", - .url_open = rtmp_open, - .url_read = rtmp_read, - .url_write = rtmp_write, - .url_close = rtmp_close, - .url_read_pause = rtmp_read_pause, - .url_read_seek = rtmp_read_seek, - .url_get_file_handle = rtmp_get_file_handle, - .priv_data_size = sizeof(LibRTMPContext), - .priv_data_class = &librtmps_class, - .flags = URL_PROTOCOL_FLAG_NETWORK, -}; diff --git a/ffmpeg1/libavformat/lmlm4.c b/ffmpeg1/libavformat/lmlm4.c deleted file mode 100644 index c8ea421..0000000 --- a/ffmpeg1/libavformat/lmlm4.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Linux Media Labs MPEG-4 demuxer - * Copyright (c) 2008 Ivo van Poorten - * - * Due to a lack of sample files, only files with one channel are supported. - * u-law and ADPCM audio are unsupported for the same reason. - * - * 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 "libavutil/intreadwrite.h" -#include "avformat.h" -#include "internal.h" - -#define LMLM4_I_FRAME 0x00 -#define LMLM4_P_FRAME 0x01 -#define LMLM4_B_FRAME 0x02 -#define LMLM4_INVALID 0x03 -#define LMLM4_MPEG1L2 0x04 - -#define LMLM4_MAX_PACKET_SIZE 1024 * 1024 - -static int lmlm4_probe(AVProbeData * pd) { - const unsigned char *buf = pd->buf; - unsigned int frame_type, packet_size; - - frame_type = AV_RB16(buf+2); - packet_size = AV_RB32(buf+4); - - if (!AV_RB16(buf) && frame_type <= LMLM4_MPEG1L2 && packet_size && - frame_type != LMLM4_INVALID && packet_size <= LMLM4_MAX_PACKET_SIZE) { - - if (frame_type == LMLM4_MPEG1L2) { - if ((AV_RB16(buf+8) & 0xfffe) != 0xfffc) - return 0; - /* I could calculate the audio framesize and compare with - * packet_size-8, but that seems overkill */ - return AVPROBE_SCORE_MAX / 3; - } else if (AV_RB24(buf+8) == 0x000001) { /* PES Signal */ - return AVPROBE_SCORE_MAX / 5; - } - } - - return 0; -} - -static int lmlm4_read_header(AVFormatContext *s) { - AVStream *st; - - if (!(st = avformat_new_stream(s, NULL))) - return AVERROR(ENOMEM); - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = AV_CODEC_ID_MPEG4; - st->need_parsing = AVSTREAM_PARSE_HEADERS; - avpriv_set_pts_info(st, 64, 1001, 30000); - - if (!(st = avformat_new_stream(s, NULL))) - return AVERROR(ENOMEM); - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = AV_CODEC_ID_MP2; - st->need_parsing = AVSTREAM_PARSE_HEADERS; - - /* the parameters will be extracted from the compressed bitstream */ - return 0; -} - -static int lmlm4_read_packet(AVFormatContext *s, AVPacket *pkt) { - AVIOContext *pb = s->pb; - int ret; - unsigned int frame_type, packet_size, padding, frame_size; - - avio_rb16(pb); /* channel number */ - frame_type = avio_rb16(pb); - packet_size = avio_rb32(pb); - padding = -packet_size & 511; - frame_size = packet_size - 8; - - if (frame_type > LMLM4_MPEG1L2 || frame_type == LMLM4_INVALID) { - av_log(s, AV_LOG_ERROR, "invalid or unsupported frame_type\n"); - return AVERROR(EIO); - } - if (packet_size > LMLM4_MAX_PACKET_SIZE || packet_size<=8) { - av_log(s, AV_LOG_ERROR, "packet size %d is invalid\n", packet_size); - return AVERROR(EIO); - } - - if ((ret = av_get_packet(pb, pkt, frame_size)) <= 0) - return AVERROR(EIO); - - avio_skip(pb, padding); - - switch (frame_type) { - case LMLM4_I_FRAME: - pkt->flags = AV_PKT_FLAG_KEY; - case LMLM4_P_FRAME: - case LMLM4_B_FRAME: - pkt->stream_index = 0; - break; - case LMLM4_MPEG1L2: - pkt->stream_index = 1; - break; - } - - return ret; -} - -AVInputFormat ff_lmlm4_demuxer = { - .name = "lmlm4", - .long_name = NULL_IF_CONFIG_SMALL("raw lmlm4"), - .read_probe = lmlm4_probe, - .read_header = lmlm4_read_header, - .read_packet = lmlm4_read_packet, -}; diff --git a/ffmpeg1/libavformat/loasdec.c b/ffmpeg1/libavformat/loasdec.c deleted file mode 100644 index d3a8dbd..0000000 --- a/ffmpeg1/libavformat/loasdec.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * LOAS AudioSyncStream demuxer - * Copyright (c) 2008 Michael Niedermayer - * - * 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 "libavutil/intreadwrite.h" -#include "libavutil/internal.h" -#include "avformat.h" -#include "internal.h" -#include "rawdec.h" - -static int loas_probe(AVProbeData *p) -{ - int max_frames = 0, first_frames = 0; - int fsize, frames; - const uint8_t *buf0 = p->buf; - const uint8_t *buf2; - const uint8_t *buf; - const uint8_t *end = buf0 + p->buf_size - 3; - buf = buf0; - - for(; buf < end; buf= buf2+1) { - buf2 = buf; - - for(frames = 0; buf2 < end; frames++) { - uint32_t header = AV_RB24(buf2); - if((header >> 13) != 0x2B7) - break; - fsize = (header & 0x1FFF) + 3; - if(fsize < 7) - break; - fsize = FFMIN(fsize, end - buf2); - buf2 += fsize; - } - max_frames = FFMAX(max_frames, frames); - if(buf == buf0) - first_frames= frames; - } - if (first_frames>=3) return AVPROBE_SCORE_MAX/2+1; - else if(max_frames>100)return AVPROBE_SCORE_MAX/2; - else if(max_frames>=3) return AVPROBE_SCORE_MAX/4; - else return 0; -} - -static int loas_read_header(AVFormatContext *s) -{ - AVStream *st; - - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = s->iformat->raw_codec_id; - st->need_parsing = AVSTREAM_PARSE_FULL_RAW; - - //LCM of all possible AAC sample rates - avpriv_set_pts_info(st, 64, 1, 28224000); - - return 0; -} - -AVInputFormat ff_loas_demuxer = { - .name = "loas", - .long_name = NULL_IF_CONFIG_SMALL("LOAS AudioSyncStream"), - .read_probe = loas_probe, - .read_header = loas_read_header, - .read_packet = ff_raw_read_partial_packet, - .flags= AVFMT_GENERIC_INDEX, - .raw_codec_id = AV_CODEC_ID_AAC_LATM, -}; diff --git a/ffmpeg1/libavformat/log2_tab.c b/ffmpeg1/libavformat/log2_tab.c deleted file mode 100644 index 47a1df0..0000000 --- a/ffmpeg1/libavformat/log2_tab.c +++ /dev/null @@ -1 +0,0 @@ -#include "libavutil/log2_tab.c" diff --git a/ffmpeg1/libavformat/lvfdec.c b/ffmpeg1/libavformat/lvfdec.c deleted file mode 100644 index f8dda58..0000000 --- a/ffmpeg1/libavformat/lvfdec.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * LVF demuxer - * Copyright (c) 2012 Paul B Mahol - * - * 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 "libavutil/intreadwrite.h" -#include "avformat.h" -#include "riff.h" - -static int lvf_probe(AVProbeData *p) -{ - if (AV_RL32(p->buf) == MKTAG('L', 'V', 'F', 'F')) - return AVPROBE_SCORE_MAX / 2; - return 0; -} - -static int lvf_read_header(AVFormatContext *s) -{ - AVStream *st; - int64_t next_offset; - unsigned size, nb_streams, id; - - avio_skip(s->pb, 16); - nb_streams = avio_rl32(s->pb); - if (!nb_streams) - return AVERROR_INVALIDDATA; - if (nb_streams > 2) { - avpriv_request_sample(s, "%d streams", nb_streams); - return AVERROR_PATCHWELCOME; - } - - avio_skip(s->pb, 1012); - - while (!url_feof(s->pb)) { - id = avio_rl32(s->pb); - size = avio_rl32(s->pb); - next_offset = avio_tell(s->pb) + size; - - switch (id) { - case MKTAG('0', '0', 'f', 'm'): - st = avformat_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - avio_skip(s->pb, 4); - st->codec->width = avio_rl32(s->pb); - st->codec->height = avio_rl32(s->pb); - avio_skip(s->pb, 4); - st->codec->codec_tag = avio_rl32(s->pb); - st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, - st->codec->codec_tag); - avpriv_set_pts_info(st, 32, 1, 1000); - break; - case MKTAG('0', '1', 'f', 'm'): - st = avformat_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_tag = avio_rl16(s->pb); - st->codec->channels = avio_rl16(s->pb); - st->codec->sample_rate = avio_rl16(s->pb); - avio_skip(s->pb, 8); - st->codec->bits_per_coded_sample = avio_r8(s->pb); - st->codec->codec_id = ff_codec_get_id(ff_codec_wav_tags, - st->codec->codec_tag); - avpriv_set_pts_info(st, 32, 1, 1000); - break; - case 0: - avio_seek(s->pb, 2048 + 8, SEEK_SET); - return 0; - default: - avpriv_request_sample(s, "id %d", id); - return AVERROR_PATCHWELCOME; - } - - avio_seek(s->pb, next_offset, SEEK_SET); - } - - return AVERROR_EOF; -} - -static int lvf_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - unsigned size, flags, timestamp, id; - int64_t pos; - int ret, is_video = 0; - - pos = avio_tell(s->pb); - while (!url_feof(s->pb)) { - id = avio_rl32(s->pb); - size = avio_rl32(s->pb); - - if (size == 0xFFFFFFFFu) - return AVERROR_EOF; - - switch (id) { - case MKTAG('0', '0', 'd', 'c'): - is_video = 1; - case MKTAG('0', '1', 'w', 'b'): - if (size < 8) - return AVERROR_INVALIDDATA; - timestamp = avio_rl32(s->pb); - flags = avio_rl32(s->pb); - ret = av_get_packet(s->pb, pkt, size - 8); - if (flags & (1 << 12)) - pkt->flags |= AV_PKT_FLAG_KEY; - pkt->stream_index = is_video ? 0 : 1; - pkt->pts = timestamp; - pkt->pos = pos; - return ret; - default: - ret = avio_skip(s->pb, size); - } - - if (ret < 0) - return ret; - } - - return AVERROR_EOF; -} - -AVInputFormat ff_lvf_demuxer = { - .name = "lvf", - .long_name = NULL_IF_CONFIG_SMALL("LVF"), - .read_probe = lvf_probe, - .read_header = lvf_read_header, - .read_packet = lvf_read_packet, - .extensions = "lvf", - .flags = AVFMT_GENERIC_INDEX, -}; diff --git a/ffmpeg1/libavformat/lxfdec.c b/ffmpeg1/libavformat/lxfdec.c deleted file mode 100644 index 876f988..0000000 --- a/ffmpeg1/libavformat/lxfdec.c +++ /dev/null @@ -1,348 +0,0 @@ -/* - * LXF demuxer - * Copyright (c) 2010 Tomas Härdin - * - * 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 "libavutil/intreadwrite.h" -#include "libavcodec/bytestream.h" -#include "avformat.h" -#include "internal.h" - -#define LXF_MAX_PACKET_HEADER_SIZE 256 -#define LXF_HEADER_DATA_SIZE 120 -#define LXF_IDENT "LEITCH\0" -#define LXF_IDENT_LENGTH 8 -#define LXF_SAMPLERATE 48000 -#define LXF_MAX_AUDIO_PACKET (8008*15*4) ///< 15-channel 32-bit NTSC audio frame - -static const AVCodecTag lxf_tags[] = { - { AV_CODEC_ID_MJPEG, 0 }, - { AV_CODEC_ID_MPEG1VIDEO, 1 }, - { AV_CODEC_ID_MPEG2VIDEO, 2 }, //MpMl, 4:2:0 - { AV_CODEC_ID_MPEG2VIDEO, 3 }, //MpPl, 4:2:2 - { AV_CODEC_ID_DVVIDEO, 4 }, //DV25 - { AV_CODEC_ID_DVVIDEO, 5 }, //DVCPRO - { AV_CODEC_ID_DVVIDEO, 6 }, //DVCPRO50 - { AV_CODEC_ID_RAWVIDEO, 7 }, //AV_PIX_FMT_ARGB, where alpha is used for chroma keying - { AV_CODEC_ID_RAWVIDEO, 8 }, //16-bit chroma key - { AV_CODEC_ID_MPEG2VIDEO, 9 }, //4:2:2 CBP ("Constrained Bytes per Gop") - { AV_CODEC_ID_NONE, 0 }, -}; - -typedef struct { - int channels; ///< number of audio channels. zero means no audio - int frame_number; ///< current video frame - uint32_t video_format, packet_type, extended_size; -} LXFDemuxContext; - -static int lxf_probe(AVProbeData *p) -{ - if (!memcmp(p->buf, LXF_IDENT, LXF_IDENT_LENGTH)) - return AVPROBE_SCORE_MAX; - - return 0; -} - -/** - * Verify the checksum of an LXF packet header - * - * @param[in] header the packet header to check - * @return zero if the checksum is OK, non-zero otherwise - */ -static int check_checksum(const uint8_t *header, int size) -{ - int x; - uint32_t sum = 0; - - for (x = 0; x < size; x += 4) - sum += AV_RL32(&header[x]); - - return sum; -} - -/** - * Read input until we find the next ident. If found, copy it to the header buffer - * - * @param[out] header where to copy the ident to - * @return 0 if an ident was found, < 0 on I/O error - */ -static int sync(AVFormatContext *s, uint8_t *header) -{ - uint8_t buf[LXF_IDENT_LENGTH]; - int ret; - - if ((ret = avio_read(s->pb, buf, LXF_IDENT_LENGTH)) != LXF_IDENT_LENGTH) - return ret < 0 ? ret : AVERROR_EOF; - - while (memcmp(buf, LXF_IDENT, LXF_IDENT_LENGTH)) { - if (url_feof(s->pb)) - return AVERROR_EOF; - - memmove(buf, &buf[1], LXF_IDENT_LENGTH-1); - buf[LXF_IDENT_LENGTH-1] = avio_r8(s->pb); - } - - memcpy(header, LXF_IDENT, LXF_IDENT_LENGTH); - - return 0; -} - -/** - * Read and checksum the next packet header - * - * @return the size of the payload following the header or < 0 on failure - */ -static int get_packet_header(AVFormatContext *s) -{ - LXFDemuxContext *lxf = s->priv_data; - AVIOContext *pb = s->pb; - int track_size, samples, ret; - uint32_t version, audio_format, header_size, channels, tmp; - AVStream *st; - uint8_t header[LXF_MAX_PACKET_HEADER_SIZE]; - const uint8_t *p; - - //find and read the ident - if ((ret = sync(s, header)) < 0) - return ret; - - ret = avio_read(pb, header + LXF_IDENT_LENGTH, 8); - if (ret != 8) - return ret < 0 ? ret : AVERROR_EOF; - - p = header + LXF_IDENT_LENGTH; - version = bytestream_get_le32(&p); - header_size = bytestream_get_le32(&p); - if (version > 1) - avpriv_request_sample(s, "format version %i", version); - if (header_size < (version ? 72 : 60) || - header_size > LXF_MAX_PACKET_HEADER_SIZE || - (header_size & 3)) { - av_log(s, AV_LOG_ERROR, "Invalid header size 0x%x\n", header_size); - return AVERROR_INVALIDDATA; - } - - //read the rest of the packet header - if ((ret = avio_read(pb, header + (p - header), - header_size - (p - header))) != - header_size - (p - header)) { - return ret < 0 ? ret : AVERROR_EOF; - } - - if (check_checksum(header, header_size)) - av_log(s, AV_LOG_ERROR, "checksum error\n"); - - lxf->packet_type = bytestream_get_le32(&p); - p += version ? 20 : 12; - - lxf->extended_size = 0; - switch (lxf->packet_type) { - case 0: - //video - lxf->video_format = bytestream_get_le32(&p); - ret = bytestream_get_le32(&p); - //skip VBI data and metadata - avio_skip(pb, (int64_t)(uint32_t)AV_RL32(p + 4) + - (int64_t)(uint32_t)AV_RL32(p + 12)); - break; - case 1: - //audio - if (!s->streams || !(st = s->streams[1])) { - av_log(s, AV_LOG_INFO, "got audio packet, but no audio stream present\n"); - break; - } - - if (version == 0) p += 8; - audio_format = bytestream_get_le32(&p); - channels = bytestream_get_le32(&p); - track_size = bytestream_get_le32(&p); - - //set codec based on specified audio bitdepth - //we only support tightly packed 16-, 20-, 24- and 32-bit PCM at the moment - st->codec->bits_per_coded_sample = (audio_format >> 6) & 0x3F; - - if (st->codec->bits_per_coded_sample != (audio_format & 0x3F)) { - av_log(s, AV_LOG_WARNING, "only tightly packed PCM currently supported\n"); - return AVERROR_PATCHWELCOME; - } - - switch (st->codec->bits_per_coded_sample) { - case 16: st->codec->codec_id = AV_CODEC_ID_PCM_S16LE_PLANAR; break; - case 20: st->codec->codec_id = AV_CODEC_ID_PCM_LXF; break; - case 24: st->codec->codec_id = AV_CODEC_ID_PCM_S24LE_PLANAR; break; - case 32: st->codec->codec_id = AV_CODEC_ID_PCM_S32LE_PLANAR; break; - default: - av_log(s, AV_LOG_WARNING, - "only 16-, 20-, 24- and 32-bit PCM currently supported\n"); - return AVERROR_PATCHWELCOME; - } - - samples = track_size * 8 / st->codec->bits_per_coded_sample; - - //use audio packet size to determine video standard - //for NTSC we have one 8008-sample audio frame per five video frames - if (samples == LXF_SAMPLERATE * 5005 / 30000) { - avpriv_set_pts_info(s->streams[0], 64, 1001, 30000); - } else { - //assume PAL, but warn if we don't have 1920 samples - if (samples != LXF_SAMPLERATE / 25) - av_log(s, AV_LOG_WARNING, - "video doesn't seem to be PAL or NTSC. guessing PAL\n"); - - avpriv_set_pts_info(s->streams[0], 64, 1, 25); - } - - //TODO: warning if track mask != (1 << channels) - 1? - ret = av_popcount(channels) * track_size; - - break; - default: - tmp = bytestream_get_le32(&p); - ret = bytestream_get_le32(&p); - if (tmp == 1) - lxf->extended_size = bytestream_get_le32(&p); - break; - } - - return ret; -} - -static int lxf_read_header(AVFormatContext *s) -{ - LXFDemuxContext *lxf = s->priv_data; - AVIOContext *pb = s->pb; - uint8_t header_data[LXF_HEADER_DATA_SIZE]; - int ret; - AVStream *st; - uint32_t video_params, disk_params; - uint16_t record_date, expiration_date; - - if ((ret = get_packet_header(s)) < 0) - return ret; - - if (ret != LXF_HEADER_DATA_SIZE) { - av_log(s, AV_LOG_ERROR, "expected %d B size header, got %d\n", - LXF_HEADER_DATA_SIZE, ret); - return AVERROR_INVALIDDATA; - } - - if ((ret = avio_read(pb, header_data, LXF_HEADER_DATA_SIZE)) != LXF_HEADER_DATA_SIZE) - return ret < 0 ? ret : AVERROR_EOF; - - if (!(st = avformat_new_stream(s, NULL))) - return AVERROR(ENOMEM); - - st->duration = AV_RL32(&header_data[32]); - video_params = AV_RL32(&header_data[40]); - record_date = AV_RL16(&header_data[56]); - expiration_date = AV_RL16(&header_data[58]); - disk_params = AV_RL32(&header_data[116]); - - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->bit_rate = 1000000 * ((video_params >> 14) & 0xFF); - st->codec->codec_tag = video_params & 0xF; - st->codec->codec_id = ff_codec_get_id(lxf_tags, st->codec->codec_tag); - - av_log(s, AV_LOG_DEBUG, "record: %x = %i-%02i-%02i\n", - record_date, 1900 + (record_date & 0x7F), (record_date >> 7) & 0xF, - (record_date >> 11) & 0x1F); - - av_log(s, AV_LOG_DEBUG, "expire: %x = %i-%02i-%02i\n", - expiration_date, 1900 + (expiration_date & 0x7F), (expiration_date >> 7) & 0xF, - (expiration_date >> 11) & 0x1F); - - if ((video_params >> 22) & 1) - av_log(s, AV_LOG_WARNING, "VBI data not yet supported\n"); - - if ((lxf->channels = 1 << (disk_params >> 4 & 3) + 1)) { - if (!(st = avformat_new_stream(s, NULL))) - return AVERROR(ENOMEM); - - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->sample_rate = LXF_SAMPLERATE; - st->codec->channels = lxf->channels; - - avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); - } - - avio_skip(s->pb, lxf->extended_size); - - return 0; -} - -static int lxf_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - LXFDemuxContext *lxf = s->priv_data; - AVIOContext *pb = s->pb; - AVStream *ast = NULL; - uint32_t stream; - int ret, ret2; - - if ((ret = get_packet_header(s)) < 0) - return ret; - - stream = lxf->packet_type; - - if (stream > 1) { - av_log(s, AV_LOG_WARNING, "got packet with illegal stream index %u\n", stream); - return AVERROR(EAGAIN); - } - - if (stream == 1 && !(ast = s->streams[1])) { - av_log(s, AV_LOG_ERROR, "got audio packet without having an audio stream\n"); - return AVERROR_INVALIDDATA; - } - - //make sure the data fits in the de-planerization buffer - if (ast && ret > LXF_MAX_AUDIO_PACKET) { - av_log(s, AV_LOG_ERROR, "audio packet too large (%i > %i)\n", - ret, LXF_MAX_AUDIO_PACKET); - return AVERROR_INVALIDDATA; - } - - if ((ret2 = av_new_packet(pkt, ret)) < 0) - return ret2; - - if ((ret2 = avio_read(pb, pkt->data, ret)) != ret) { - av_free_packet(pkt); - return ret2 < 0 ? ret2 : AVERROR_EOF; - } - - pkt->stream_index = stream; - - if (!ast) { - //picture type (0 = closed I, 1 = open I, 2 = P, 3 = B) - if (((lxf->video_format >> 22) & 0x3) < 2) - pkt->flags |= AV_PKT_FLAG_KEY; - - pkt->dts = lxf->frame_number++; - } - - return ret; -} - -AVInputFormat ff_lxf_demuxer = { - .name = "lxf", - .long_name = NULL_IF_CONFIG_SMALL("VR native stream (LXF)"), - .priv_data_size = sizeof(LXFDemuxContext), - .read_probe = lxf_probe, - .read_header = lxf_read_header, - .read_packet = lxf_read_packet, - .codec_tag = (const AVCodecTag* const []){lxf_tags, 0}, -}; diff --git a/ffmpeg1/libavformat/m4vdec.c b/ffmpeg1/libavformat/m4vdec.c deleted file mode 100644 index e72fb42..0000000 --- a/ffmpeg1/libavformat/m4vdec.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * RAW MPEG-4 video demuxer - * Copyright (c) 2006 Thijs Vermeir - * - * 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 "rawdec.h" - -#define VISUAL_OBJECT_START_CODE 0x000001b5 -#define VOP_START_CODE 0x000001b6 - -static int mpeg4video_probe(AVProbeData *probe_packet) -{ - uint32_t temp_buffer= -1; - int VO=0, VOL=0, VOP = 0, VISO = 0, res=0; - int i; - - for(i=0; ibuf_size; i++){ - temp_buffer = (temp_buffer<<8) + probe_packet->buf[i]; - if ((temp_buffer & 0xffffff00) != 0x100) - continue; - - if (temp_buffer == VOP_START_CODE) VOP++; - else if (temp_buffer == VISUAL_OBJECT_START_CODE) VISO++; - else if (temp_buffer < 0x120) VO++; - else if (temp_buffer < 0x130) VOL++; - else if ( !(0x1AF < temp_buffer && temp_buffer < 0x1B7) - && !(0x1B9 < temp_buffer && temp_buffer < 0x1C4)) res++; - } - - if (VOP >= VISO && VOP >= VOL && VO >= VOL && VOL > 0 && res==0) - return VOP+VO > 3 ? AVPROBE_SCORE_MAX/2 : AVPROBE_SCORE_MAX/4; - return 0; -} - -FF_DEF_RAWVIDEO_DEMUXER(m4v, "raw MPEG-4 video", mpeg4video_probe, "m4v", AV_CODEC_ID_MPEG4) diff --git a/ffmpeg1/libavformat/matroska.c b/ffmpeg1/libavformat/matroska.c deleted file mode 100644 index 09eecf2..0000000 --- a/ffmpeg1/libavformat/matroska.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Matroska common data - * Copyright (c) 2003-2004 The ffmpeg Project - * - * 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 "matroska.h" - -/* If you add a tag here that is not in ff_codec_bmp_tags[] - or ff_codec_wav_tags[], add it also to additional_audio_tags[] - or additional_video_tags[] in matroskaenc.c */ -const CodecTags ff_mkv_codec_tags[]={ - {"A_AAC" , AV_CODEC_ID_AAC}, - {"A_AC3" , AV_CODEC_ID_AC3}, - {"A_ALAC" , AV_CODEC_ID_ALAC}, - {"A_DTS" , AV_CODEC_ID_DTS}, - {"A_EAC3" , AV_CODEC_ID_EAC3}, - {"A_FLAC" , AV_CODEC_ID_FLAC}, - {"A_MLP" , AV_CODEC_ID_MLP}, - {"A_MPEG/L2" , AV_CODEC_ID_MP2}, - {"A_MPEG/L1" , AV_CODEC_ID_MP2}, - {"A_MPEG/L3" , AV_CODEC_ID_MP3}, - {"A_OPUS/EXPERIMENTAL",AV_CODEC_ID_OPUS}, - {"A_OPUS", AV_CODEC_ID_OPUS}, - {"A_PCM/FLOAT/IEEE" , AV_CODEC_ID_PCM_F32LE}, - {"A_PCM/FLOAT/IEEE" , AV_CODEC_ID_PCM_F64LE}, - {"A_PCM/INT/BIG" , AV_CODEC_ID_PCM_S16BE}, - {"A_PCM/INT/BIG" , AV_CODEC_ID_PCM_S24BE}, - {"A_PCM/INT/BIG" , AV_CODEC_ID_PCM_S32BE}, - {"A_PCM/INT/LIT" , AV_CODEC_ID_PCM_S16LE}, - {"A_PCM/INT/LIT" , AV_CODEC_ID_PCM_S24LE}, - {"A_PCM/INT/LIT" , AV_CODEC_ID_PCM_S32LE}, - {"A_PCM/INT/LIT" , AV_CODEC_ID_PCM_U8}, - {"A_QUICKTIME/QDM2" , AV_CODEC_ID_QDM2}, - {"A_REAL/14_4" , AV_CODEC_ID_RA_144}, - {"A_REAL/28_8" , AV_CODEC_ID_RA_288}, - {"A_REAL/ATRC" , AV_CODEC_ID_ATRAC3}, - {"A_REAL/COOK" , AV_CODEC_ID_COOK}, - {"A_REAL/SIPR" , AV_CODEC_ID_SIPR}, - {"A_TRUEHD" , AV_CODEC_ID_TRUEHD}, - {"A_TTA1" , AV_CODEC_ID_TTA}, - {"A_VORBIS" , AV_CODEC_ID_VORBIS}, - {"A_WAVPACK4" , AV_CODEC_ID_WAVPACK}, - - {"S_TEXT/UTF8" , AV_CODEC_ID_SUBRIP}, - {"S_TEXT/UTF8" , AV_CODEC_ID_TEXT}, - {"S_TEXT/UTF8" , AV_CODEC_ID_SRT}, - {"S_TEXT/ASCII" , AV_CODEC_ID_TEXT}, - {"S_TEXT/ASS" , AV_CODEC_ID_SSA}, - {"S_TEXT/SSA" , AV_CODEC_ID_SSA}, - {"S_ASS" , AV_CODEC_ID_SSA}, - {"S_SSA" , AV_CODEC_ID_SSA}, - {"S_VOBSUB" , AV_CODEC_ID_DVD_SUBTITLE}, - {"S_DVBSUB" , AV_CODEC_ID_DVB_SUBTITLE}, - {"S_HDMV/PGS" , AV_CODEC_ID_HDMV_PGS_SUBTITLE}, - - {"V_DIRAC" , AV_CODEC_ID_DIRAC}, - {"V_MJPEG" , AV_CODEC_ID_MJPEG}, - {"V_MPEG1" , AV_CODEC_ID_MPEG1VIDEO}, - {"V_MPEG2" , AV_CODEC_ID_MPEG2VIDEO}, - {"V_MPEG4/ISO/ASP" , AV_CODEC_ID_MPEG4}, - {"V_MPEG4/ISO/AP" , AV_CODEC_ID_MPEG4}, - {"V_MPEG4/ISO/SP" , AV_CODEC_ID_MPEG4}, - {"V_MPEG4/ISO/AVC" , AV_CODEC_ID_H264}, - {"V_MPEG4/MS/V3" , AV_CODEC_ID_MSMPEG4V3}, - {"V_PRORES" , AV_CODEC_ID_PRORES}, - {"V_REAL/RV10" , AV_CODEC_ID_RV10}, - {"V_REAL/RV20" , AV_CODEC_ID_RV20}, - {"V_REAL/RV30" , AV_CODEC_ID_RV30}, - {"V_REAL/RV40" , AV_CODEC_ID_RV40}, - {"V_SNOW" , AV_CODEC_ID_SNOW}, - {"V_THEORA" , AV_CODEC_ID_THEORA}, - {"V_UNCOMPRESSED" , AV_CODEC_ID_RAWVIDEO}, - {"V_VP8" , AV_CODEC_ID_VP8}, - {"V_VP9" , AV_CODEC_ID_VP9}, - - {"" , AV_CODEC_ID_NONE} -}; - -const CodecMime ff_mkv_mime_tags[] = { - {"text/plain" , AV_CODEC_ID_TEXT}, - {"image/gif" , AV_CODEC_ID_GIF}, - {"image/jpeg" , AV_CODEC_ID_MJPEG}, - {"image/png" , AV_CODEC_ID_PNG}, - {"image/tiff" , AV_CODEC_ID_TIFF}, - {"application/x-truetype-font", AV_CODEC_ID_TTF}, - {"application/x-font" , AV_CODEC_ID_TTF}, - {"application/vnd.ms-opentype", AV_CODEC_ID_OTF}, - - {"" , AV_CODEC_ID_NONE} -}; - -const AVMetadataConv ff_mkv_metadata_conv[] = { - { "LEAD_PERFORMER", "performer" }, - { "PART_NUMBER" , "track" }, - { 0 } -}; - -const char * const ff_matroska_video_stereo_mode[MATROSKA_VIDEO_STEREO_MODE_COUNT] = { - "mono", - "left_right", - "bottom_top", - "top_bottom", - "checkerboard_rl", - "checkerboard_lr", - "row_interleaved_rl", - "row_interleaved_lr", - "col_interleaved_rl", - "col_interleaved_lr", - "anaglyph_cyan_red", - "right_left", - "anaglyph_green_magenta", - "block_lr", - "block_rl", -}; - -const char * const ff_matroska_video_stereo_plane[MATROSKA_VIDEO_STEREO_PLANE_COUNT] = { - "left", - "right", - "background", -}; diff --git a/ffmpeg1/libavformat/matroska.h b/ffmpeg1/libavformat/matroska.h deleted file mode 100644 index 8a7e10b..0000000 --- a/ffmpeg1/libavformat/matroska.h +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Matroska constants - * Copyright (c) 2003-2004 The ffmpeg Project - * - * 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 AVFORMAT_MATROSKA_H -#define AVFORMAT_MATROSKA_H - -#include "libavcodec/avcodec.h" -#include "metadata.h" -#include "internal.h" - -/* EBML version supported */ -#define EBML_VERSION 1 - -/* top-level master-IDs */ -#define EBML_ID_HEADER 0x1A45DFA3 - -/* IDs in the HEADER master */ -#define EBML_ID_EBMLVERSION 0x4286 -#define EBML_ID_EBMLREADVERSION 0x42F7 -#define EBML_ID_EBMLMAXIDLENGTH 0x42F2 -#define EBML_ID_EBMLMAXSIZELENGTH 0x42F3 -#define EBML_ID_DOCTYPE 0x4282 -#define EBML_ID_DOCTYPEVERSION 0x4287 -#define EBML_ID_DOCTYPEREADVERSION 0x4285 - -/* general EBML types */ -#define EBML_ID_VOID 0xEC -#define EBML_ID_CRC32 0xBF - -/* - * Matroska element IDs, max. 32 bits - */ - -/* toplevel segment */ -#define MATROSKA_ID_SEGMENT 0x18538067 - -/* Matroska top-level master IDs */ -#define MATROSKA_ID_INFO 0x1549A966 -#define MATROSKA_ID_TRACKS 0x1654AE6B -#define MATROSKA_ID_CUES 0x1C53BB6B -#define MATROSKA_ID_TAGS 0x1254C367 -#define MATROSKA_ID_SEEKHEAD 0x114D9B74 -#define MATROSKA_ID_ATTACHMENTS 0x1941A469 -#define MATROSKA_ID_CLUSTER 0x1F43B675 -#define MATROSKA_ID_CHAPTERS 0x1043A770 - -/* IDs in the info master */ -#define MATROSKA_ID_TIMECODESCALE 0x2AD7B1 -#define MATROSKA_ID_DURATION 0x4489 -#define MATROSKA_ID_TITLE 0x7BA9 -#define MATROSKA_ID_WRITINGAPP 0x5741 -#define MATROSKA_ID_MUXINGAPP 0x4D80 -#define MATROSKA_ID_DATEUTC 0x4461 -#define MATROSKA_ID_SEGMENTUID 0x73A4 - -/* ID in the tracks master */ -#define MATROSKA_ID_TRACKENTRY 0xAE - -/* IDs in the trackentry master */ -#define MATROSKA_ID_TRACKNUMBER 0xD7 -#define MATROSKA_ID_TRACKUID 0x73C5 -#define MATROSKA_ID_TRACKTYPE 0x83 -#define MATROSKA_ID_TRACKVIDEO 0xE0 -#define MATROSKA_ID_TRACKAUDIO 0xE1 -#define MATROSKA_ID_TRACKOPERATION 0xE2 -#define MATROSKA_ID_TRACKCOMBINEPLANES 0xE3 -#define MATROSKA_ID_TRACKPLANE 0xE4 -#define MATROSKA_ID_TRACKPLANEUID 0xE5 -#define MATROSKA_ID_TRACKPLANETYPE 0xE6 -#define MATROSKA_ID_CODECID 0x86 -#define MATROSKA_ID_CODECPRIVATE 0x63A2 -#define MATROSKA_ID_CODECNAME 0x258688 -#define MATROSKA_ID_CODECINFOURL 0x3B4040 -#define MATROSKA_ID_CODECDOWNLOADURL 0x26B240 -#define MATROSKA_ID_CODECDECODEALL 0xAA -#define MATROSKA_ID_TRACKNAME 0x536E -#define MATROSKA_ID_TRACKLANGUAGE 0x22B59C -#define MATROSKA_ID_TRACKFLAGENABLED 0xB9 -#define MATROSKA_ID_TRACKFLAGDEFAULT 0x88 -#define MATROSKA_ID_TRACKFLAGFORCED 0x55AA -#define MATROSKA_ID_TRACKFLAGLACING 0x9C -#define MATROSKA_ID_TRACKMINCACHE 0x6DE7 -#define MATROSKA_ID_TRACKMAXCACHE 0x6DF8 -#define MATROSKA_ID_TRACKDEFAULTDURATION 0x23E383 -#define MATROSKA_ID_TRACKCONTENTENCODINGS 0x6D80 -#define MATROSKA_ID_TRACKCONTENTENCODING 0x6240 -#define MATROSKA_ID_TRACKTIMECODESCALE 0x23314F -#define MATROSKA_ID_TRACKMAXBLKADDID 0x55EE - -/* IDs in the trackvideo master */ -#define MATROSKA_ID_VIDEOFRAMERATE 0x2383E3 -#define MATROSKA_ID_VIDEODISPLAYWIDTH 0x54B0 -#define MATROSKA_ID_VIDEODISPLAYHEIGHT 0x54BA -#define MATROSKA_ID_VIDEOPIXELWIDTH 0xB0 -#define MATROSKA_ID_VIDEOPIXELHEIGHT 0xBA -#define MATROSKA_ID_VIDEOPIXELCROPB 0x54AA -#define MATROSKA_ID_VIDEOPIXELCROPT 0x54BB -#define MATROSKA_ID_VIDEOPIXELCROPL 0x54CC -#define MATROSKA_ID_VIDEOPIXELCROPR 0x54DD -#define MATROSKA_ID_VIDEODISPLAYUNIT 0x54B2 -#define MATROSKA_ID_VIDEOFLAGINTERLACED 0x9A -#define MATROSKA_ID_VIDEOSTEREOMODE 0x53B8 -#define MATROSKA_ID_VIDEOALPHAMODE 0x53C0 -#define MATROSKA_ID_VIDEOASPECTRATIO 0x54B3 -#define MATROSKA_ID_VIDEOCOLORSPACE 0x2EB524 - -/* IDs in the trackaudio master */ -#define MATROSKA_ID_AUDIOSAMPLINGFREQ 0xB5 -#define MATROSKA_ID_AUDIOOUTSAMPLINGFREQ 0x78B5 - -#define MATROSKA_ID_AUDIOBITDEPTH 0x6264 -#define MATROSKA_ID_AUDIOCHANNELS 0x9F - -/* IDs in the content encoding master */ -#define MATROSKA_ID_ENCODINGORDER 0x5031 -#define MATROSKA_ID_ENCODINGSCOPE 0x5032 -#define MATROSKA_ID_ENCODINGTYPE 0x5033 -#define MATROSKA_ID_ENCODINGCOMPRESSION 0x5034 -#define MATROSKA_ID_ENCODINGCOMPALGO 0x4254 -#define MATROSKA_ID_ENCODINGCOMPSETTINGS 0x4255 - -#define MATROSKA_ID_ENCODINGENCRYPTION 0x5035 -#define MATROSKA_ID_ENCODINGENCAESSETTINGS 0x47E7 -#define MATROSKA_ID_ENCODINGENCALGO 0x47E1 -#define MATROSKA_ID_ENCODINGENCKEYID 0x47E2 -#define MATROSKA_ID_ENCODINGSIGALGO 0x47E5 -#define MATROSKA_ID_ENCODINGSIGHASHALGO 0x47E6 -#define MATROSKA_ID_ENCODINGSIGKEYID 0x47E4 -#define MATROSKA_ID_ENCODINGSIGNATURE 0x47E3 - -/* ID in the cues master */ -#define MATROSKA_ID_POINTENTRY 0xBB - -/* IDs in the pointentry master */ -#define MATROSKA_ID_CUETIME 0xB3 -#define MATROSKA_ID_CUETRACKPOSITION 0xB7 - -/* IDs in the cuetrackposition master */ -#define MATROSKA_ID_CUETRACK 0xF7 -#define MATROSKA_ID_CUECLUSTERPOSITION 0xF1 -#define MATROSKA_ID_CUEBLOCKNUMBER 0x5378 - -/* IDs in the tags master */ -#define MATROSKA_ID_TAG 0x7373 -#define MATROSKA_ID_SIMPLETAG 0x67C8 -#define MATROSKA_ID_TAGNAME 0x45A3 -#define MATROSKA_ID_TAGSTRING 0x4487 -#define MATROSKA_ID_TAGLANG 0x447A -#define MATROSKA_ID_TAGDEFAULT 0x4484 -#define MATROSKA_ID_TAGDEFAULT_BUG 0x44B4 -#define MATROSKA_ID_TAGTARGETS 0x63C0 -#define MATROSKA_ID_TAGTARGETS_TYPE 0x63CA -#define MATROSKA_ID_TAGTARGETS_TYPEVALUE 0x68CA -#define MATROSKA_ID_TAGTARGETS_TRACKUID 0x63C5 -#define MATROSKA_ID_TAGTARGETS_CHAPTERUID 0x63C4 -#define MATROSKA_ID_TAGTARGETS_ATTACHUID 0x63C6 - -/* IDs in the seekhead master */ -#define MATROSKA_ID_SEEKENTRY 0x4DBB - -/* IDs in the seekpoint master */ -#define MATROSKA_ID_SEEKID 0x53AB -#define MATROSKA_ID_SEEKPOSITION 0x53AC - -/* IDs in the cluster master */ -#define MATROSKA_ID_CLUSTERTIMECODE 0xE7 -#define MATROSKA_ID_CLUSTERPOSITION 0xA7 -#define MATROSKA_ID_CLUSTERPREVSIZE 0xAB -#define MATROSKA_ID_BLOCKGROUP 0xA0 -#define MATROSKA_ID_BLOCKADDITIONS 0x75A1 -#define MATROSKA_ID_BLOCKMORE 0xA6 -#define MATROSKA_ID_BLOCKADDID 0xEE -#define MATROSKA_ID_BLOCKADDITIONAL 0xA5 -#define MATROSKA_ID_SIMPLEBLOCK 0xA3 - -/* IDs in the blockgroup master */ -#define MATROSKA_ID_BLOCK 0xA1 -#define MATROSKA_ID_BLOCKDURATION 0x9B -#define MATROSKA_ID_BLOCKREFERENCE 0xFB - -/* IDs in the attachments master */ -#define MATROSKA_ID_ATTACHEDFILE 0x61A7 -#define MATROSKA_ID_FILEDESC 0x467E -#define MATROSKA_ID_FILENAME 0x466E -#define MATROSKA_ID_FILEMIMETYPE 0x4660 -#define MATROSKA_ID_FILEDATA 0x465C -#define MATROSKA_ID_FILEUID 0x46AE - -/* IDs in the chapters master */ -#define MATROSKA_ID_EDITIONENTRY 0x45B9 -#define MATROSKA_ID_CHAPTERATOM 0xB6 -#define MATROSKA_ID_CHAPTERTIMESTART 0x91 -#define MATROSKA_ID_CHAPTERTIMEEND 0x92 -#define MATROSKA_ID_CHAPTERDISPLAY 0x80 -#define MATROSKA_ID_CHAPSTRING 0x85 -#define MATROSKA_ID_CHAPLANG 0x437C -#define MATROSKA_ID_EDITIONUID 0x45BC -#define MATROSKA_ID_EDITIONFLAGHIDDEN 0x45BD -#define MATROSKA_ID_EDITIONFLAGDEFAULT 0x45DB -#define MATROSKA_ID_EDITIONFLAGORDERED 0x45DD -#define MATROSKA_ID_CHAPTERUID 0x73C4 -#define MATROSKA_ID_CHAPTERFLAGHIDDEN 0x98 -#define MATROSKA_ID_CHAPTERFLAGENABLED 0x4598 -#define MATROSKA_ID_CHAPTERPHYSEQUIV 0x63C3 - -typedef enum { - MATROSKA_TRACK_TYPE_NONE = 0x0, - MATROSKA_TRACK_TYPE_VIDEO = 0x1, - MATROSKA_TRACK_TYPE_AUDIO = 0x2, - MATROSKA_TRACK_TYPE_COMPLEX = 0x3, - MATROSKA_TRACK_TYPE_LOGO = 0x10, - MATROSKA_TRACK_TYPE_SUBTITLE = 0x11, - MATROSKA_TRACK_TYPE_CONTROL = 0x20, -} MatroskaTrackType; - -typedef enum { - MATROSKA_TRACK_ENCODING_COMP_ZLIB = 0, - MATROSKA_TRACK_ENCODING_COMP_BZLIB = 1, - MATROSKA_TRACK_ENCODING_COMP_LZO = 2, - MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP = 3, -} MatroskaTrackEncodingCompAlgo; - -typedef enum { - MATROSKA_VIDEO_STEREOMODE_TYPE_MONO = 0, - MATROSKA_VIDEO_STEREOMODE_TYPE_LEFT_RIGHT = 1, - MATROSKA_VIDEO_STEREOMODE_TYPE_BOTTOM_TOP = 2, - MATROSKA_VIDEO_STEREOMODE_TYPE_TOP_BOTTOM = 3, - MATROSKA_VIDEO_STEREOMODE_TYPE_CHECKERBOARD_RL = 4, - MATROSKA_VIDEO_STEREOMODE_TYPE_CHECKERBOARD_LR = 5, - MATROSKA_VIDEO_STEREOMODE_TYPE_ROW_INTERLEAVED_RL = 6, - MATROSKA_VIDEO_STEREOMODE_TYPE_ROW_INTERLEAVED_LR = 7, - MATROSKA_VIDEO_STEREOMODE_TYPE_COL_INTERLEAVED_RL = 8, - MATROSKA_VIDEO_STEREOMODE_TYPE_COL_INTERLEAVED_LR = 9, - MATROSKA_VIDEO_STEREOMODE_TYPE_ANAGLYPH_CYAN_RED = 10, - MATROSKA_VIDEO_STEREOMODE_TYPE_RIGHT_LEFT = 11, - MATROSKA_VIDEO_STEREOMODE_TYPE_ANAGLYPH_GREEN_MAG = 12, - MATROSKA_VIDEO_STEREOMODE_TYPE_BOTH_EYES_BLOCK_LR = 13, - MATROSKA_VIDEO_STEREOMODE_TYPE_BOTH_EYES_BLOCK_RL = 14, -} MatroskaVideoStereoModeType; - -/* - * Matroska Codec IDs, strings - */ - -typedef struct CodecTags{ - char str[20]; - enum AVCodecID id; -}CodecTags; - -/* max. depth in the EBML tree structure */ -#define EBML_MAX_DEPTH 16 - -#define MATROSKA_VIDEO_STEREO_MODE_COUNT 15 -#define MATROSKA_VIDEO_STEREO_PLANE_COUNT 3 - -extern const CodecTags ff_mkv_codec_tags[]; -extern const CodecMime ff_mkv_mime_tags[]; -extern const AVMetadataConv ff_mkv_metadata_conv[]; -extern const char * const ff_matroska_video_stereo_mode[MATROSKA_VIDEO_STEREO_MODE_COUNT]; -extern const char * const ff_matroska_video_stereo_plane[MATROSKA_VIDEO_STEREO_PLANE_COUNT]; - -#endif /* AVFORMAT_MATROSKA_H */ diff --git a/ffmpeg1/libavformat/matroskadec.c b/ffmpeg1/libavformat/matroskadec.c deleted file mode 100644 index eea29da..0000000 --- a/ffmpeg1/libavformat/matroskadec.c +++ /dev/null @@ -1,2557 +0,0 @@ -/* - * Matroska file demuxer - * Copyright (c) 2003-2008 The FFmpeg Project - * - * 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 - */ - -/** - * @file - * Matroska file demuxer - * @author Ronald Bultje - * @author with a little help from Moritz Bunkus - * @author totally reworked by Aurelien Jacobs - * @see specs available on the Matroska project page: http://www.matroska.org/ - */ - -#include -#include "avformat.h" -#include "internal.h" -#include "avio_internal.h" -/* For ff_codec_get_id(). */ -#include "riff.h" -#include "isom.h" -#include "rmsipr.h" -#include "matroska.h" -#include "libavcodec/bytestream.h" -#include "libavcodec/mpeg4audio.h" -#include "libavutil/base64.h" -#include "libavutil/intfloat.h" -#include "libavutil/intreadwrite.h" -#include "libavutil/avstring.h" -#include "libavutil/lzo.h" -#include "libavutil/dict.h" -#if CONFIG_ZLIB -#include -#endif -#if CONFIG_BZLIB -#include -#endif - -typedef enum { - EBML_NONE, - EBML_UINT, - EBML_FLOAT, - EBML_STR, - EBML_UTF8, - EBML_BIN, - EBML_NEST, - EBML_PASS, - EBML_STOP, - EBML_TYPE_COUNT -} EbmlType; - -typedef const struct EbmlSyntax { - uint32_t id; - EbmlType type; - int list_elem_size; - int data_offset; - union { - uint64_t u; - double f; - const char *s; - const struct EbmlSyntax *n; - } def; -} EbmlSyntax; - -typedef struct { - int nb_elem; - void *elem; -} EbmlList; - -typedef struct { - int size; - uint8_t *data; - int64_t pos; -} EbmlBin; - -typedef struct { - uint64_t version; - uint64_t max_size; - uint64_t id_length; - char *doctype; - uint64_t doctype_version; -} Ebml; - -typedef struct { - uint64_t algo; - EbmlBin settings; -} MatroskaTrackCompression; - -typedef struct { - uint64_t algo; - EbmlBin key_id; -} MatroskaTrackEncryption; - -typedef struct { - uint64_t scope; - uint64_t type; - MatroskaTrackCompression compression; - MatroskaTrackEncryption encryption; -} MatroskaTrackEncoding; - -typedef struct { - double frame_rate; - uint64_t display_width; - uint64_t display_height; - uint64_t pixel_width; - uint64_t pixel_height; - EbmlBin color_space; - uint64_t stereo_mode; - uint64_t alpha_mode; -} MatroskaTrackVideo; - -typedef struct { - double samplerate; - double out_samplerate; - uint64_t bitdepth; - uint64_t channels; - - /* real audio header (extracted from extradata) */ - int coded_framesize; - int sub_packet_h; - int frame_size; - int sub_packet_size; - int sub_packet_cnt; - int pkt_cnt; - uint64_t buf_timecode; - uint8_t *buf; -} MatroskaTrackAudio; - -typedef struct { - uint64_t uid; - uint64_t type; -} MatroskaTrackPlane; - -typedef struct { - EbmlList combine_planes; -} MatroskaTrackOperation; - -typedef struct { - uint64_t num; - uint64_t uid; - uint64_t type; - char *name; - char *codec_id; - EbmlBin codec_priv; - char *language; - double time_scale; - uint64_t default_duration; - uint64_t flag_default; - uint64_t flag_forced; - MatroskaTrackVideo video; - MatroskaTrackAudio audio; - MatroskaTrackOperation operation; - EbmlList encodings; - - AVStream *stream; - int64_t end_timecode; - int ms_compat; - uint64_t max_block_additional_id; -} MatroskaTrack; - -typedef struct { - uint64_t uid; - char *filename; - char *mime; - EbmlBin bin; - - AVStream *stream; -} MatroskaAttachement; - -typedef struct { - uint64_t start; - uint64_t end; - uint64_t uid; - char *title; - - AVChapter *chapter; -} MatroskaChapter; - -typedef struct { - uint64_t track; - uint64_t pos; -} MatroskaIndexPos; - -typedef struct { - uint64_t time; - EbmlList pos; -} MatroskaIndex; - -typedef struct { - char *name; - char *string; - char *lang; - uint64_t def; - EbmlList sub; -} MatroskaTag; - -typedef struct { - char *type; - uint64_t typevalue; - uint64_t trackuid; - uint64_t chapteruid; - uint64_t attachuid; -} MatroskaTagTarget; - -typedef struct { - MatroskaTagTarget target; - EbmlList tag; -} MatroskaTags; - -typedef struct { - uint64_t id; - uint64_t pos; -} MatroskaSeekhead; - -typedef struct { - uint64_t start; - uint64_t length; -} MatroskaLevel; - -typedef struct { - uint64_t timecode; - EbmlList blocks; -} MatroskaCluster; - -typedef struct { - AVFormatContext *ctx; - - /* EBML stuff */ - int num_levels; - MatroskaLevel levels[EBML_MAX_DEPTH]; - int level_up; - uint32_t current_id; - - uint64_t time_scale; - double duration; - char *title; - EbmlBin date_utc; - EbmlList tracks; - EbmlList attachments; - EbmlList chapters; - EbmlList index; - EbmlList tags; - EbmlList seekhead; - - /* byte position of the segment inside the stream */ - int64_t segment_start; - - /* the packet queue */ - AVPacket **packets; - int num_packets; - AVPacket *prev_pkt; - - int done; - - /* What to skip before effectively reading a packet. */ - int skip_to_keyframe; - uint64_t skip_to_timecode; - - /* File has a CUES element, but we defer parsing until it is needed. */ - int cues_parsing_deferred; - - int current_cluster_num_blocks; - int64_t current_cluster_pos; - MatroskaCluster current_cluster; - - /* File has SSA subtitles which prevent incremental cluster parsing. */ - int contains_ssa; -} MatroskaDemuxContext; - -typedef struct { - uint64_t duration; - int64_t reference; - uint64_t non_simple; - EbmlBin bin; - uint64_t additional_id; - EbmlBin additional; -} MatroskaBlock; - -static EbmlSyntax ebml_header[] = { - { EBML_ID_EBMLREADVERSION, EBML_UINT, 0, offsetof(Ebml,version), {.u=EBML_VERSION} }, - { EBML_ID_EBMLMAXSIZELENGTH, EBML_UINT, 0, offsetof(Ebml,max_size), {.u=8} }, - { EBML_ID_EBMLMAXIDLENGTH, EBML_UINT, 0, offsetof(Ebml,id_length), {.u=4} }, - { EBML_ID_DOCTYPE, EBML_STR, 0, offsetof(Ebml,doctype), {.s="(none)"} }, - { EBML_ID_DOCTYPEREADVERSION, EBML_UINT, 0, offsetof(Ebml,doctype_version), {.u=1} }, - { EBML_ID_EBMLVERSION, EBML_NONE }, - { EBML_ID_DOCTYPEVERSION, EBML_NONE }, - { 0 } -}; - -static EbmlSyntax ebml_syntax[] = { - { EBML_ID_HEADER, EBML_NEST, 0, 0, {.n=ebml_header} }, - { 0 } -}; - -static EbmlSyntax matroska_info[] = { - { MATROSKA_ID_TIMECODESCALE, EBML_UINT, 0, offsetof(MatroskaDemuxContext,time_scale), {.u=1000000} }, - { MATROSKA_ID_DURATION, EBML_FLOAT, 0, offsetof(MatroskaDemuxContext,duration) }, - { MATROSKA_ID_TITLE, EBML_UTF8, 0, offsetof(MatroskaDemuxContext,title) }, - { MATROSKA_ID_WRITINGAPP, EBML_NONE }, - { MATROSKA_ID_MUXINGAPP, EBML_NONE }, - { MATROSKA_ID_DATEUTC, EBML_BIN, 0, offsetof(MatroskaDemuxContext,date_utc) }, - { MATROSKA_ID_SEGMENTUID, EBML_NONE }, - { 0 } -}; - -static EbmlSyntax matroska_track_video[] = { - { MATROSKA_ID_VIDEOFRAMERATE, EBML_FLOAT,0, offsetof(MatroskaTrackVideo,frame_rate) }, - { MATROSKA_ID_VIDEODISPLAYWIDTH, EBML_UINT, 0, offsetof(MatroskaTrackVideo,display_width) }, - { MATROSKA_ID_VIDEODISPLAYHEIGHT, EBML_UINT, 0, offsetof(MatroskaTrackVideo,display_height) }, - { MATROSKA_ID_VIDEOPIXELWIDTH, EBML_UINT, 0, offsetof(MatroskaTrackVideo,pixel_width) }, - { MATROSKA_ID_VIDEOPIXELHEIGHT, EBML_UINT, 0, offsetof(MatroskaTrackVideo,pixel_height) }, - { MATROSKA_ID_VIDEOCOLORSPACE, EBML_BIN, 0, offsetof(MatroskaTrackVideo,color_space) }, - { MATROSKA_ID_VIDEOSTEREOMODE, EBML_UINT, 0, offsetof(MatroskaTrackVideo,stereo_mode) }, - { MATROSKA_ID_VIDEOALPHAMODE, EBML_UINT, 0, offsetof(MatroskaTrackVideo,alpha_mode) }, - { MATROSKA_ID_VIDEOPIXELCROPB, EBML_NONE }, - { MATROSKA_ID_VIDEOPIXELCROPT, EBML_NONE }, - { MATROSKA_ID_VIDEOPIXELCROPL, EBML_NONE }, - { MATROSKA_ID_VIDEOPIXELCROPR, EBML_NONE }, - { MATROSKA_ID_VIDEODISPLAYUNIT, EBML_NONE }, - { MATROSKA_ID_VIDEOFLAGINTERLACED,EBML_NONE }, - { MATROSKA_ID_VIDEOASPECTRATIO, EBML_NONE }, - { 0 } -}; - -static EbmlSyntax matroska_track_audio[] = { - { MATROSKA_ID_AUDIOSAMPLINGFREQ, EBML_FLOAT,0, offsetof(MatroskaTrackAudio,samplerate), {.f=8000.0} }, - { MATROSKA_ID_AUDIOOUTSAMPLINGFREQ,EBML_FLOAT,0,offsetof(MatroskaTrackAudio,out_samplerate) }, - { MATROSKA_ID_AUDIOBITDEPTH, EBML_UINT, 0, offsetof(MatroskaTrackAudio,bitdepth) }, - { MATROSKA_ID_AUDIOCHANNELS, EBML_UINT, 0, offsetof(MatroskaTrackAudio,channels), {.u=1} }, - { 0 } -}; - -static EbmlSyntax matroska_track_encoding_compression[] = { - { MATROSKA_ID_ENCODINGCOMPALGO, EBML_UINT, 0, offsetof(MatroskaTrackCompression,algo), {.u=0} }, - { MATROSKA_ID_ENCODINGCOMPSETTINGS,EBML_BIN, 0, offsetof(MatroskaTrackCompression,settings) }, - { 0 } -}; - -static EbmlSyntax matroska_track_encoding_encryption[] = { - { MATROSKA_ID_ENCODINGENCALGO, EBML_UINT, 0, offsetof(MatroskaTrackEncryption,algo), {.u=0} }, - { MATROSKA_ID_ENCODINGENCKEYID, EBML_BIN, 0, offsetof(MatroskaTrackEncryption,key_id) }, - { MATROSKA_ID_ENCODINGENCAESSETTINGS, EBML_NONE }, - { MATROSKA_ID_ENCODINGSIGALGO, EBML_NONE }, - { MATROSKA_ID_ENCODINGSIGHASHALGO, EBML_NONE }, - { MATROSKA_ID_ENCODINGSIGKEYID, EBML_NONE }, - { MATROSKA_ID_ENCODINGSIGNATURE, EBML_NONE }, - { 0 } -}; -static EbmlSyntax matroska_track_encoding[] = { - { MATROSKA_ID_ENCODINGSCOPE, EBML_UINT, 0, offsetof(MatroskaTrackEncoding,scope), {.u=1} }, - { MATROSKA_ID_ENCODINGTYPE, EBML_UINT, 0, offsetof(MatroskaTrackEncoding,type), {.u=0} }, - { MATROSKA_ID_ENCODINGCOMPRESSION,EBML_NEST, 0, offsetof(MatroskaTrackEncoding,compression), {.n=matroska_track_encoding_compression} }, - { MATROSKA_ID_ENCODINGENCRYPTION, EBML_NEST, 0, offsetof(MatroskaTrackEncoding,encryption), {.n=matroska_track_encoding_encryption} }, - { MATROSKA_ID_ENCODINGORDER, EBML_NONE }, - { 0 } -}; - -static EbmlSyntax matroska_track_encodings[] = { - { MATROSKA_ID_TRACKCONTENTENCODING, EBML_NEST, sizeof(MatroskaTrackEncoding), offsetof(MatroskaTrack,encodings), {.n=matroska_track_encoding} }, - { 0 } -}; - -static EbmlSyntax matroska_track_plane[] = { - { MATROSKA_ID_TRACKPLANEUID, EBML_UINT, 0, offsetof(MatroskaTrackPlane,uid) }, - { MATROSKA_ID_TRACKPLANETYPE, EBML_UINT, 0, offsetof(MatroskaTrackPlane,type) }, - { 0 } -}; - -static EbmlSyntax matroska_track_combine_planes[] = { - { MATROSKA_ID_TRACKPLANE, EBML_NEST, sizeof(MatroskaTrackPlane), offsetof(MatroskaTrackOperation,combine_planes), {.n=matroska_track_plane} }, - { 0 } -}; - -static EbmlSyntax matroska_track_operation[] = { - { MATROSKA_ID_TRACKCOMBINEPLANES, EBML_NEST, 0, 0, {.n=matroska_track_combine_planes} }, - { 0 } -}; - -static EbmlSyntax matroska_track[] = { - { MATROSKA_ID_TRACKNUMBER, EBML_UINT, 0, offsetof(MatroskaTrack,num) }, - { MATROSKA_ID_TRACKNAME, EBML_UTF8, 0, offsetof(MatroskaTrack,name) }, - { MATROSKA_ID_TRACKUID, EBML_UINT, 0, offsetof(MatroskaTrack,uid) }, - { MATROSKA_ID_TRACKTYPE, EBML_UINT, 0, offsetof(MatroskaTrack,type) }, - { MATROSKA_ID_CODECID, EBML_STR, 0, offsetof(MatroskaTrack,codec_id) }, - { MATROSKA_ID_CODECPRIVATE, EBML_BIN, 0, offsetof(MatroskaTrack,codec_priv) }, - { MATROSKA_ID_TRACKLANGUAGE, EBML_UTF8, 0, offsetof(MatroskaTrack,language), {.s="eng"} }, - { MATROSKA_ID_TRACKDEFAULTDURATION, EBML_UINT, 0, offsetof(MatroskaTrack,default_duration) }, - { MATROSKA_ID_TRACKTIMECODESCALE, EBML_FLOAT,0, offsetof(MatroskaTrack,time_scale), {.f=1.0} }, - { MATROSKA_ID_TRACKFLAGDEFAULT, EBML_UINT, 0, offsetof(MatroskaTrack,flag_default), {.u=1} }, - { MATROSKA_ID_TRACKFLAGFORCED, EBML_UINT, 0, offsetof(MatroskaTrack,flag_forced), {.u=0} }, - { MATROSKA_ID_TRACKVIDEO, EBML_NEST, 0, offsetof(MatroskaTrack,video), {.n=matroska_track_video} }, - { MATROSKA_ID_TRACKAUDIO, EBML_NEST, 0, offsetof(MatroskaTrack,audio), {.n=matroska_track_audio} }, - { MATROSKA_ID_TRACKOPERATION, EBML_NEST, 0, offsetof(MatroskaTrack,operation), {.n=matroska_track_operation} }, - { MATROSKA_ID_TRACKCONTENTENCODINGS,EBML_NEST, 0, 0, {.n=matroska_track_encodings} }, - { MATROSKA_ID_TRACKMAXBLKADDID, EBML_UINT, 0, offsetof(MatroskaTrack,max_block_additional_id) }, - { MATROSKA_ID_TRACKFLAGENABLED, EBML_NONE }, - { MATROSKA_ID_TRACKFLAGLACING, EBML_NONE }, - { MATROSKA_ID_CODECNAME, EBML_NONE }, - { MATROSKA_ID_CODECDECODEALL, EBML_NONE }, - { MATROSKA_ID_CODECINFOURL, EBML_NONE }, - { MATROSKA_ID_CODECDOWNLOADURL, EBML_NONE }, - { MATROSKA_ID_TRACKMINCACHE, EBML_NONE }, - { MATROSKA_ID_TRACKMAXCACHE, EBML_NONE }, - { 0 } -}; - -static EbmlSyntax matroska_tracks[] = { - { MATROSKA_ID_TRACKENTRY, EBML_NEST, sizeof(MatroskaTrack), offsetof(MatroskaDemuxContext,tracks), {.n=matroska_track} }, - { 0 } -}; - -static EbmlSyntax matroska_attachment[] = { - { MATROSKA_ID_FILEUID, EBML_UINT, 0, offsetof(MatroskaAttachement,uid) }, - { MATROSKA_ID_FILENAME, EBML_UTF8, 0, offsetof(MatroskaAttachement,filename) }, - { MATROSKA_ID_FILEMIMETYPE, EBML_STR, 0, offsetof(MatroskaAttachement,mime) }, - { MATROSKA_ID_FILEDATA, EBML_BIN, 0, offsetof(MatroskaAttachement,bin) }, - { MATROSKA_ID_FILEDESC, EBML_NONE }, - { 0 } -}; - -static EbmlSyntax matroska_attachments[] = { - { MATROSKA_ID_ATTACHEDFILE, EBML_NEST, sizeof(MatroskaAttachement), offsetof(MatroskaDemuxContext,attachments), {.n=matroska_attachment} }, - { 0 } -}; - -static EbmlSyntax matroska_chapter_display[] = { - { MATROSKA_ID_CHAPSTRING, EBML_UTF8, 0, offsetof(MatroskaChapter,title) }, - { MATROSKA_ID_CHAPLANG, EBML_NONE }, - { 0 } -}; - -static EbmlSyntax matroska_chapter_entry[] = { - { MATROSKA_ID_CHAPTERTIMESTART, EBML_UINT, 0, offsetof(MatroskaChapter,start), {.u=AV_NOPTS_VALUE} }, - { MATROSKA_ID_CHAPTERTIMEEND, EBML_UINT, 0, offsetof(MatroskaChapter,end), {.u=AV_NOPTS_VALUE} }, - { MATROSKA_ID_CHAPTERUID, EBML_UINT, 0, offsetof(MatroskaChapter,uid) }, - { MATROSKA_ID_CHAPTERDISPLAY, EBML_NEST, 0, 0, {.n=matroska_chapter_display} }, - { MATROSKA_ID_CHAPTERFLAGHIDDEN, EBML_NONE }, - { MATROSKA_ID_CHAPTERFLAGENABLED, EBML_NONE }, - { MATROSKA_ID_CHAPTERPHYSEQUIV, EBML_NONE }, - { MATROSKA_ID_CHAPTERATOM, EBML_NONE }, - { 0 } -}; - -static EbmlSyntax matroska_chapter[] = { - { MATROSKA_ID_CHAPTERATOM, EBML_NEST, sizeof(MatroskaChapter), offsetof(MatroskaDemuxContext,chapters), {.n=matroska_chapter_entry} }, - { MATROSKA_ID_EDITIONUID, EBML_NONE }, - { MATROSKA_ID_EDITIONFLAGHIDDEN, EBML_NONE }, - { MATROSKA_ID_EDITIONFLAGDEFAULT, EBML_NONE }, - { MATROSKA_ID_EDITIONFLAGORDERED, EBML_NONE }, - { 0 } -}; - -static EbmlSyntax matroska_chapters[] = { - { MATROSKA_ID_EDITIONENTRY, EBML_NEST, 0, 0, {.n=matroska_chapter} }, - { 0 } -}; - -static EbmlSyntax matroska_index_pos[] = { - { MATROSKA_ID_CUETRACK, EBML_UINT, 0, offsetof(MatroskaIndexPos,track) }, - { MATROSKA_ID_CUECLUSTERPOSITION, EBML_UINT, 0, offsetof(MatroskaIndexPos,pos) }, - { MATROSKA_ID_CUEBLOCKNUMBER, EBML_NONE }, - { 0 } -}; - -static EbmlSyntax matroska_index_entry[] = { - { MATROSKA_ID_CUETIME, EBML_UINT, 0, offsetof(MatroskaIndex,time) }, - { MATROSKA_ID_CUETRACKPOSITION, EBML_NEST, sizeof(MatroskaIndexPos), offsetof(MatroskaIndex,pos), {.n=matroska_index_pos} }, - { 0 } -}; - -static EbmlSyntax matroska_index[] = { - { MATROSKA_ID_POINTENTRY, EBML_NEST, sizeof(MatroskaIndex), offsetof(MatroskaDemuxContext,index), {.n=matroska_index_entry} }, - { 0 } -}; - -static EbmlSyntax matroska_simpletag[] = { - { MATROSKA_ID_TAGNAME, EBML_UTF8, 0, offsetof(MatroskaTag,name) }, - { MATROSKA_ID_TAGSTRING, EBML_UTF8, 0, offsetof(MatroskaTag,string) }, - { MATROSKA_ID_TAGLANG, EBML_STR, 0, offsetof(MatroskaTag,lang), {.s="und"} }, - { MATROSKA_ID_TAGDEFAULT, EBML_UINT, 0, offsetof(MatroskaTag,def) }, - { MATROSKA_ID_TAGDEFAULT_BUG, EBML_UINT, 0, offsetof(MatroskaTag,def) }, - { MATROSKA_ID_SIMPLETAG, EBML_NEST, sizeof(MatroskaTag), offsetof(MatroskaTag,sub), {.n=matroska_simpletag} }, - { 0 } -}; - -static EbmlSyntax matroska_tagtargets[] = { - { MATROSKA_ID_TAGTARGETS_TYPE, EBML_STR, 0, offsetof(MatroskaTagTarget,type) }, - { MATROSKA_ID_TAGTARGETS_TYPEVALUE, EBML_UINT, 0, offsetof(MatroskaTagTarget,typevalue), {.u=50} }, - { MATROSKA_ID_TAGTARGETS_TRACKUID, EBML_UINT, 0, offsetof(MatroskaTagTarget,trackuid) }, - { MATROSKA_ID_TAGTARGETS_CHAPTERUID,EBML_UINT, 0, offsetof(MatroskaTagTarget,chapteruid) }, - { MATROSKA_ID_TAGTARGETS_ATTACHUID, EBML_UINT, 0, offsetof(MatroskaTagTarget,attachuid) }, - { 0 } -}; - -static EbmlSyntax matroska_tag[] = { - { MATROSKA_ID_SIMPLETAG, EBML_NEST, sizeof(MatroskaTag), offsetof(MatroskaTags,tag), {.n=matroska_simpletag} }, - { MATROSKA_ID_TAGTARGETS, EBML_NEST, 0, offsetof(MatroskaTags,target), {.n=matroska_tagtargets} }, - { 0 } -}; - -static EbmlSyntax matroska_tags[] = { - { MATROSKA_ID_TAG, EBML_NEST, sizeof(MatroskaTags), offsetof(MatroskaDemuxContext,tags), {.n=matroska_tag} }, - { 0 } -}; - -static EbmlSyntax matroska_seekhead_entry[] = { - { MATROSKA_ID_SEEKID, EBML_UINT, 0, offsetof(MatroskaSeekhead,id) }, - { MATROSKA_ID_SEEKPOSITION, EBML_UINT, 0, offsetof(MatroskaSeekhead,pos), {.u=-1} }, - { 0 } -}; - -static EbmlSyntax matroska_seekhead[] = { - { MATROSKA_ID_SEEKENTRY, EBML_NEST, sizeof(MatroskaSeekhead), offsetof(MatroskaDemuxContext,seekhead), {.n=matroska_seekhead_entry} }, - { 0 } -}; - -static EbmlSyntax matroska_segment[] = { - { MATROSKA_ID_INFO, EBML_NEST, 0, 0, {.n=matroska_info } }, - { MATROSKA_ID_TRACKS, EBML_NEST, 0, 0, {.n=matroska_tracks } }, - { MATROSKA_ID_ATTACHMENTS, EBML_NEST, 0, 0, {.n=matroska_attachments} }, - { MATROSKA_ID_CHAPTERS, EBML_NEST, 0, 0, {.n=matroska_chapters } }, - { MATROSKA_ID_CUES, EBML_NEST, 0, 0, {.n=matroska_index } }, - { MATROSKA_ID_TAGS, EBML_NEST, 0, 0, {.n=matroska_tags } }, - { MATROSKA_ID_SEEKHEAD, EBML_NEST, 0, 0, {.n=matroska_seekhead } }, - { MATROSKA_ID_CLUSTER, EBML_STOP }, - { 0 } -}; - -static EbmlSyntax matroska_segments[] = { - { MATROSKA_ID_SEGMENT, EBML_NEST, 0, 0, {.n=matroska_segment } }, - { 0 } -}; - -static EbmlSyntax matroska_blockmore[] = { - { MATROSKA_ID_BLOCKADDID, EBML_UINT, 0, offsetof(MatroskaBlock,additional_id) }, - { MATROSKA_ID_BLOCKADDITIONAL, EBML_BIN, 0, offsetof(MatroskaBlock,additional) }, - { 0 } -}; - -static EbmlSyntax matroska_blockadditions[] = { - { MATROSKA_ID_BLOCKMORE, EBML_NEST, 0, 0, {.n=matroska_blockmore} }, - { 0 } -}; - -static EbmlSyntax matroska_blockgroup[] = { - { MATROSKA_ID_BLOCK, EBML_BIN, 0, offsetof(MatroskaBlock,bin) }, - { MATROSKA_ID_BLOCKADDITIONS, EBML_NEST, 0, 0, {.n=matroska_blockadditions} }, - { MATROSKA_ID_SIMPLEBLOCK, EBML_BIN, 0, offsetof(MatroskaBlock,bin) }, - { MATROSKA_ID_BLOCKDURATION, EBML_UINT, 0, offsetof(MatroskaBlock,duration) }, - { MATROSKA_ID_BLOCKREFERENCE, EBML_UINT, 0, offsetof(MatroskaBlock,reference) }, - { 1, EBML_UINT, 0, offsetof(MatroskaBlock,non_simple), {.u=1} }, - { 0 } -}; - -static EbmlSyntax matroska_cluster[] = { - { MATROSKA_ID_CLUSTERTIMECODE,EBML_UINT,0, offsetof(MatroskaCluster,timecode) }, - { MATROSKA_ID_BLOCKGROUP, EBML_NEST, sizeof(MatroskaBlock), offsetof(MatroskaCluster,blocks), {.n=matroska_blockgroup} }, - { MATROSKA_ID_SIMPLEBLOCK, EBML_PASS, sizeof(MatroskaBlock), offsetof(MatroskaCluster,blocks), {.n=matroska_blockgroup} }, - { MATROSKA_ID_CLUSTERPOSITION,EBML_NONE }, - { MATROSKA_ID_CLUSTERPREVSIZE,EBML_NONE }, - { 0 } -}; - -static EbmlSyntax matroska_clusters[] = { - { MATROSKA_ID_CLUSTER, EBML_NEST, 0, 0, {.n=matroska_cluster} }, - { MATROSKA_ID_INFO, EBML_NONE }, - { MATROSKA_ID_CUES, EBML_NONE }, - { MATROSKA_ID_TAGS, EBML_NONE }, - { MATROSKA_ID_SEEKHEAD, EBML_NONE }, - { 0 } -}; - -static EbmlSyntax matroska_cluster_incremental_parsing[] = { - { MATROSKA_ID_CLUSTERTIMECODE,EBML_UINT,0, offsetof(MatroskaCluster,timecode) }, - { MATROSKA_ID_BLOCKGROUP, EBML_NEST, sizeof(MatroskaBlock), offsetof(MatroskaCluster,blocks), {.n=matroska_blockgroup} }, - { MATROSKA_ID_SIMPLEBLOCK, EBML_PASS, sizeof(MatroskaBlock), offsetof(MatroskaCluster,blocks), {.n=matroska_blockgroup} }, - { MATROSKA_ID_CLUSTERPOSITION,EBML_NONE }, - { MATROSKA_ID_CLUSTERPREVSIZE,EBML_NONE }, - { MATROSKA_ID_INFO, EBML_NONE }, - { MATROSKA_ID_CUES, EBML_NONE }, - { MATROSKA_ID_TAGS, EBML_NONE }, - { MATROSKA_ID_SEEKHEAD, EBML_NONE }, - { MATROSKA_ID_CLUSTER, EBML_STOP }, - { 0 } -}; - -static EbmlSyntax matroska_cluster_incremental[] = { - { MATROSKA_ID_CLUSTERTIMECODE,EBML_UINT,0, offsetof(MatroskaCluster,timecode) }, - { MATROSKA_ID_BLOCKGROUP, EBML_STOP }, - { MATROSKA_ID_SIMPLEBLOCK, EBML_STOP }, - { MATROSKA_ID_CLUSTERPOSITION,EBML_NONE }, - { MATROSKA_ID_CLUSTERPREVSIZE,EBML_NONE }, - { 0 } -}; - -static EbmlSyntax matroska_clusters_incremental[] = { - { MATROSKA_ID_CLUSTER, EBML_NEST, 0, 0, {.n=matroska_cluster_incremental} }, - { MATROSKA_ID_INFO, EBML_NONE }, - { MATROSKA_ID_CUES, EBML_NONE }, - { MATROSKA_ID_TAGS, EBML_NONE }, - { MATROSKA_ID_SEEKHEAD, EBML_NONE }, - { 0 } -}; - -static const char *const matroska_doctypes[] = { "matroska", "webm" }; - -static int matroska_resync(MatroskaDemuxContext *matroska, int64_t last_pos) -{ - AVIOContext *pb = matroska->ctx->pb; - uint32_t id; - matroska->current_id = 0; - matroska->num_levels = 0; - - // seek to next position to resync from - if (avio_seek(pb, last_pos + 1, SEEK_SET) < 0 || avio_tell(pb) <= last_pos) - goto eof; - - id = avio_rb32(pb); - - // try to find a toplevel element - while (!url_feof(pb)) { - if (id == MATROSKA_ID_INFO || id == MATROSKA_ID_TRACKS || - id == MATROSKA_ID_CUES || id == MATROSKA_ID_TAGS || - id == MATROSKA_ID_SEEKHEAD || id == MATROSKA_ID_ATTACHMENTS || - id == MATROSKA_ID_CLUSTER || id == MATROSKA_ID_CHAPTERS) - { - matroska->current_id = id; - return 0; - } - id = (id << 8) | avio_r8(pb); - } -eof: - matroska->done = 1; - return AVERROR_EOF; -} - -/* - * Return: Whether we reached the end of a level in the hierarchy or not. - */ -static int ebml_level_end(MatroskaDemuxContext *matroska) -{ - AVIOContext *pb = matroska->ctx->pb; - int64_t pos = avio_tell(pb); - - if (matroska->num_levels > 0) { - MatroskaLevel *level = &matroska->levels[matroska->num_levels - 1]; - if (pos - level->start >= level->length || matroska->current_id) { - matroska->num_levels--; - return 1; - } - } - return 0; -} - -/* - * Read: an "EBML number", which is defined as a variable-length - * array of bytes. The first byte indicates the length by giving a - * number of 0-bits followed by a one. The position of the first - * "one" bit inside the first byte indicates the length of this - * number. - * Returns: number of bytes read, < 0 on error - */ -static int ebml_read_num(MatroskaDemuxContext *matroska, AVIOContext *pb, - int max_size, uint64_t *number) -{ - int read = 1, n = 1; - uint64_t total = 0; - - /* The first byte tells us the length in bytes - avio_r8() can normally - * return 0, but since that's not a valid first ebmlID byte, we can - * use it safely here to catch EOS. */ - if (!(total = avio_r8(pb))) { - /* we might encounter EOS here */ - if (!url_feof(pb)) { - int64_t pos = avio_tell(pb); - av_log(matroska->ctx, AV_LOG_ERROR, - "Read error at pos. %"PRIu64" (0x%"PRIx64")\n", - pos, pos); - return pb->error ? pb->error : AVERROR(EIO); - } - return AVERROR_EOF; - } - - /* get the length of the EBML number */ - read = 8 - ff_log2_tab[total]; - if (read > max_size) { - int64_t pos = avio_tell(pb) - 1; - av_log(matroska->ctx, AV_LOG_ERROR, - "Invalid EBML number size tag 0x%02x at pos %"PRIu64" (0x%"PRIx64")\n", - (uint8_t) total, pos, pos); - return AVERROR_INVALIDDATA; - } - - /* read out length */ - total ^= 1 << ff_log2_tab[total]; - while (n++ < read) - total = (total << 8) | avio_r8(pb); - - *number = total; - - return read; -} - -/** - * Read a EBML length value. - * This needs special handling for the "unknown length" case which has multiple - * encodings. - */ -static int ebml_read_length(MatroskaDemuxContext *matroska, AVIOContext *pb, - uint64_t *number) -{ - int res = ebml_read_num(matroska, pb, 8, number); - if (res > 0 && *number + 1 == 1ULL << (7 * res)) - *number = 0xffffffffffffffULL; - return res; -} - -/* - * Read the next element as an unsigned int. - * 0 is success, < 0 is failure. - */ -static int ebml_read_uint(AVIOContext *pb, int size, uint64_t *num) -{ - int n = 0; - - if (size > 8) - return AVERROR_INVALIDDATA; - - /* big-endian ordering; build up number */ - *num = 0; - while (n++ < size) - *num = (*num << 8) | avio_r8(pb); - - return 0; -} - -/* - * Read the next element as a float. - * 0 is success, < 0 is failure. - */ -static int ebml_read_float(AVIOContext *pb, int size, double *num) -{ - if (size == 0) { - *num = 0; - } else if (size == 4) { - *num = av_int2float(avio_rb32(pb)); - } else if (size == 8){ - *num = av_int2double(avio_rb64(pb)); - } else - return AVERROR_INVALIDDATA; - - return 0; -} - -/* - * Read the next element as an ASCII string. - * 0 is success, < 0 is failure. - */ -static int ebml_read_ascii(AVIOContext *pb, int size, char **str) -{ - char *res; - - /* EBML strings are usually not 0-terminated, so we allocate one - * byte more, read the string and NULL-terminate it ourselves. */ - if (!(res = av_malloc(size + 1))) - return AVERROR(ENOMEM); - if (avio_read(pb, (uint8_t *) res, size) != size) { - av_free(res); - return AVERROR(EIO); - } - (res)[size] = '\0'; - av_free(*str); - *str = res; - - return 0; -} - -/* - * Read the next element as binary data. - * 0 is success, < 0 is failure. - */ -static int ebml_read_binary(AVIOContext *pb, int length, EbmlBin *bin) -{ - av_fast_padded_malloc(&bin->data, &bin->size, length); - if (!bin->data) - return AVERROR(ENOMEM); - - bin->size = length; - bin->pos = avio_tell(pb); - if (avio_read(pb, bin->data, length) != length) { - av_freep(&bin->data); - bin->size = 0; - return AVERROR(EIO); - } - - return 0; -} - -/* - * Read the next element, but only the header. The contents - * are supposed to be sub-elements which can be read separately. - * 0 is success, < 0 is failure. - */ -static int ebml_read_master(MatroskaDemuxContext *matroska, uint64_t length) -{ - AVIOContext *pb = matroska->ctx->pb; - MatroskaLevel *level; - - if (matroska->num_levels >= EBML_MAX_DEPTH) { - av_log(matroska->ctx, AV_LOG_ERROR, - "File moves beyond max. allowed depth (%d)\n", EBML_MAX_DEPTH); - return AVERROR(ENOSYS); - } - - level = &matroska->levels[matroska->num_levels++]; - level->start = avio_tell(pb); - level->length = length; - - return 0; -} - -/* - * Read signed/unsigned "EBML" numbers. - * Return: number of bytes processed, < 0 on error - */ -static int matroska_ebmlnum_uint(MatroskaDemuxContext *matroska, - uint8_t *data, uint32_t size, uint64_t *num) -{ - AVIOContext pb; - ffio_init_context(&pb, data, size, 0, NULL, NULL, NULL, NULL); - return ebml_read_num(matroska, &pb, FFMIN(size, 8), num); -} - -/* - * Same as above, but signed. - */ -static int matroska_ebmlnum_sint(MatroskaDemuxContext *matroska, - uint8_t *data, uint32_t size, int64_t *num) -{ - uint64_t unum; - int res; - - /* read as unsigned number first */ - if ((res = matroska_ebmlnum_uint(matroska, data, size, &unum)) < 0) - return res; - - /* make signed (weird way) */ - *num = unum - ((1LL << (7*res - 1)) - 1); - - return res; -} - -static int ebml_parse_elem(MatroskaDemuxContext *matroska, - EbmlSyntax *syntax, void *data); - -static int ebml_parse_id(MatroskaDemuxContext *matroska, EbmlSyntax *syntax, - uint32_t id, void *data) -{ - int i; - for (i=0; syntax[i].id; i++) - if (id == syntax[i].id) - break; - if (!syntax[i].id && id == MATROSKA_ID_CLUSTER && - matroska->num_levels > 0 && - matroska->levels[matroska->num_levels-1].length == 0xffffffffffffff) - return 0; // we reached the end of an unknown size cluster - if (!syntax[i].id && id != EBML_ID_VOID && id != EBML_ID_CRC32) { - av_log(matroska->ctx, AV_LOG_INFO, "Unknown entry 0x%X\n", id); - if (matroska->ctx->error_recognition & AV_EF_EXPLODE) - return AVERROR_INVALIDDATA; - } - return ebml_parse_elem(matroska, &syntax[i], data); -} - -static int ebml_parse(MatroskaDemuxContext *matroska, EbmlSyntax *syntax, - void *data) -{ - if (!matroska->current_id) { - uint64_t id; - int res = ebml_read_num(matroska, matroska->ctx->pb, 4, &id); - if (res < 0) - return res; - matroska->current_id = id | 1 << 7*res; - } - return ebml_parse_id(matroska, syntax, matroska->current_id, data); -} - -static int ebml_parse_nest(MatroskaDemuxContext *matroska, EbmlSyntax *syntax, - void *data) -{ - int i, res = 0; - - for (i=0; syntax[i].id; i++) - switch (syntax[i].type) { - case EBML_UINT: - *(uint64_t *)((char *)data+syntax[i].data_offset) = syntax[i].def.u; - break; - case EBML_FLOAT: - *(double *)((char *)data+syntax[i].data_offset) = syntax[i].def.f; - break; - case EBML_STR: - case EBML_UTF8: - *(char **)((char *)data+syntax[i].data_offset) = av_strdup(syntax[i].def.s); - break; - } - - while (!res && !ebml_level_end(matroska)) - res = ebml_parse(matroska, syntax, data); - - return res; -} - -static int ebml_parse_elem(MatroskaDemuxContext *matroska, - EbmlSyntax *syntax, void *data) -{ - static const uint64_t max_lengths[EBML_TYPE_COUNT] = { - [EBML_UINT] = 8, - [EBML_FLOAT] = 8, - // max. 16 MB for strings - [EBML_STR] = 0x1000000, - [EBML_UTF8] = 0x1000000, - // max. 256 MB for binary data - [EBML_BIN] = 0x10000000, - // no limits for anything else - }; - AVIOContext *pb = matroska->ctx->pb; - uint32_t id = syntax->id; - uint64_t length; - int res; - void *newelem; - - data = (char *)data + syntax->data_offset; - if (syntax->list_elem_size) { - EbmlList *list = data; - newelem = av_realloc(list->elem, (list->nb_elem+1)*syntax->list_elem_size); - if (!newelem) - return AVERROR(ENOMEM); - list->elem = newelem; - data = (char*)list->elem + list->nb_elem*syntax->list_elem_size; - memset(data, 0, syntax->list_elem_size); - list->nb_elem++; - } - - if (syntax->type != EBML_PASS && syntax->type != EBML_STOP) { - matroska->current_id = 0; - if ((res = ebml_read_length(matroska, pb, &length)) < 0) - return res; - if (max_lengths[syntax->type] && length > max_lengths[syntax->type]) { - av_log(matroska->ctx, AV_LOG_ERROR, - "Invalid length 0x%"PRIx64" > 0x%"PRIx64" for syntax element %i\n", - length, max_lengths[syntax->type], syntax->type); - return AVERROR_INVALIDDATA; - } - } - - switch (syntax->type) { - case EBML_UINT: res = ebml_read_uint (pb, length, data); break; - case EBML_FLOAT: res = ebml_read_float (pb, length, data); break; - case EBML_STR: - case EBML_UTF8: res = ebml_read_ascii (pb, length, data); break; - case EBML_BIN: res = ebml_read_binary(pb, length, data); break; - case EBML_NEST: if ((res=ebml_read_master(matroska, length)) < 0) - return res; - if (id == MATROSKA_ID_SEGMENT) - matroska->segment_start = avio_tell(matroska->ctx->pb); - return ebml_parse_nest(matroska, syntax->def.n, data); - case EBML_PASS: return ebml_parse_id(matroska, syntax->def.n, id, data); - case EBML_STOP: return 1; - default: - if(ffio_limit(pb, length) != length) - return AVERROR(EIO); - return avio_skip(pb,length)<0 ? AVERROR(EIO) : 0; - } - if (res == AVERROR_INVALIDDATA) - av_log(matroska->ctx, AV_LOG_ERROR, "Invalid element\n"); - else if (res == AVERROR(EIO)) - av_log(matroska->ctx, AV_LOG_ERROR, "Read error\n"); - return res; -} - -static void ebml_free(EbmlSyntax *syntax, void *data) -{ - int i, j; - for (i=0; syntax[i].id; i++) { - void *data_off = (char *)data + syntax[i].data_offset; - switch (syntax[i].type) { - case EBML_STR: - case EBML_UTF8: av_freep(data_off); break; - case EBML_BIN: av_freep(&((EbmlBin *)data_off)->data); break; - case EBML_NEST: - if (syntax[i].list_elem_size) { - EbmlList *list = data_off; - char *ptr = list->elem; - for (j=0; jnb_elem; j++, ptr+=syntax[i].list_elem_size) - ebml_free(syntax[i].def.n, ptr); - av_free(list->elem); - } else - ebml_free(syntax[i].def.n, data_off); - default: break; - } - } -} - - -/* - * Autodetecting... - */ -static int matroska_probe(AVProbeData *p) -{ - uint64_t total = 0; - int len_mask = 0x80, size = 1, n = 1, i; - - /* EBML header? */ - if (AV_RB32(p->buf) != EBML_ID_HEADER) - return 0; - - /* length of header */ - total = p->buf[4]; - while (size <= 8 && !(total & len_mask)) { - size++; - len_mask >>= 1; - } - if (size > 8) - return 0; - total &= (len_mask - 1); - while (n < size) - total = (total << 8) | p->buf[4 + n++]; - - /* Does the probe data contain the whole header? */ - if (p->buf_size < 4 + size + total) - return 0; - - /* The header should contain a known document type. For now, - * we don't parse the whole header but simply check for the - * availability of that array of characters inside the header. - * Not fully fool-proof, but good enough. */ - for (i = 0; i < FF_ARRAY_ELEMS(matroska_doctypes); i++) { - int probelen = strlen(matroska_doctypes[i]); - if (total < probelen) - continue; - for (n = 4+size; n <= 4+size+total-probelen; n++) - if (!memcmp(p->buf+n, matroska_doctypes[i], probelen)) - return AVPROBE_SCORE_MAX; - } - - // probably valid EBML header but no recognized doctype - return AVPROBE_SCORE_MAX/2; -} - -static MatroskaTrack *matroska_find_track_by_num(MatroskaDemuxContext *matroska, - int num) -{ - MatroskaTrack *tracks = matroska->tracks.elem; - int i; - - for (i=0; i < matroska->tracks.nb_elem; i++) - if (tracks[i].num == num) - return &tracks[i]; - - av_log(matroska->ctx, AV_LOG_ERROR, "Invalid track number %d\n", num); - return NULL; -} - -static int matroska_decode_buffer(uint8_t** buf, int* buf_size, - MatroskaTrack *track) -{ - MatroskaTrackEncoding *encodings = track->encodings.elem; - uint8_t* data = *buf; - int isize = *buf_size; - uint8_t* pkt_data = NULL; - uint8_t av_unused *newpktdata; - int pkt_size = isize; - int result = 0; - int olen; - - if (pkt_size >= 10000000U) - return AVERROR_INVALIDDATA; - - switch (encodings[0].compression.algo) { - case MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP: { - int header_size = encodings[0].compression.settings.size; - uint8_t *header = encodings[0].compression.settings.data; - - if (header_size && !header) { - av_log(NULL, AV_LOG_ERROR, "Compression size but no data in headerstrip\n"); - return -1; - } - - if (!header_size) - return 0; - - pkt_size = isize + header_size; - pkt_data = av_malloc(pkt_size); - if (!pkt_data) - return AVERROR(ENOMEM); - - memcpy(pkt_data, header, header_size); - memcpy(pkt_data + header_size, data, isize); - break; - } -#if CONFIG_LZO - case MATROSKA_TRACK_ENCODING_COMP_LZO: - do { - olen = pkt_size *= 3; - newpktdata = av_realloc(pkt_data, pkt_size + AV_LZO_OUTPUT_PADDING); - if (!newpktdata) { - result = AVERROR(ENOMEM); - goto failed; - } - pkt_data = newpktdata; - result = av_lzo1x_decode(pkt_data, &olen, data, &isize); - } while (result==AV_LZO_OUTPUT_FULL && pkt_size<10000000); - if (result) { - result = AVERROR_INVALIDDATA; - goto failed; - } - pkt_size -= olen; - break; -#endif -#if CONFIG_ZLIB - case MATROSKA_TRACK_ENCODING_COMP_ZLIB: { - z_stream zstream = {0}; - if (inflateInit(&zstream) != Z_OK) - return -1; - zstream.next_in = data; - zstream.avail_in = isize; - do { - pkt_size *= 3; - newpktdata = av_realloc(pkt_data, pkt_size); - if (!newpktdata) { - inflateEnd(&zstream); - goto failed; - } - pkt_data = newpktdata; - zstream.avail_out = pkt_size - zstream.total_out; - zstream.next_out = pkt_data + zstream.total_out; - if (pkt_data) { - result = inflate(&zstream, Z_NO_FLUSH); - } else - result = Z_MEM_ERROR; - } while (result==Z_OK && pkt_size<10000000); - pkt_size = zstream.total_out; - inflateEnd(&zstream); - if (result != Z_STREAM_END) { - if (result == Z_MEM_ERROR) - result = AVERROR(ENOMEM); - else - result = AVERROR_INVALIDDATA; - goto failed; - } - break; - } -#endif -#if CONFIG_BZLIB - case MATROSKA_TRACK_ENCODING_COMP_BZLIB: { - bz_stream bzstream = {0}; - if (BZ2_bzDecompressInit(&bzstream, 0, 0) != BZ_OK) - return -1; - bzstream.next_in = data; - bzstream.avail_in = isize; - do { - pkt_size *= 3; - newpktdata = av_realloc(pkt_data, pkt_size); - if (!newpktdata) { - BZ2_bzDecompressEnd(&bzstream); - goto failed; - } - pkt_data = newpktdata; - bzstream.avail_out = pkt_size - bzstream.total_out_lo32; - bzstream.next_out = pkt_data + bzstream.total_out_lo32; - if (pkt_data) { - result = BZ2_bzDecompress(&bzstream); - } else - result = BZ_MEM_ERROR; - } while (result==BZ_OK && pkt_size<10000000); - pkt_size = bzstream.total_out_lo32; - BZ2_bzDecompressEnd(&bzstream); - if (result != BZ_STREAM_END) { - if (result == BZ_MEM_ERROR) - result = AVERROR(ENOMEM); - else - result = AVERROR_INVALIDDATA; - goto failed; - } - break; - } -#endif - default: - return AVERROR_INVALIDDATA; - } - - *buf = pkt_data; - *buf_size = pkt_size; - return 0; - failed: - av_free(pkt_data); - return result; -} - -static void matroska_fix_ass_packet(MatroskaDemuxContext *matroska, - AVPacket *pkt, uint64_t display_duration) -{ - AVBufferRef *line; - char *layer, *ptr = pkt->data, *end = ptr+pkt->size; - for (; *ptr!=',' && ptrpts + display_duration; - int sc = matroska->time_scale * pkt->pts / 10000000; - int ec = matroska->time_scale * end_pts / 10000000; - int sh, sm, ss, eh, em, es, len; - sh = sc/360000; sc -= 360000*sh; - sm = sc/ 6000; sc -= 6000*sm; - ss = sc/ 100; sc -= 100*ss; - eh = ec/360000; ec -= 360000*eh; - em = ec/ 6000; ec -= 6000*em; - es = ec/ 100; ec -= 100*es; - *ptr++ = '\0'; - len = 50 + end-ptr + FF_INPUT_BUFFER_PADDING_SIZE; - if (!(line = av_buffer_alloc(len))) - return; - snprintf(line->data, len,"Dialogue: %s,%d:%02d:%02d.%02d,%d:%02d:%02d.%02d,%s\r\n", - layer, sh, sm, ss, sc, eh, em, es, ec, ptr); - av_buffer_unref(&pkt->buf); - pkt->buf = line; - pkt->data = line->data; - pkt->size = strlen(line->data); - } -} - -static int matroska_merge_packets(AVPacket *out, AVPacket *in) -{ - int ret = av_grow_packet(out, in->size); - if (ret < 0) - return ret; - - memcpy(out->data + out->size - in->size, in->data, in->size); - - av_free_packet(in); - av_free(in); - return 0; -} - -static void matroska_convert_tag(AVFormatContext *s, EbmlList *list, - AVDictionary **metadata, char *prefix) -{ - MatroskaTag *tags = list->elem; - char key[1024]; - int i; - - for (i=0; i < list->nb_elem; i++) { - const char *lang= (tags[i].lang && strcmp(tags[i].lang, "und")) ? tags[i].lang : NULL; - - if (!tags[i].name) { - av_log(s, AV_LOG_WARNING, "Skipping invalid tag with no TagName.\n"); - continue; - } - if (prefix) snprintf(key, sizeof(key), "%s/%s", prefix, tags[i].name); - else av_strlcpy(key, tags[i].name, sizeof(key)); - if (tags[i].def || !lang) { - av_dict_set(metadata, key, tags[i].string, 0); - if (tags[i].sub.nb_elem) - matroska_convert_tag(s, &tags[i].sub, metadata, key); - } - if (lang) { - av_strlcat(key, "-", sizeof(key)); - av_strlcat(key, lang, sizeof(key)); - av_dict_set(metadata, key, tags[i].string, 0); - if (tags[i].sub.nb_elem) - matroska_convert_tag(s, &tags[i].sub, metadata, key); - } - } - ff_metadata_conv(metadata, NULL, ff_mkv_metadata_conv); -} - -static void matroska_convert_tags(AVFormatContext *s) -{ - MatroskaDemuxContext *matroska = s->priv_data; - MatroskaTags *tags = matroska->tags.elem; - int i, j; - - for (i=0; i < matroska->tags.nb_elem; i++) { - if (tags[i].target.attachuid) { - MatroskaAttachement *attachment = matroska->attachments.elem; - for (j=0; jattachments.nb_elem; j++) - if (attachment[j].uid == tags[i].target.attachuid - && attachment[j].stream) - matroska_convert_tag(s, &tags[i].tag, - &attachment[j].stream->metadata, NULL); - } else if (tags[i].target.chapteruid) { - MatroskaChapter *chapter = matroska->chapters.elem; - for (j=0; jchapters.nb_elem; j++) - if (chapter[j].uid == tags[i].target.chapteruid - && chapter[j].chapter) - matroska_convert_tag(s, &tags[i].tag, - &chapter[j].chapter->metadata, NULL); - } else if (tags[i].target.trackuid) { - MatroskaTrack *track = matroska->tracks.elem; - for (j=0; jtracks.nb_elem; j++) - if (track[j].uid == tags[i].target.trackuid && track[j].stream) - matroska_convert_tag(s, &tags[i].tag, - &track[j].stream->metadata, NULL); - } else { - matroska_convert_tag(s, &tags[i].tag, &s->metadata, - tags[i].target.type); - } - } -} - -static int matroska_parse_seekhead_entry(MatroskaDemuxContext *matroska, int idx) -{ - EbmlList *seekhead_list = &matroska->seekhead; - MatroskaSeekhead *seekhead = seekhead_list->elem; - uint32_t level_up = matroska->level_up; - int64_t before_pos = avio_tell(matroska->ctx->pb); - uint32_t saved_id = matroska->current_id; - MatroskaLevel level; - int64_t offset; - int ret = 0; - - if (idx >= seekhead_list->nb_elem - || seekhead[idx].id == MATROSKA_ID_SEEKHEAD - || seekhead[idx].id == MATROSKA_ID_CLUSTER) - return 0; - - /* seek */ - offset = seekhead[idx].pos + matroska->segment_start; - if (avio_seek(matroska->ctx->pb, offset, SEEK_SET) == offset) { - /* We don't want to lose our seekhead level, so we add - * a dummy. This is a crude hack. */ - if (matroska->num_levels == EBML_MAX_DEPTH) { - av_log(matroska->ctx, AV_LOG_INFO, - "Max EBML element depth (%d) reached, " - "cannot parse further.\n", EBML_MAX_DEPTH); - ret = AVERROR_INVALIDDATA; - } else { - level.start = 0; - level.length = (uint64_t)-1; - matroska->levels[matroska->num_levels] = level; - matroska->num_levels++; - matroska->current_id = 0; - - ret = ebml_parse(matroska, matroska_segment, matroska); - - /* remove dummy level */ - while (matroska->num_levels) { - uint64_t length = matroska->levels[--matroska->num_levels].length; - if (length == (uint64_t)-1) - break; - } - } - } - /* seek back */ - avio_seek(matroska->ctx->pb, before_pos, SEEK_SET); - matroska->level_up = level_up; - matroska->current_id = saved_id; - - return ret; -} - -static void matroska_execute_seekhead(MatroskaDemuxContext *matroska) -{ - EbmlList *seekhead_list = &matroska->seekhead; - int64_t before_pos = avio_tell(matroska->ctx->pb); - int i; - - // we should not do any seeking in the streaming case - if (!matroska->ctx->pb->seekable || - (matroska->ctx->flags & AVFMT_FLAG_IGNIDX)) - return; - - for (i = 0; i < seekhead_list->nb_elem; i++) { - MatroskaSeekhead *seekhead = seekhead_list->elem; - if (seekhead[i].pos <= before_pos) - continue; - - // defer cues parsing until we actually need cue data. - if (seekhead[i].id == MATROSKA_ID_CUES) { - matroska->cues_parsing_deferred = 1; - continue; - } - - if (matroska_parse_seekhead_entry(matroska, i) < 0) { - // mark index as broken - matroska->cues_parsing_deferred = -1; - break; - } - } -} - -static void matroska_add_index_entries(MatroskaDemuxContext *matroska) { - EbmlList *index_list; - MatroskaIndex *index; - int index_scale = 1; - int i, j; - - index_list = &matroska->index; - index = index_list->elem; - if (index_list->nb_elem - && index[0].time > 1E14/matroska->time_scale) { - av_log(matroska->ctx, AV_LOG_WARNING, "Working around broken index.\n"); - index_scale = matroska->time_scale; - } - for (i = 0; i < index_list->nb_elem; i++) { - EbmlList *pos_list = &index[i].pos; - MatroskaIndexPos *pos = pos_list->elem; - for (j = 0; j < pos_list->nb_elem; j++) { - MatroskaTrack *track = matroska_find_track_by_num(matroska, pos[j].track); - if (track && track->stream) - av_add_index_entry(track->stream, - pos[j].pos + matroska->segment_start, - index[i].time/index_scale, 0, 0, - AVINDEX_KEYFRAME); - } - } -} - -static void matroska_parse_cues(MatroskaDemuxContext *matroska) { - EbmlList *seekhead_list = &matroska->seekhead; - MatroskaSeekhead *seekhead = seekhead_list->elem; - int i; - - for (i = 0; i < seekhead_list->nb_elem; i++) - if (seekhead[i].id == MATROSKA_ID_CUES) - break; - assert(i <= seekhead_list->nb_elem); - - if (matroska_parse_seekhead_entry(matroska, i) < 0) - matroska->cues_parsing_deferred = -1; - matroska_add_index_entries(matroska); -} - -static int matroska_aac_profile(char *codec_id) -{ - static const char * const aac_profiles[] = { "MAIN", "LC", "SSR" }; - int profile; - - for (profile=0; profilepriv_data; - EbmlList *attachements_list = &matroska->attachments; - MatroskaAttachement *attachements; - EbmlList *chapters_list = &matroska->chapters; - MatroskaChapter *chapters; - MatroskaTrack *tracks; - uint64_t max_start = 0; - int64_t pos; - Ebml ebml = { 0 }; - AVStream *st; - int i, j, k, res; - - matroska->ctx = s; - - /* First read the EBML header. */ - if (ebml_parse(matroska, ebml_syntax, &ebml) - || ebml.version > EBML_VERSION || ebml.max_size > sizeof(uint64_t) - || ebml.id_length > sizeof(uint32_t) || ebml.doctype_version > 3 || !ebml.doctype) { - av_log(matroska->ctx, AV_LOG_ERROR, - "EBML header using unsupported features\n" - "(EBML version %"PRIu64", doctype %s, doc version %"PRIu64")\n", - ebml.version, ebml.doctype, ebml.doctype_version); - ebml_free(ebml_syntax, &ebml); - return AVERROR_PATCHWELCOME; - } else if (ebml.doctype_version == 3) { - av_log(matroska->ctx, AV_LOG_WARNING, - "EBML header using unsupported features\n" - "(EBML version %"PRIu64", doctype %s, doc version %"PRIu64")\n", - ebml.version, ebml.doctype, ebml.doctype_version); - } - for (i = 0; i < FF_ARRAY_ELEMS(matroska_doctypes); i++) - if (!strcmp(ebml.doctype, matroska_doctypes[i])) - break; - if (i >= FF_ARRAY_ELEMS(matroska_doctypes)) { - av_log(s, AV_LOG_WARNING, "Unknown EBML doctype '%s'\n", ebml.doctype); - if (matroska->ctx->error_recognition & AV_EF_EXPLODE) { - ebml_free(ebml_syntax, &ebml); - return AVERROR_INVALIDDATA; - } - } - ebml_free(ebml_syntax, &ebml); - - /* The next thing is a segment. */ - pos = avio_tell(matroska->ctx->pb); - res = ebml_parse(matroska, matroska_segments, matroska); - // try resyncing until we find a EBML_STOP type element. - while (res != 1) { - res = matroska_resync(matroska, pos); - if (res < 0) - return res; - pos = avio_tell(matroska->ctx->pb); - res = ebml_parse(matroska, matroska_segment, matroska); - } - matroska_execute_seekhead(matroska); - - if (!matroska->time_scale) - matroska->time_scale = 1000000; - if (matroska->duration) - matroska->ctx->duration = matroska->duration * matroska->time_scale - * 1000 / AV_TIME_BASE; - av_dict_set(&s->metadata, "title", matroska->title, 0); - - if (matroska->date_utc.size == 8) - matroska_metadata_creation_time(&s->metadata, AV_RB64(matroska->date_utc.data)); - - tracks = matroska->tracks.elem; - for (i=0; i < matroska->tracks.nb_elem; i++) { - MatroskaTrack *track = &tracks[i]; - enum AVCodecID codec_id = AV_CODEC_ID_NONE; - EbmlList *encodings_list = &track->encodings; - MatroskaTrackEncoding *encodings = encodings_list->elem; - uint8_t *extradata = NULL; - int extradata_size = 0; - int extradata_offset = 0; - uint32_t fourcc = 0; - AVIOContext b; - char* key_id_base64 = NULL; - - /* Apply some sanity checks. */ - if (track->type != MATROSKA_TRACK_TYPE_VIDEO && - track->type != MATROSKA_TRACK_TYPE_AUDIO && - track->type != MATROSKA_TRACK_TYPE_SUBTITLE) { - av_log(matroska->ctx, AV_LOG_INFO, - "Unknown or unsupported track type %"PRIu64"\n", - track->type); - continue; - } - if (track->codec_id == NULL) - continue; - - if (track->type == MATROSKA_TRACK_TYPE_VIDEO) { - if (!track->default_duration && track->video.frame_rate > 0) - track->default_duration = 1000000000/track->video.frame_rate; - if (!track->video.display_width) - track->video.display_width = track->video.pixel_width; - if (!track->video.display_height) - track->video.display_height = track->video.pixel_height; - if (track->video.color_space.size == 4) - fourcc = AV_RL32(track->video.color_space.data); - } else if (track->type == MATROSKA_TRACK_TYPE_AUDIO) { - if (!track->audio.out_samplerate) - track->audio.out_samplerate = track->audio.samplerate; - } - if (encodings_list->nb_elem > 1) { - av_log(matroska->ctx, AV_LOG_ERROR, - "Multiple combined encodings not supported"); - } else if (encodings_list->nb_elem == 1) { - if (encodings[0].type) { - if (encodings[0].encryption.key_id.size > 0) { - /* Save the encryption key id to be stored later as a - metadata tag. */ - const int b64_size = AV_BASE64_SIZE(encodings[0].encryption.key_id.size); - key_id_base64 = av_malloc(b64_size); - if (key_id_base64 == NULL) - return AVERROR(ENOMEM); - - av_base64_encode(key_id_base64, b64_size, - encodings[0].encryption.key_id.data, - encodings[0].encryption.key_id.size); - } else { - encodings[0].scope = 0; - av_log(matroska->ctx, AV_LOG_ERROR, - "Unsupported encoding type"); - } - } else if ( -#if CONFIG_ZLIB - encodings[0].compression.algo != MATROSKA_TRACK_ENCODING_COMP_ZLIB && -#endif -#if CONFIG_BZLIB - encodings[0].compression.algo != MATROSKA_TRACK_ENCODING_COMP_BZLIB && -#endif -#if CONFIG_LZO - encodings[0].compression.algo != MATROSKA_TRACK_ENCODING_COMP_LZO && -#endif - encodings[0].compression.algo != MATROSKA_TRACK_ENCODING_COMP_HEADERSTRIP) { - encodings[0].scope = 0; - av_log(matroska->ctx, AV_LOG_ERROR, - "Unsupported encoding type"); - } else if (track->codec_priv.size && encodings[0].scope&2) { - uint8_t *codec_priv = track->codec_priv.data; - int ret = matroska_decode_buffer(&track->codec_priv.data, - &track->codec_priv.size, - track); - if (ret < 0) { - track->codec_priv.data = NULL; - track->codec_priv.size = 0; - av_log(matroska->ctx, AV_LOG_ERROR, - "Failed to decode codec private data\n"); - } - - if (codec_priv != track->codec_priv.data) - av_free(codec_priv); - } - } - - for(j=0; ff_mkv_codec_tags[j].id != AV_CODEC_ID_NONE; j++){ - if(!strncmp(ff_mkv_codec_tags[j].str, track->codec_id, - strlen(ff_mkv_codec_tags[j].str))){ - codec_id= ff_mkv_codec_tags[j].id; - break; - } - } - - st = track->stream = avformat_new_stream(s, NULL); - if (st == NULL) { - av_free(key_id_base64); - return AVERROR(ENOMEM); - } - - if (key_id_base64) { - /* export encryption key id as base64 metadata tag */ - av_dict_set(&st->metadata, "enc_key_id", key_id_base64, 0); - av_freep(&key_id_base64); - } - - if (!strcmp(track->codec_id, "V_MS/VFW/FOURCC") - && track->codec_priv.size >= 40 - && track->codec_priv.data != NULL) { - track->ms_compat = 1; - fourcc = AV_RL32(track->codec_priv.data + 16); - codec_id = ff_codec_get_id(ff_codec_bmp_tags, fourcc); - extradata_offset = 40; - } else if (!strcmp(track->codec_id, "A_MS/ACM") - && track->codec_priv.size >= 14 - && track->codec_priv.data != NULL) { - int ret; - ffio_init_context(&b, track->codec_priv.data, track->codec_priv.size, - 0, NULL, NULL, NULL, NULL); - ret = ff_get_wav_header(&b, st->codec, track->codec_priv.size); - if (ret < 0) - return ret; - codec_id = st->codec->codec_id; - extradata_offset = FFMIN(track->codec_priv.size, 18); - } else if (!strcmp(track->codec_id, "V_QUICKTIME") - && (track->codec_priv.size >= 86) - && (track->codec_priv.data != NULL)) { - fourcc = AV_RL32(track->codec_priv.data); - codec_id = ff_codec_get_id(ff_codec_movvideo_tags, fourcc); - } else if (codec_id == AV_CODEC_ID_ALAC && track->codec_priv.size && track->codec_priv.size < INT_MAX - 12 - FF_INPUT_BUFFER_PADDING_SIZE) { - /* Only ALAC's magic cookie is stored in Matroska's track headers. - Create the "atom size", "tag", and "tag version" fields the - decoder expects manually. */ - extradata_size = 12 + track->codec_priv.size; - extradata = av_mallocz(extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); - if (extradata == NULL) - return AVERROR(ENOMEM); - AV_WB32(extradata, extradata_size); - memcpy(&extradata[4], "alac", 4); - AV_WB32(&extradata[8], 0); - memcpy(&extradata[12], track->codec_priv.data, track->codec_priv.size); - } else if (codec_id == AV_CODEC_ID_PCM_S16BE) { - switch (track->audio.bitdepth) { - case 8: codec_id = AV_CODEC_ID_PCM_U8; break; - case 24: codec_id = AV_CODEC_ID_PCM_S24BE; break; - case 32: codec_id = AV_CODEC_ID_PCM_S32BE; break; - } - } else if (codec_id == AV_CODEC_ID_PCM_S16LE) { - switch (track->audio.bitdepth) { - case 8: codec_id = AV_CODEC_ID_PCM_U8; break; - case 24: codec_id = AV_CODEC_ID_PCM_S24LE; break; - case 32: codec_id = AV_CODEC_ID_PCM_S32LE; break; - } - } else if (codec_id==AV_CODEC_ID_PCM_F32LE && track->audio.bitdepth==64) { - codec_id = AV_CODEC_ID_PCM_F64LE; - } else if (codec_id == AV_CODEC_ID_AAC && !track->codec_priv.size) { - int profile = matroska_aac_profile(track->codec_id); - int sri = matroska_aac_sri(track->audio.samplerate); - extradata = av_mallocz(5 + FF_INPUT_BUFFER_PADDING_SIZE); - if (extradata == NULL) - return AVERROR(ENOMEM); - extradata[0] = (profile << 3) | ((sri&0x0E) >> 1); - extradata[1] = ((sri&0x01) << 7) | (track->audio.channels<<3); - if (strstr(track->codec_id, "SBR")) { - sri = matroska_aac_sri(track->audio.out_samplerate); - extradata[2] = 0x56; - extradata[3] = 0xE5; - extradata[4] = 0x80 | (sri<<3); - extradata_size = 5; - } else - extradata_size = 2; - } else if (codec_id == AV_CODEC_ID_TTA) { - extradata_size = 30; - extradata = av_mallocz(extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); - if (extradata == NULL) - return AVERROR(ENOMEM); - ffio_init_context(&b, extradata, extradata_size, 1, - NULL, NULL, NULL, NULL); - avio_write(&b, "TTA1", 4); - avio_wl16(&b, 1); - avio_wl16(&b, track->audio.channels); - avio_wl16(&b, track->audio.bitdepth); - avio_wl32(&b, track->audio.out_samplerate); - avio_wl32(&b, matroska->ctx->duration * track->audio.out_samplerate); - } else if (codec_id == AV_CODEC_ID_RV10 || codec_id == AV_CODEC_ID_RV20 || - codec_id == AV_CODEC_ID_RV30 || codec_id == AV_CODEC_ID_RV40) { - extradata_offset = 26; - } else if (codec_id == AV_CODEC_ID_RA_144) { - track->audio.out_samplerate = 8000; - track->audio.channels = 1; - } else if ((codec_id == AV_CODEC_ID_RA_288 || codec_id == AV_CODEC_ID_COOK || - codec_id == AV_CODEC_ID_ATRAC3 || codec_id == AV_CODEC_ID_SIPR) - && track->codec_priv.data) { - int flavor; - - ffio_init_context(&b, track->codec_priv.data,track->codec_priv.size, - 0, NULL, NULL, NULL, NULL); - avio_skip(&b, 22); - flavor = avio_rb16(&b); - track->audio.coded_framesize = avio_rb32(&b); - avio_skip(&b, 12); - track->audio.sub_packet_h = avio_rb16(&b); - track->audio.frame_size = avio_rb16(&b); - track->audio.sub_packet_size = avio_rb16(&b); - track->audio.buf = av_malloc(track->audio.frame_size * track->audio.sub_packet_h); - if (codec_id == AV_CODEC_ID_RA_288) { - st->codec->block_align = track->audio.coded_framesize; - track->codec_priv.size = 0; - } else { - if (codec_id == AV_CODEC_ID_SIPR && flavor < 4) { - const int sipr_bit_rate[4] = { 6504, 8496, 5000, 16000 }; - track->audio.sub_packet_size = ff_sipr_subpk_size[flavor]; - st->codec->bit_rate = sipr_bit_rate[flavor]; - } - st->codec->block_align = track->audio.sub_packet_size; - extradata_offset = 78; - } - } - track->codec_priv.size -= extradata_offset; - - if (codec_id == AV_CODEC_ID_NONE) - av_log(matroska->ctx, AV_LOG_INFO, - "Unknown/unsupported AVCodecID %s.\n", track->codec_id); - - if (track->time_scale < 0.01) - track->time_scale = 1.0; - avpriv_set_pts_info(st, 64, matroska->time_scale*track->time_scale, 1000*1000*1000); /* 64 bit pts in ns */ - - st->codec->codec_id = codec_id; - st->start_time = 0; - if (strcmp(track->language, "und")) - av_dict_set(&st->metadata, "language", track->language, 0); - av_dict_set(&st->metadata, "title", track->name, 0); - - if (track->flag_default) - st->disposition |= AV_DISPOSITION_DEFAULT; - if (track->flag_forced) - st->disposition |= AV_DISPOSITION_FORCED; - - if (!st->codec->extradata) { - if(extradata){ - st->codec->extradata = extradata; - st->codec->extradata_size = extradata_size; - } else if(track->codec_priv.data && track->codec_priv.size > 0){ - st->codec->extradata = av_mallocz(track->codec_priv.size + - FF_INPUT_BUFFER_PADDING_SIZE); - if(st->codec->extradata == NULL) - return AVERROR(ENOMEM); - st->codec->extradata_size = track->codec_priv.size; - memcpy(st->codec->extradata, - track->codec_priv.data + extradata_offset, - track->codec_priv.size); - } - } - - if (track->type == MATROSKA_TRACK_TYPE_VIDEO) { - MatroskaTrackPlane *planes = track->operation.combine_planes.elem; - - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_tag = fourcc; - st->codec->width = track->video.pixel_width; - st->codec->height = track->video.pixel_height; - av_reduce(&st->sample_aspect_ratio.num, - &st->sample_aspect_ratio.den, - st->codec->height * track->video.display_width, - st->codec-> width * track->video.display_height, - 255); - st->need_parsing = AVSTREAM_PARSE_HEADERS; - if (track->default_duration) { - av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den, - 1000000000, track->default_duration, 30000); -#if FF_API_R_FRAME_RATE - st->r_frame_rate = st->avg_frame_rate; -#endif - } - - /* export stereo mode flag as metadata tag */ - if (track->video.stereo_mode && track->video.stereo_mode < MATROSKA_VIDEO_STEREO_MODE_COUNT) - av_dict_set(&st->metadata, "stereo_mode", ff_matroska_video_stereo_mode[track->video.stereo_mode], 0); - - /* export alpha mode flag as metadata tag */ - if (track->video.alpha_mode) - av_dict_set(&st->metadata, "alpha_mode", "1", 0); - - /* if we have virtual track, mark the real tracks */ - for (j=0; j < track->operation.combine_planes.nb_elem; j++) { - char buf[32]; - if (planes[j].type >= MATROSKA_VIDEO_STEREO_PLANE_COUNT) - continue; - snprintf(buf, sizeof(buf), "%s_%d", - ff_matroska_video_stereo_plane[planes[j].type], i); - for (k=0; k < matroska->tracks.nb_elem; k++) - if (planes[j].uid == tracks[k].uid) { - av_dict_set(&s->streams[k]->metadata, - "stereo_mode", buf, 0); - break; - } - } - } else if (track->type == MATROSKA_TRACK_TYPE_AUDIO) { - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->sample_rate = track->audio.out_samplerate; - st->codec->channels = track->audio.channels; - st->codec->bits_per_coded_sample = track->audio.bitdepth; - if (st->codec->codec_id != AV_CODEC_ID_AAC) - st->need_parsing = AVSTREAM_PARSE_HEADERS; - } else if (track->type == MATROSKA_TRACK_TYPE_SUBTITLE) { - st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE; - if (st->codec->codec_id == AV_CODEC_ID_SSA) - matroska->contains_ssa = 1; - } - } - - attachements = attachements_list->elem; - for (j=0; jnb_elem; j++) { - if (!(attachements[j].filename && attachements[j].mime && - attachements[j].bin.data && attachements[j].bin.size > 0)) { - av_log(matroska->ctx, AV_LOG_ERROR, "incomplete attachment\n"); - } else { - AVStream *st = avformat_new_stream(s, NULL); - if (st == NULL) - break; - av_dict_set(&st->metadata, "filename",attachements[j].filename, 0); - av_dict_set(&st->metadata, "mimetype", attachements[j].mime, 0); - st->codec->codec_id = AV_CODEC_ID_NONE; - st->codec->codec_type = AVMEDIA_TYPE_ATTACHMENT; - st->codec->extradata = av_malloc(attachements[j].bin.size + FF_INPUT_BUFFER_PADDING_SIZE); - if(st->codec->extradata == NULL) - break; - st->codec->extradata_size = attachements[j].bin.size; - memcpy(st->codec->extradata, attachements[j].bin.data, attachements[j].bin.size); - - for (i=0; ff_mkv_mime_tags[i].id != AV_CODEC_ID_NONE; i++) { - if (!strncmp(ff_mkv_mime_tags[i].str, attachements[j].mime, - strlen(ff_mkv_mime_tags[i].str))) { - st->codec->codec_id = ff_mkv_mime_tags[i].id; - break; - } - } - attachements[j].stream = st; - } - } - - chapters = chapters_list->elem; - for (i=0; inb_elem; i++) - if (chapters[i].start != AV_NOPTS_VALUE && chapters[i].uid - && (max_start==0 || chapters[i].start > max_start)) { - chapters[i].chapter = - avpriv_new_chapter(s, chapters[i].uid, (AVRational){1, 1000000000}, - chapters[i].start, chapters[i].end, - chapters[i].title); - av_dict_set(&chapters[i].chapter->metadata, - "title", chapters[i].title, 0); - max_start = chapters[i].start; - } - - matroska_add_index_entries(matroska); - - matroska_convert_tags(s); - - return 0; -} - -/* - * Put one packet in an application-supplied AVPacket struct. - * Returns 0 on success or -1 on failure. - */ -static int matroska_deliver_packet(MatroskaDemuxContext *matroska, - AVPacket *pkt) -{ - if (matroska->num_packets > 0) { - memcpy(pkt, matroska->packets[0], sizeof(AVPacket)); - av_free(matroska->packets[0]); - if (matroska->num_packets > 1) { - void *newpackets; - memmove(&matroska->packets[0], &matroska->packets[1], - (matroska->num_packets - 1) * sizeof(AVPacket *)); - newpackets = av_realloc(matroska->packets, - (matroska->num_packets - 1) * sizeof(AVPacket *)); - if (newpackets) - matroska->packets = newpackets; - } else { - av_freep(&matroska->packets); - matroska->prev_pkt = NULL; - } - matroska->num_packets--; - return 0; - } - - return -1; -} - -/* - * Free all packets in our internal queue. - */ -static void matroska_clear_queue(MatroskaDemuxContext *matroska) -{ - matroska->prev_pkt = NULL; - if (matroska->packets) { - int n; - for (n = 0; n < matroska->num_packets; n++) { - av_free_packet(matroska->packets[n]); - av_free(matroska->packets[n]); - } - av_freep(&matroska->packets); - matroska->num_packets = 0; - } -} - -static int matroska_parse_laces(MatroskaDemuxContext *matroska, uint8_t **buf, - int size, int type, - uint32_t **lace_buf, int *laces) -{ - int res = 0, n; - uint8_t *data = *buf; - uint32_t *lace_size; - - if (!type) { - *laces = 1; - *lace_buf = av_mallocz(sizeof(int)); - if (!*lace_buf) - return AVERROR(ENOMEM); - - *lace_buf[0] = size; - return 0; - } - - av_assert0(size > 0); - *laces = *data + 1; - data += 1; - size -= 1; - lace_size = av_mallocz(*laces * sizeof(int)); - if (!lace_size) - return AVERROR(ENOMEM); - - switch (type) { - case 0x1: /* Xiph lacing */ { - uint8_t temp; - uint32_t total = 0; - for (n = 0; res == 0 && n < *laces - 1; n++) { - while (1) { - if (size == 0) { - res = AVERROR_EOF; - break; - } - temp = *data; - lace_size[n] += temp; - data += 1; - size -= 1; - if (temp != 0xff) - break; - } - total += lace_size[n]; - } - if (size <= total) { - res = AVERROR_INVALIDDATA; - break; - } - - lace_size[n] = size - total; - break; - } - - case 0x2: /* fixed-size lacing */ - if (size % (*laces)) { - res = AVERROR_INVALIDDATA; - break; - } - for (n = 0; n < *laces; n++) - lace_size[n] = size / *laces; - break; - - case 0x3: /* EBML lacing */ { - uint64_t num; - uint32_t total; - n = matroska_ebmlnum_uint(matroska, data, size, &num); - if (n < 0) { - av_log(matroska->ctx, AV_LOG_INFO, - "EBML block data error\n"); - res = n; - break; - } - data += n; - size -= n; - total = lace_size[0] = num; - for (n = 1; res == 0 && n < *laces - 1; n++) { - int64_t snum; - int r; - r = matroska_ebmlnum_sint(matroska, data, size, &snum); - if (r < 0) { - av_log(matroska->ctx, AV_LOG_INFO, - "EBML block data error\n"); - res = r; - break; - } - data += r; - size -= r; - lace_size[n] = lace_size[n - 1] + snum; - total += lace_size[n]; - } - if (size <= total) { - res = AVERROR_INVALIDDATA; - break; - } - lace_size[*laces - 1] = size - total; - break; - } - } - - *buf = data; - *lace_buf = lace_size; - - return res; -} - -static int matroska_parse_rm_audio(MatroskaDemuxContext *matroska, - MatroskaTrack *track, - AVStream *st, - uint8_t *data, int size, - uint64_t timecode, - int64_t pos) -{ - int a = st->codec->block_align; - int sps = track->audio.sub_packet_size; - int cfs = track->audio.coded_framesize; - int h = track->audio.sub_packet_h; - int y = track->audio.sub_packet_cnt; - int w = track->audio.frame_size; - int x; - - if (!track->audio.pkt_cnt) { - if (track->audio.sub_packet_cnt == 0) - track->audio.buf_timecode = timecode; - if (st->codec->codec_id == AV_CODEC_ID_RA_288) { - if (size < cfs * h / 2) { - av_log(matroska->ctx, AV_LOG_ERROR, - "Corrupt int4 RM-style audio packet size\n"); - return AVERROR_INVALIDDATA; - } - for (x=0; xaudio.buf+x*2*w+y*cfs, - data+x*cfs, cfs); - } else if (st->codec->codec_id == AV_CODEC_ID_SIPR) { - if (size < w) { - av_log(matroska->ctx, AV_LOG_ERROR, - "Corrupt sipr RM-style audio packet size\n"); - return AVERROR_INVALIDDATA; - } - memcpy(track->audio.buf + y*w, data, w); - } else { - if (size < sps * w / sps || h<=0) { - av_log(matroska->ctx, AV_LOG_ERROR, - "Corrupt generic RM-style audio packet size\n"); - return AVERROR_INVALIDDATA; - } - for (x=0; xaudio.buf+sps*(h*x+((h+1)/2)*(y&1)+(y>>1)), data+x*sps, sps); - } - - if (++track->audio.sub_packet_cnt >= h) { - if (st->codec->codec_id == AV_CODEC_ID_SIPR) - ff_rm_reorder_sipr_data(track->audio.buf, h, w); - track->audio.sub_packet_cnt = 0; - track->audio.pkt_cnt = h*w / a; - } - } - - while (track->audio.pkt_cnt) { - AVPacket *pkt = NULL; - if (!(pkt = av_mallocz(sizeof(AVPacket))) || av_new_packet(pkt, a) < 0){ - av_free(pkt); - return AVERROR(ENOMEM); - } - memcpy(pkt->data, track->audio.buf - + a * (h*w / a - track->audio.pkt_cnt--), a); - pkt->pts = track->audio.buf_timecode; - track->audio.buf_timecode = AV_NOPTS_VALUE; - pkt->pos = pos; - pkt->stream_index = st->index; - dynarray_add(&matroska->packets,&matroska->num_packets,pkt); - } - - return 0; -} -static int matroska_parse_frame(MatroskaDemuxContext *matroska, - MatroskaTrack *track, - AVStream *st, - uint8_t *data, int pkt_size, - uint64_t timecode, uint64_t lace_duration, - int64_t pos, int is_keyframe, - uint8_t *additional, uint64_t additional_id, int additional_size) -{ - MatroskaTrackEncoding *encodings = track->encodings.elem; - uint8_t *pkt_data = data; - int offset = 0, res; - AVPacket *pkt; - - if (encodings && !encodings->type && encodings->scope & 1) { - res = matroska_decode_buffer(&pkt_data, &pkt_size, track); - if (res < 0) - return res; - } - - if (st->codec->codec_id == AV_CODEC_ID_PRORES) - offset = 8; - - pkt = av_mallocz(sizeof(AVPacket)); - /* XXX: prevent data copy... */ - if (av_new_packet(pkt, pkt_size + offset) < 0) { - av_free(pkt); - return AVERROR(ENOMEM); - } - - if (st->codec->codec_id == AV_CODEC_ID_PRORES) { - uint8_t *buf = pkt->data; - bytestream_put_be32(&buf, pkt_size); - bytestream_put_be32(&buf, MKBETAG('i', 'c', 'p', 'f')); - } - - memcpy(pkt->data + offset, pkt_data, pkt_size); - - if (pkt_data != data) - av_free(pkt_data); - - pkt->flags = is_keyframe; - pkt->stream_index = st->index; - - if (additional_size > 0) { - uint8_t *side_data = av_packet_new_side_data(pkt, - AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL, - additional_size + 8); - if(side_data == NULL) { - av_free_packet(pkt); - av_free(pkt); - return AVERROR(ENOMEM); - } - AV_WB64(side_data, additional_id); - memcpy(side_data + 8, additional, additional_size); - } - - if (track->ms_compat) - pkt->dts = timecode; - else - pkt->pts = timecode; - pkt->pos = pos; - if (st->codec->codec_id == AV_CODEC_ID_SUBRIP) { - /* - * For backward compatibility. - * Historically, we have put subtitle duration - * in convergence_duration, on the off chance - * that the time_scale is less than 1us, which - * could result in a 32bit overflow on the - * normal duration field. - */ - pkt->convergence_duration = lace_duration; - } - - if (track->type != MATROSKA_TRACK_TYPE_SUBTITLE || - lace_duration <= INT_MAX) { - /* - * For non subtitle tracks, just store the duration - * as normal. - * - * If it's a subtitle track and duration value does - * not overflow a uint32, then also store it normally. - */ - pkt->duration = lace_duration; - } - - if (st->codec->codec_id == AV_CODEC_ID_SSA) - matroska_fix_ass_packet(matroska, pkt, lace_duration); - - if (matroska->prev_pkt && - timecode != AV_NOPTS_VALUE && - matroska->prev_pkt->pts == timecode && - matroska->prev_pkt->stream_index == st->index && - st->codec->codec_id == AV_CODEC_ID_SSA) - matroska_merge_packets(matroska->prev_pkt, pkt); - else { - dynarray_add(&matroska->packets,&matroska->num_packets,pkt); - matroska->prev_pkt = pkt; - } - - return 0; -} - -static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data, - int size, int64_t pos, uint64_t cluster_time, - uint64_t block_duration, int is_keyframe, - uint8_t *additional, uint64_t additional_id, int additional_size, - int64_t cluster_pos) -{ - uint64_t timecode = AV_NOPTS_VALUE; - MatroskaTrack *track; - int res = 0; - AVStream *st; - int16_t block_time; - uint32_t *lace_size = NULL; - int n, flags, laces = 0; - uint64_t num; - - if ((n = matroska_ebmlnum_uint(matroska, data, size, &num)) < 0) { - av_log(matroska->ctx, AV_LOG_ERROR, "EBML block data error\n"); - return n; - } - data += n; - size -= n; - - track = matroska_find_track_by_num(matroska, num); - if (!track || !track->stream) { - av_log(matroska->ctx, AV_LOG_INFO, - "Invalid stream %"PRIu64" or size %u\n", num, size); - return AVERROR_INVALIDDATA; - } else if (size <= 3) - return 0; - st = track->stream; - if (st->discard >= AVDISCARD_ALL) - return res; - av_assert1(block_duration != AV_NOPTS_VALUE); - - block_time = AV_RB16(data); - data += 2; - flags = *data++; - size -= 3; - if (is_keyframe == -1) - is_keyframe = flags & 0x80 ? AV_PKT_FLAG_KEY : 0; - - if (cluster_time != (uint64_t)-1 - && (block_time >= 0 || cluster_time >= -block_time)) { - timecode = cluster_time + block_time; - if (track->type == MATROSKA_TRACK_TYPE_SUBTITLE - && timecode < track->end_timecode) - is_keyframe = 0; /* overlapping subtitles are not key frame */ - if (is_keyframe) - av_add_index_entry(st, cluster_pos, timecode, 0,0,AVINDEX_KEYFRAME); - } - - if (matroska->skip_to_keyframe && track->type != MATROSKA_TRACK_TYPE_SUBTITLE) { - if (timecode < matroska->skip_to_timecode) - return res; - if (!st->skip_to_keyframe) { - av_log(matroska->ctx, AV_LOG_ERROR, "File is broken, keyframes not correctly marked!\n"); - matroska->skip_to_keyframe = 0; - } - if (is_keyframe) - matroska->skip_to_keyframe = 0; - } - - res = matroska_parse_laces(matroska, &data, size, (flags & 0x06) >> 1, - &lace_size, &laces); - - if (res) - goto end; - - if (!block_duration) - block_duration = track->default_duration * laces / matroska->time_scale; - - if (cluster_time != (uint64_t)-1 && (block_time >= 0 || cluster_time >= -block_time)) - track->end_timecode = - FFMAX(track->end_timecode, timecode + block_duration); - - for (n = 0; n < laces; n++) { - int64_t lace_duration = block_duration*(n+1) / laces - block_duration*n / laces; - - if (lace_size[n] > size) { - av_log(matroska->ctx, AV_LOG_ERROR, "Invalid packet size\n"); - break; - } - - if ((st->codec->codec_id == AV_CODEC_ID_RA_288 || - st->codec->codec_id == AV_CODEC_ID_COOK || - st->codec->codec_id == AV_CODEC_ID_SIPR || - st->codec->codec_id == AV_CODEC_ID_ATRAC3) && - st->codec->block_align && track->audio.sub_packet_size) { - - res = matroska_parse_rm_audio(matroska, track, st, data, size, - timecode, pos); - if (res) - goto end; - - } else { - res = matroska_parse_frame(matroska, track, st, data, lace_size[n], - timecode, lace_duration, - pos, !n? is_keyframe : 0, - additional, additional_id, additional_size); - if (res) - goto end; - } - - if (timecode != AV_NOPTS_VALUE) - timecode = lace_duration ? timecode + lace_duration : AV_NOPTS_VALUE; - data += lace_size[n]; - size -= lace_size[n]; - } - -end: - av_free(lace_size); - return res; -} - -static int matroska_parse_cluster_incremental(MatroskaDemuxContext *matroska) -{ - EbmlList *blocks_list; - MatroskaBlock *blocks; - int i, res; - res = ebml_parse(matroska, - matroska_cluster_incremental_parsing, - &matroska->current_cluster); - if (res == 1) { - /* New Cluster */ - if (matroska->current_cluster_pos) - ebml_level_end(matroska); - ebml_free(matroska_cluster, &matroska->current_cluster); - memset(&matroska->current_cluster, 0, sizeof(MatroskaCluster)); - matroska->current_cluster_num_blocks = 0; - matroska->current_cluster_pos = avio_tell(matroska->ctx->pb); - matroska->prev_pkt = NULL; - /* sizeof the ID which was already read */ - if (matroska->current_id) - matroska->current_cluster_pos -= 4; - res = ebml_parse(matroska, - matroska_clusters_incremental, - &matroska->current_cluster); - /* Try parsing the block again. */ - if (res == 1) - res = ebml_parse(matroska, - matroska_cluster_incremental_parsing, - &matroska->current_cluster); - } - - if (!res && - matroska->current_cluster_num_blocks < - matroska->current_cluster.blocks.nb_elem) { - blocks_list = &matroska->current_cluster.blocks; - blocks = blocks_list->elem; - - matroska->current_cluster_num_blocks = blocks_list->nb_elem; - i = blocks_list->nb_elem - 1; - if (blocks[i].bin.size > 0 && blocks[i].bin.data) { - int is_keyframe = blocks[i].non_simple ? !blocks[i].reference : -1; - uint8_t* additional = blocks[i].additional.size > 0 ? - blocks[i].additional.data : NULL; - if (!blocks[i].non_simple) - blocks[i].duration = 0; - res = matroska_parse_block(matroska, - blocks[i].bin.data, blocks[i].bin.size, - blocks[i].bin.pos, - matroska->current_cluster.timecode, - blocks[i].duration, is_keyframe, - additional, blocks[i].additional_id, - blocks[i].additional.size, - matroska->current_cluster_pos); - } - } - - if (res < 0) matroska->done = 1; - return res; -} - -static int matroska_parse_cluster(MatroskaDemuxContext *matroska) -{ - MatroskaCluster cluster = { 0 }; - EbmlList *blocks_list; - MatroskaBlock *blocks; - int i, res; - int64_t pos; - if (!matroska->contains_ssa) - return matroska_parse_cluster_incremental(matroska); - pos = avio_tell(matroska->ctx->pb); - matroska->prev_pkt = NULL; - if (matroska->current_id) - pos -= 4; /* sizeof the ID which was already read */ - res = ebml_parse(matroska, matroska_clusters, &cluster); - blocks_list = &cluster.blocks; - blocks = blocks_list->elem; - for (i=0; inb_elem; i++) - if (blocks[i].bin.size > 0 && blocks[i].bin.data) { - int is_keyframe = blocks[i].non_simple ? !blocks[i].reference : -1; - res=matroska_parse_block(matroska, - blocks[i].bin.data, blocks[i].bin.size, - blocks[i].bin.pos, cluster.timecode, - blocks[i].duration, is_keyframe, NULL, 0, 0, - pos); - } - ebml_free(matroska_cluster, &cluster); - return res; -} - -static int matroska_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - MatroskaDemuxContext *matroska = s->priv_data; - - while (matroska_deliver_packet(matroska, pkt)) { - int64_t pos = avio_tell(matroska->ctx->pb); - if (matroska->done) - return AVERROR_EOF; - if (matroska_parse_cluster(matroska) < 0) - matroska_resync(matroska, pos); - } - - return 0; -} - -static int matroska_read_seek(AVFormatContext *s, int stream_index, - int64_t timestamp, int flags) -{ - MatroskaDemuxContext *matroska = s->priv_data; - MatroskaTrack *tracks = matroska->tracks.elem; - AVStream *st = s->streams[stream_index]; - int i, index, index_sub, index_min; - - /* Parse the CUES now since we need the index data to seek. */ - if (matroska->cues_parsing_deferred > 0) { - matroska->cues_parsing_deferred = 0; - matroska_parse_cues(matroska); - } - - if (!st->nb_index_entries) - goto err; - timestamp = FFMAX(timestamp, st->index_entries[0].timestamp); - - if ((index = av_index_search_timestamp(st, timestamp, flags)) < 0) { - avio_seek(s->pb, st->index_entries[st->nb_index_entries-1].pos, SEEK_SET); - matroska->current_id = 0; - while ((index = av_index_search_timestamp(st, timestamp, flags)) < 0) { - matroska_clear_queue(matroska); - if (matroska_parse_cluster(matroska) < 0) - break; - } - } - - matroska_clear_queue(matroska); - if (index < 0 || (matroska->cues_parsing_deferred < 0 && index == st->nb_index_entries - 1)) - goto err; - - index_min = index; - for (i=0; i < matroska->tracks.nb_elem; i++) { - tracks[i].audio.pkt_cnt = 0; - tracks[i].audio.sub_packet_cnt = 0; - tracks[i].audio.buf_timecode = AV_NOPTS_VALUE; - tracks[i].end_timecode = 0; - if (tracks[i].type == MATROSKA_TRACK_TYPE_SUBTITLE - && tracks[i].stream->discard != AVDISCARD_ALL) { - index_sub = av_index_search_timestamp(tracks[i].stream, st->index_entries[index].timestamp, AVSEEK_FLAG_BACKWARD); - if (index_sub >= 0 - && st->index_entries[index_sub].pos < st->index_entries[index_min].pos - && st->index_entries[index].timestamp - st->index_entries[index_sub].timestamp < 30000000000/matroska->time_scale) - index_min = index_sub; - } - } - - avio_seek(s->pb, st->index_entries[index_min].pos, SEEK_SET); - matroska->current_id = 0; - if (flags & AVSEEK_FLAG_ANY) { - st->skip_to_keyframe = 0; - matroska->skip_to_timecode = timestamp; - } else { - st->skip_to_keyframe = 1; - matroska->skip_to_timecode = st->index_entries[index].timestamp; - } - matroska->skip_to_keyframe = 1; - matroska->done = 0; - matroska->num_levels = 0; - ff_update_cur_dts(s, st, st->index_entries[index].timestamp); - return 0; -err: - // slightly hackish but allows proper fallback to - // the generic seeking code. - matroska_clear_queue(matroska); - matroska->current_id = 0; - st->skip_to_keyframe = - matroska->skip_to_keyframe = 0; - matroska->done = 0; - matroska->num_levels = 0; - return -1; -} - -static int matroska_read_close(AVFormatContext *s) -{ - MatroskaDemuxContext *matroska = s->priv_data; - MatroskaTrack *tracks = matroska->tracks.elem; - int n; - - matroska_clear_queue(matroska); - - for (n=0; n < matroska->tracks.nb_elem; n++) - if (tracks[n].type == MATROSKA_TRACK_TYPE_AUDIO) - av_free(tracks[n].audio.buf); - ebml_free(matroska_cluster, &matroska->current_cluster); - ebml_free(matroska_segment, matroska); - - return 0; -} - -AVInputFormat ff_matroska_demuxer = { - .name = "matroska,webm", - .long_name = NULL_IF_CONFIG_SMALL("Matroska / WebM"), - .priv_data_size = sizeof(MatroskaDemuxContext), - .read_probe = matroska_probe, - .read_header = matroska_read_header, - .read_packet = matroska_read_packet, - .read_close = matroska_read_close, - .read_seek = matroska_read_seek, -}; diff --git a/ffmpeg1/libavformat/matroskaenc.c b/ffmpeg1/libavformat/matroskaenc.c deleted file mode 100644 index a151eef..0000000 --- a/ffmpeg1/libavformat/matroskaenc.c +++ /dev/null @@ -1,1461 +0,0 @@ -/* - * Matroska muxer - * Copyright (c) 2007 David Conrad - * - * 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 "internal.h" -#include "riff.h" -#include "isom.h" -#include "matroska.h" -#include "avc.h" -#include "flacenc.h" -#include "avlanguage.h" -#include "libavutil/samplefmt.h" -#include "libavutil/sha.h" -#include "libavutil/intreadwrite.h" -#include "libavutil/intfloat.h" -#include "libavutil/mathematics.h" -#include "libavutil/random_seed.h" -#include "libavutil/lfg.h" -#include "libavutil/dict.h" -#include "libavutil/avstring.h" -#include "libavcodec/xiph.h" -#include "libavcodec/mpeg4audio.h" - -typedef struct ebml_master { - int64_t pos; ///< absolute offset in the file where the master's elements start - int sizebytes; ///< how many bytes were reserved for the size -} ebml_master; - -typedef struct mkv_seekhead_entry { - unsigned int elementid; - uint64_t segmentpos; -} mkv_seekhead_entry; - -typedef struct mkv_seekhead { - int64_t filepos; - int64_t segment_offset; ///< the file offset to the beginning of the segment - int reserved_size; ///< -1 if appending to file - int max_entries; - mkv_seekhead_entry *entries; - int num_entries; -} mkv_seekhead; - -typedef struct { - uint64_t pts; - int tracknum; - int64_t cluster_pos; ///< file offset of the cluster containing the block -} mkv_cuepoint; - -typedef struct { - int64_t segment_offset; - mkv_cuepoint *entries; - int num_entries; -} mkv_cues; - -typedef struct { - int write_dts; - int has_cue; -} mkv_track; - -#define MODE_MATROSKAv2 0x01 -#define MODE_WEBM 0x02 - -typedef struct MatroskaMuxContext { - int mode; - AVIOContext *dyn_bc; - ebml_master segment; - int64_t segment_offset; - ebml_master cluster; - int64_t cluster_pos; ///< file offset of the current cluster - int64_t cluster_pts; - int64_t duration_offset; - int64_t duration; - mkv_seekhead *main_seekhead; - mkv_cues *cues; - mkv_track *tracks; - - AVPacket cur_audio_pkt; - - int have_attachments; -} MatroskaMuxContext; - - -/** 2 bytes * 3 for EBML IDs, 3 1-byte EBML lengths, 8 bytes for 64 bit - * offset, 4 bytes for target EBML ID */ -#define MAX_SEEKENTRY_SIZE 21 - -/** per-cuepoint-track - 3 1-byte EBML IDs, 3 1-byte EBML sizes, 2 - * 8-byte uint max */ -#define MAX_CUETRACKPOS_SIZE 22 - -/** per-cuepoint - 2 1-byte EBML IDs, 2 1-byte EBML sizes, 8-byte uint max */ -#define MAX_CUEPOINT_SIZE(num_tracks) 12 + MAX_CUETRACKPOS_SIZE*num_tracks - - -static int ebml_id_size(unsigned int id) -{ - return (av_log2(id+1)-1)/7+1; -} - -static void put_ebml_id(AVIOContext *pb, unsigned int id) -{ - int i = ebml_id_size(id); - while (i--) - avio_w8(pb, (uint8_t)(id >> (i*8))); -} - -/** - * Write an EBML size meaning "unknown size". - * - * @param bytes The number of bytes the size should occupy (maximum: 8). - */ -static void put_ebml_size_unknown(AVIOContext *pb, int bytes) -{ - av_assert0(bytes <= 8); - avio_w8(pb, 0x1ff >> bytes); - while (--bytes) - avio_w8(pb, 0xff); -} - -/** - * Calculate how many bytes are needed to represent a given number in EBML. - */ -static int ebml_num_size(uint64_t num) -{ - int bytes = 1; - while ((num+1) >> bytes*7) bytes++; - return bytes; -} - -/** - * Write a number in EBML variable length format. - * - * @param bytes The number of bytes that need to be used to write the number. - * If zero, any number of bytes can be used. - */ -static void put_ebml_num(AVIOContext *pb, uint64_t num, int bytes) -{ - int i, needed_bytes = ebml_num_size(num); - - // sizes larger than this are currently undefined in EBML - av_assert0(num < (1ULL<<56)-1); - - if (bytes == 0) - // don't care how many bytes are used, so use the min - bytes = needed_bytes; - // the bytes needed to write the given size would exceed the bytes - // that we need to use, so write unknown size. This shouldn't happen. - av_assert0(bytes >= needed_bytes); - - num |= 1ULL << bytes*7; - for (i = bytes - 1; i >= 0; i--) - avio_w8(pb, (uint8_t)(num >> i*8)); -} - -static void put_ebml_uint(AVIOContext *pb, unsigned int elementid, uint64_t val) -{ - int i, bytes = 1; - uint64_t tmp = val; - while (tmp>>=8) bytes++; - - put_ebml_id(pb, elementid); - put_ebml_num(pb, bytes, 0); - for (i = bytes - 1; i >= 0; i--) - avio_w8(pb, (uint8_t)(val >> i*8)); -} - -static void put_ebml_float(AVIOContext *pb, unsigned int elementid, double val) -{ - put_ebml_id(pb, elementid); - put_ebml_num(pb, 8, 0); - avio_wb64(pb, av_double2int(val)); -} - -static void put_ebml_binary(AVIOContext *pb, unsigned int elementid, - const void *buf, int size) -{ - put_ebml_id(pb, elementid); - put_ebml_num(pb, size, 0); - avio_write(pb, buf, size); -} - -static void put_ebml_string(AVIOContext *pb, unsigned int elementid, const char *str) -{ - put_ebml_binary(pb, elementid, str, strlen(str)); -} - -/** - * Write a void element of a given size. Useful for reserving space in - * the file to be written to later. - * - * @param size The number of bytes to reserve, which must be at least 2. - */ -static void put_ebml_void(AVIOContext *pb, uint64_t size) -{ - int64_t currentpos = avio_tell(pb); - - av_assert0(size >= 2); - - put_ebml_id(pb, EBML_ID_VOID); - // we need to subtract the length needed to store the size from the - // size we need to reserve so 2 cases, we use 8 bytes to store the - // size if possible, 1 byte otherwise - if (size < 10) - put_ebml_num(pb, size-1, 0); - else - put_ebml_num(pb, size-9, 8); - while(avio_tell(pb) < currentpos + size) - avio_w8(pb, 0); -} - -static ebml_master start_ebml_master(AVIOContext *pb, unsigned int elementid, uint64_t expectedsize) -{ - int bytes = expectedsize ? ebml_num_size(expectedsize) : 8; - put_ebml_id(pb, elementid); - put_ebml_size_unknown(pb, bytes); - return (ebml_master){ avio_tell(pb), bytes }; -} - -static void end_ebml_master(AVIOContext *pb, ebml_master master) -{ - int64_t pos = avio_tell(pb); - - if (avio_seek(pb, master.pos - master.sizebytes, SEEK_SET) < 0) - return; - put_ebml_num(pb, pos - master.pos, master.sizebytes); - avio_seek(pb, pos, SEEK_SET); -} - -static void put_xiph_size(AVIOContext *pb, int size) -{ - int i; - for (i = 0; i < size / 255; i++) - avio_w8(pb, 255); - avio_w8(pb, size % 255); -} - -/** - * Initialize a mkv_seekhead element to be ready to index level 1 Matroska - * elements. If a maximum number of elements is specified, enough space - * will be reserved at the current file location to write a seek head of - * that size. - * - * @param segment_offset The absolute offset to the position in the file - * where the segment begins. - * @param numelements The maximum number of elements that will be indexed - * by this seek head, 0 if unlimited. - */ -static mkv_seekhead * mkv_start_seekhead(AVIOContext *pb, int64_t segment_offset, int numelements) -{ - mkv_seekhead *new_seekhead = av_mallocz(sizeof(mkv_seekhead)); - if (new_seekhead == NULL) - return NULL; - - new_seekhead->segment_offset = segment_offset; - - if (numelements > 0) { - new_seekhead->filepos = avio_tell(pb); - // 21 bytes max for a seek entry, 10 bytes max for the SeekHead ID - // and size, and 3 bytes to guarantee that an EBML void element - // will fit afterwards - new_seekhead->reserved_size = numelements * MAX_SEEKENTRY_SIZE + 13; - new_seekhead->max_entries = numelements; - put_ebml_void(pb, new_seekhead->reserved_size); - } - return new_seekhead; -} - -static int mkv_add_seekhead_entry(mkv_seekhead *seekhead, unsigned int elementid, uint64_t filepos) -{ - mkv_seekhead_entry *entries = seekhead->entries; - - // don't store more elements than we reserved space for - if (seekhead->max_entries > 0 && seekhead->max_entries <= seekhead->num_entries) - return -1; - - entries = av_realloc(entries, (seekhead->num_entries + 1) * sizeof(mkv_seekhead_entry)); - if (entries == NULL) - return AVERROR(ENOMEM); - - entries[seekhead->num_entries ].elementid = elementid; - entries[seekhead->num_entries++].segmentpos = filepos - seekhead->segment_offset; - - seekhead->entries = entries; - return 0; -} - -/** - * Write the seek head to the file and free it. If a maximum number of - * elements was specified to mkv_start_seekhead(), the seek head will - * be written at the location reserved for it. Otherwise, it is written - * at the current location in the file. - * - * @return The file offset where the seekhead was written, - * -1 if an error occurred. - */ -static int64_t mkv_write_seekhead(AVIOContext *pb, mkv_seekhead *seekhead) -{ - ebml_master metaseek, seekentry; - int64_t currentpos; - int i; - - currentpos = avio_tell(pb); - - if (seekhead->reserved_size > 0) { - if (avio_seek(pb, seekhead->filepos, SEEK_SET) < 0) { - currentpos = -1; - goto fail; - } - } - - metaseek = start_ebml_master(pb, MATROSKA_ID_SEEKHEAD, seekhead->reserved_size); - for (i = 0; i < seekhead->num_entries; i++) { - mkv_seekhead_entry *entry = &seekhead->entries[i]; - - seekentry = start_ebml_master(pb, MATROSKA_ID_SEEKENTRY, MAX_SEEKENTRY_SIZE); - - put_ebml_id(pb, MATROSKA_ID_SEEKID); - put_ebml_num(pb, ebml_id_size(entry->elementid), 0); - put_ebml_id(pb, entry->elementid); - - put_ebml_uint(pb, MATROSKA_ID_SEEKPOSITION, entry->segmentpos); - end_ebml_master(pb, seekentry); - } - end_ebml_master(pb, metaseek); - - if (seekhead->reserved_size > 0) { - uint64_t remaining = seekhead->filepos + seekhead->reserved_size - avio_tell(pb); - put_ebml_void(pb, remaining); - avio_seek(pb, currentpos, SEEK_SET); - - currentpos = seekhead->filepos; - } -fail: - av_free(seekhead->entries); - av_free(seekhead); - - return currentpos; -} - -static mkv_cues * mkv_start_cues(int64_t segment_offset) -{ - mkv_cues *cues = av_mallocz(sizeof(mkv_cues)); - if (cues == NULL) - return NULL; - - cues->segment_offset = segment_offset; - return cues; -} - -static int mkv_add_cuepoint(mkv_cues *cues, int stream, int64_t ts, int64_t cluster_pos) -{ - mkv_cuepoint *entries = cues->entries; - - if (ts < 0) - return 0; - - entries = av_realloc(entries, (cues->num_entries + 1) * sizeof(mkv_cuepoint)); - if (entries == NULL) - return AVERROR(ENOMEM); - - entries[cues->num_entries ].pts = ts; - entries[cues->num_entries ].tracknum = stream + 1; - entries[cues->num_entries++].cluster_pos = cluster_pos - cues->segment_offset; - - cues->entries = entries; - return 0; -} - -static int64_t mkv_write_cues(AVIOContext *pb, mkv_cues *cues, mkv_track *tracks, int num_tracks) -{ - ebml_master cues_element; - int64_t currentpos; - int i, j; - - currentpos = avio_tell(pb); - cues_element = start_ebml_master(pb, MATROSKA_ID_CUES, 0); - - for (i = 0; i < cues->num_entries; i++) { - ebml_master cuepoint, track_positions; - mkv_cuepoint *entry = &cues->entries[i]; - uint64_t pts = entry->pts; - - cuepoint = start_ebml_master(pb, MATROSKA_ID_POINTENTRY, MAX_CUEPOINT_SIZE(num_tracks)); - put_ebml_uint(pb, MATROSKA_ID_CUETIME, pts); - - // put all the entries from different tracks that have the exact same - // timestamp into the same CuePoint - for (j = 0; j < num_tracks; j++) - tracks[j].has_cue = 0; - for (j = 0; j < cues->num_entries - i && entry[j].pts == pts; j++) { - int tracknum = entry[j].tracknum - 1; - av_assert0(tracknum>=0 && tracknumcodec_id == AV_CODEC_ID_VORBIS) - first_header_size = 30; - else - first_header_size = 42; - - if (avpriv_split_xiph_headers(codec->extradata, codec->extradata_size, - first_header_size, header_start, header_len) < 0) { - av_log(s, AV_LOG_ERROR, "Extradata corrupt.\n"); - return -1; - } - - avio_w8(pb, 2); // number packets - 1 - for (j = 0; j < 2; j++) { - put_xiph_size(pb, header_len[j]); - } - for (j = 0; j < 3; j++) - avio_write(pb, header_start[j], header_len[j]); - - return 0; -} - -static void get_aac_sample_rates(AVFormatContext *s, AVCodecContext *codec, int *sample_rate, int *output_sample_rate) -{ - MPEG4AudioConfig mp4ac; - - if (avpriv_mpeg4audio_get_config(&mp4ac, codec->extradata, - codec->extradata_size * 8, 1) < 0) { - av_log(s, AV_LOG_WARNING, "Error parsing AAC extradata, unable to determine samplerate.\n"); - return; - } - - *sample_rate = mp4ac.sample_rate; - *output_sample_rate = mp4ac.ext_sample_rate; -} - -static int mkv_write_codecprivate(AVFormatContext *s, AVIOContext *pb, AVCodecContext *codec, int native_id, int qt_id) -{ - AVIOContext *dyn_cp; - uint8_t *codecpriv; - int ret, codecpriv_size; - - ret = avio_open_dyn_buf(&dyn_cp); - if(ret < 0) - return ret; - - if (native_id) { - if (codec->codec_id == AV_CODEC_ID_VORBIS || codec->codec_id == AV_CODEC_ID_THEORA) - ret = put_xiph_codecpriv(s, dyn_cp, codec); - else if (codec->codec_id == AV_CODEC_ID_FLAC) - ret = ff_flac_write_header(dyn_cp, codec, 1); - else if (codec->codec_id == AV_CODEC_ID_H264) - ret = ff_isom_write_avcc(dyn_cp, codec->extradata, codec->extradata_size); - else if (codec->codec_id == AV_CODEC_ID_ALAC) { - if (codec->extradata_size < 36) { - av_log(s, AV_LOG_ERROR, - "Invalid extradata found, ALAC expects a 36-byte " - "QuickTime atom."); - ret = AVERROR_INVALIDDATA; - } else - avio_write(dyn_cp, codec->extradata + 12, - codec->extradata_size - 12); - } - else if (codec->extradata_size && codec->codec_id != AV_CODEC_ID_TTA) - avio_write(dyn_cp, codec->extradata, codec->extradata_size); - } else if (codec->codec_type == AVMEDIA_TYPE_VIDEO) { - if (qt_id) { - if (!codec->codec_tag) - codec->codec_tag = ff_codec_get_tag(ff_codec_movvideo_tags, codec->codec_id); - if (codec->extradata_size) - avio_write(dyn_cp, codec->extradata, codec->extradata_size); - } else { - if (!codec->codec_tag) - codec->codec_tag = ff_codec_get_tag(ff_codec_bmp_tags, codec->codec_id); - if (!codec->codec_tag) { - av_log(s, AV_LOG_ERROR, "No bmp codec tag found for codec %s\n", - avcodec_get_name(codec->codec_id)); - ret = AVERROR(EINVAL); - } - - ff_put_bmp_header(dyn_cp, codec, ff_codec_bmp_tags, 0); - } - - } else if (codec->codec_type == AVMEDIA_TYPE_AUDIO) { - unsigned int tag; - tag = ff_codec_get_tag(ff_codec_wav_tags, codec->codec_id); - if (!tag) { - av_log(s, AV_LOG_ERROR, "No wav codec tag found for codec %s\n", - avcodec_get_name(codec->codec_id)); - ret = AVERROR(EINVAL); - } - if (!codec->codec_tag) - codec->codec_tag = tag; - - ff_put_wav_header(dyn_cp, codec); - } - - codecpriv_size = avio_close_dyn_buf(dyn_cp, &codecpriv); - if (codecpriv_size) - put_ebml_binary(pb, MATROSKA_ID_CODECPRIVATE, codecpriv, codecpriv_size); - av_free(codecpriv); - return ret; -} - -static int mkv_write_tracks(AVFormatContext *s) -{ - MatroskaMuxContext *mkv = s->priv_data; - AVIOContext *pb = s->pb; - ebml_master tracks; - int i, j, ret, default_stream_exists = 0; - - ret = mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_TRACKS, avio_tell(pb)); - if (ret < 0) return ret; - - tracks = start_ebml_master(pb, MATROSKA_ID_TRACKS, 0); - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - default_stream_exists |= st->disposition & AV_DISPOSITION_DEFAULT; - } - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - AVCodecContext *codec = st->codec; - ebml_master subinfo, track; - int native_id = 0; - int qt_id = 0; - int bit_depth = av_get_bits_per_sample(codec->codec_id); - int sample_rate = codec->sample_rate; - int output_sample_rate = 0; - AVDictionaryEntry *tag; - - if (codec->codec_type == AVMEDIA_TYPE_ATTACHMENT) { - mkv->have_attachments = 1; - continue; - } - - if (!bit_depth) - bit_depth = av_get_bytes_per_sample(codec->sample_fmt) << 3; - if (!bit_depth) - bit_depth = codec->bits_per_coded_sample; - - if (codec->codec_id == AV_CODEC_ID_AAC) - get_aac_sample_rates(s, codec, &sample_rate, &output_sample_rate); - - track = start_ebml_master(pb, MATROSKA_ID_TRACKENTRY, 0); - put_ebml_uint (pb, MATROSKA_ID_TRACKNUMBER , i + 1); - put_ebml_uint (pb, MATROSKA_ID_TRACKUID , i + 1); - put_ebml_uint (pb, MATROSKA_ID_TRACKFLAGLACING , 0); // no lacing (yet) - - if ((tag = av_dict_get(st->metadata, "title", NULL, 0))) - put_ebml_string(pb, MATROSKA_ID_TRACKNAME, tag->value); - tag = av_dict_get(st->metadata, "language", NULL, 0); - put_ebml_string(pb, MATROSKA_ID_TRACKLANGUAGE, tag ? tag->value:"und"); - - if (default_stream_exists) { - put_ebml_uint(pb, MATROSKA_ID_TRACKFLAGDEFAULT, !!(st->disposition & AV_DISPOSITION_DEFAULT)); - } - if (st->disposition & AV_DISPOSITION_FORCED) - put_ebml_uint(pb, MATROSKA_ID_TRACKFLAGFORCED, 1); - - // look for a codec ID string specific to mkv to use, - // if none are found, use AVI codes - for (j = 0; ff_mkv_codec_tags[j].id != AV_CODEC_ID_NONE; j++) { - if (ff_mkv_codec_tags[j].id == codec->codec_id) { - put_ebml_string(pb, MATROSKA_ID_CODECID, ff_mkv_codec_tags[j].str); - native_id = 1; - break; - } - } - - if (mkv->mode == MODE_WEBM && !(codec->codec_id == AV_CODEC_ID_VP8 || - codec->codec_id == AV_CODEC_ID_VORBIS)) { - av_log(s, AV_LOG_ERROR, - "Only VP8 video and Vorbis audio are supported for WebM.\n"); - return AVERROR(EINVAL); - } - - switch (codec->codec_type) { - case AVMEDIA_TYPE_VIDEO: - put_ebml_uint(pb, MATROSKA_ID_TRACKTYPE, MATROSKA_TRACK_TYPE_VIDEO); - if(st->avg_frame_rate.num && st->avg_frame_rate.den && 1.0/av_q2d(st->avg_frame_rate) > av_q2d(codec->time_base)) - put_ebml_uint(pb, MATROSKA_ID_TRACKDEFAULTDURATION, 1E9/av_q2d(st->avg_frame_rate)); - else - put_ebml_uint(pb, MATROSKA_ID_TRACKDEFAULTDURATION, av_q2d(codec->time_base)*1E9); - - if (!native_id && - ff_codec_get_tag(ff_codec_movvideo_tags, codec->codec_id) && - (!ff_codec_get_tag(ff_codec_bmp_tags, codec->codec_id) - || codec->codec_id == AV_CODEC_ID_SVQ1 - || codec->codec_id == AV_CODEC_ID_SVQ3 - || codec->codec_id == AV_CODEC_ID_CINEPAK)) - qt_id = 1; - - if (qt_id) - put_ebml_string(pb, MATROSKA_ID_CODECID, "V_QUICKTIME"); - else if (!native_id) { - // if there is no mkv-specific codec ID, use VFW mode - put_ebml_string(pb, MATROSKA_ID_CODECID, "V_MS/VFW/FOURCC"); - mkv->tracks[i].write_dts = 1; - } - - subinfo = start_ebml_master(pb, MATROSKA_ID_TRACKVIDEO, 0); - // XXX: interlace flag? - put_ebml_uint (pb, MATROSKA_ID_VIDEOPIXELWIDTH , codec->width); - put_ebml_uint (pb, MATROSKA_ID_VIDEOPIXELHEIGHT, codec->height); - - if ((tag = av_dict_get(st->metadata, "stereo_mode", NULL, 0)) || - (tag = av_dict_get( s->metadata, "stereo_mode", NULL, 0))) { - // save stereo mode flag - uint64_t st_mode = MATROSKA_VIDEO_STEREO_MODE_COUNT; - - for (j=0; jvalue, ff_matroska_video_stereo_mode[j])){ - st_mode = j; - break; - } - - if ((mkv->mode == MODE_WEBM && st_mode > 3 && st_mode != 11) - || st_mode >= MATROSKA_VIDEO_STEREO_MODE_COUNT) { - av_log(s, AV_LOG_ERROR, - "The specified stereo mode is not valid.\n"); - return AVERROR(EINVAL); - } else - put_ebml_uint(pb, MATROSKA_ID_VIDEOSTEREOMODE, st_mode); - } - - if (st->sample_aspect_ratio.num) { - int64_t d_width = av_rescale(codec->width, st->sample_aspect_ratio.num, st->sample_aspect_ratio.den); - if (d_width > INT_MAX) { - av_log(s, AV_LOG_ERROR, "Overflow in display width\n"); - return AVERROR(EINVAL); - } - put_ebml_uint(pb, MATROSKA_ID_VIDEODISPLAYWIDTH , d_width); - put_ebml_uint(pb, MATROSKA_ID_VIDEODISPLAYHEIGHT, codec->height); - } - - if (codec->codec_id == AV_CODEC_ID_RAWVIDEO) { - uint32_t color_space = av_le2ne32(codec->codec_tag); - put_ebml_binary(pb, MATROSKA_ID_VIDEOCOLORSPACE, &color_space, sizeof(color_space)); - } - end_ebml_master(pb, subinfo); - break; - - case AVMEDIA_TYPE_AUDIO: - put_ebml_uint(pb, MATROSKA_ID_TRACKTYPE, MATROSKA_TRACK_TYPE_AUDIO); - - if (!native_id) - // no mkv-specific ID, use ACM mode - put_ebml_string(pb, MATROSKA_ID_CODECID, "A_MS/ACM"); - - subinfo = start_ebml_master(pb, MATROSKA_ID_TRACKAUDIO, 0); - put_ebml_uint (pb, MATROSKA_ID_AUDIOCHANNELS , codec->channels); - put_ebml_float (pb, MATROSKA_ID_AUDIOSAMPLINGFREQ, sample_rate); - if (output_sample_rate) - put_ebml_float(pb, MATROSKA_ID_AUDIOOUTSAMPLINGFREQ, output_sample_rate); - if (bit_depth) - put_ebml_uint(pb, MATROSKA_ID_AUDIOBITDEPTH, bit_depth); - end_ebml_master(pb, subinfo); - break; - - case AVMEDIA_TYPE_SUBTITLE: - put_ebml_uint(pb, MATROSKA_ID_TRACKTYPE, MATROSKA_TRACK_TYPE_SUBTITLE); - if (!native_id) { - av_log(s, AV_LOG_ERROR, "Subtitle codec %d is not supported.\n", codec->codec_id); - return AVERROR(ENOSYS); - } - break; - default: - av_log(s, AV_LOG_ERROR, "Only audio, video, and subtitles are supported for Matroska.\n"); - break; - } - ret = mkv_write_codecprivate(s, pb, codec, native_id, qt_id); - if (ret < 0) return ret; - - end_ebml_master(pb, track); - - // ms precision is the de-facto standard timescale for mkv files - avpriv_set_pts_info(st, 64, 1, 1000); - } - end_ebml_master(pb, tracks); - return 0; -} - -static int mkv_write_chapters(AVFormatContext *s) -{ - MatroskaMuxContext *mkv = s->priv_data; - AVIOContext *pb = s->pb; - ebml_master chapters, editionentry; - AVRational scale = {1, 1E9}; - int i, ret; - - if (!s->nb_chapters) - return 0; - - ret = mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_CHAPTERS, avio_tell(pb)); - if (ret < 0) return ret; - - chapters = start_ebml_master(pb, MATROSKA_ID_CHAPTERS , 0); - editionentry = start_ebml_master(pb, MATROSKA_ID_EDITIONENTRY, 0); - put_ebml_uint(pb, MATROSKA_ID_EDITIONFLAGDEFAULT, 1); - put_ebml_uint(pb, MATROSKA_ID_EDITIONFLAGHIDDEN , 0); - for (i = 0; i < s->nb_chapters; i++) { - ebml_master chapteratom, chapterdisplay; - AVChapter *c = s->chapters[i]; - AVDictionaryEntry *t = NULL; - - chapteratom = start_ebml_master(pb, MATROSKA_ID_CHAPTERATOM, 0); - put_ebml_uint(pb, MATROSKA_ID_CHAPTERUID, c->id); - put_ebml_uint(pb, MATROSKA_ID_CHAPTERTIMESTART, - av_rescale_q(c->start, c->time_base, scale)); - put_ebml_uint(pb, MATROSKA_ID_CHAPTERTIMEEND, - av_rescale_q(c->end, c->time_base, scale)); - put_ebml_uint(pb, MATROSKA_ID_CHAPTERFLAGHIDDEN , 0); - put_ebml_uint(pb, MATROSKA_ID_CHAPTERFLAGENABLED, 1); - if ((t = av_dict_get(c->metadata, "title", NULL, 0))) { - chapterdisplay = start_ebml_master(pb, MATROSKA_ID_CHAPTERDISPLAY, 0); - put_ebml_string(pb, MATROSKA_ID_CHAPSTRING, t->value); - put_ebml_string(pb, MATROSKA_ID_CHAPLANG , "und"); - end_ebml_master(pb, chapterdisplay); - } - end_ebml_master(pb, chapteratom); - } - end_ebml_master(pb, editionentry); - end_ebml_master(pb, chapters); - return 0; -} - -static void mkv_write_simpletag(AVIOContext *pb, AVDictionaryEntry *t) -{ - uint8_t *key = av_strdup(t->key); - uint8_t *p = key; - const uint8_t *lang = NULL; - ebml_master tag; - - if ((p = strrchr(p, '-')) && - (lang = av_convert_lang_to(p + 1, AV_LANG_ISO639_2_BIBL))) - *p = 0; - - p = key; - while (*p) { - if (*p == ' ') - *p = '_'; - else if (*p >= 'a' && *p <= 'z') - *p -= 'a' - 'A'; - p++; - } - - tag = start_ebml_master(pb, MATROSKA_ID_SIMPLETAG, 0); - put_ebml_string(pb, MATROSKA_ID_TAGNAME, key); - if (lang) - put_ebml_string(pb, MATROSKA_ID_TAGLANG, lang); - put_ebml_string(pb, MATROSKA_ID_TAGSTRING, t->value); - end_ebml_master(pb, tag); - - av_freep(&key); -} - -static int mkv_write_tag(AVFormatContext *s, AVDictionary *m, unsigned int elementid, - unsigned int uid, ebml_master *tags) -{ - MatroskaMuxContext *mkv = s->priv_data; - ebml_master tag, targets; - AVDictionaryEntry *t = NULL; - int ret; - - if (!tags->pos) { - ret = mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_TAGS, avio_tell(s->pb)); - if (ret < 0) return ret; - - *tags = start_ebml_master(s->pb, MATROSKA_ID_TAGS, 0); - } - - tag = start_ebml_master(s->pb, MATROSKA_ID_TAG, 0); - targets = start_ebml_master(s->pb, MATROSKA_ID_TAGTARGETS, 0); - if (elementid) - put_ebml_uint(s->pb, elementid, uid); - end_ebml_master(s->pb, targets); - - while ((t = av_dict_get(m, "", t, AV_DICT_IGNORE_SUFFIX))) - if (av_strcasecmp(t->key, "title") && av_strcasecmp(t->key, "stereo_mode")) - mkv_write_simpletag(s->pb, t); - - end_ebml_master(s->pb, tag); - return 0; -} - -static int mkv_write_tags(AVFormatContext *s) -{ - ebml_master tags = {0}; - int i, ret; - - ff_metadata_conv_ctx(s, ff_mkv_metadata_conv, NULL); - - if (av_dict_get(s->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX)) { - ret = mkv_write_tag(s, s->metadata, 0, 0, &tags); - if (ret < 0) return ret; - } - - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - - if (!av_dict_get(st->metadata, "", 0, AV_DICT_IGNORE_SUFFIX)) - continue; - - ret = mkv_write_tag(s, st->metadata, MATROSKA_ID_TAGTARGETS_TRACKUID, i + 1, &tags); - if (ret < 0) return ret; - } - - for (i = 0; i < s->nb_chapters; i++) { - AVChapter *ch = s->chapters[i]; - - if (!av_dict_get(ch->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX)) - continue; - - ret = mkv_write_tag(s, ch->metadata, MATROSKA_ID_TAGTARGETS_CHAPTERUID, ch->id, &tags); - if (ret < 0) return ret; - } - - if (tags.pos) - end_ebml_master(s->pb, tags); - return 0; -} - -static int mkv_write_attachments(AVFormatContext *s) -{ - MatroskaMuxContext *mkv = s->priv_data; - AVIOContext *pb = s->pb; - ebml_master attachments; - AVLFG c; - int i, ret; - - if (!mkv->have_attachments) - return 0; - - av_lfg_init(&c, av_get_random_seed()); - - ret = mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_ATTACHMENTS, avio_tell(pb)); - if (ret < 0) return ret; - - attachments = start_ebml_master(pb, MATROSKA_ID_ATTACHMENTS, 0); - - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - ebml_master attached_file; - AVDictionaryEntry *t; - const char *mimetype = NULL; - uint64_t fileuid; - - if (st->codec->codec_type != AVMEDIA_TYPE_ATTACHMENT) - continue; - - attached_file = start_ebml_master(pb, MATROSKA_ID_ATTACHEDFILE, 0); - - if (t = av_dict_get(st->metadata, "title", NULL, 0)) - put_ebml_string(pb, MATROSKA_ID_FILEDESC, t->value); - if (!(t = av_dict_get(st->metadata, "filename", NULL, 0))) { - av_log(s, AV_LOG_ERROR, "Attachment stream %d has no filename tag.\n", i); - return AVERROR(EINVAL); - } - put_ebml_string(pb, MATROSKA_ID_FILENAME, t->value); - if (t = av_dict_get(st->metadata, "mimetype", NULL, 0)) - mimetype = t->value; - else if (st->codec->codec_id != AV_CODEC_ID_NONE ) { - int i; - for (i = 0; ff_mkv_mime_tags[i].id != AV_CODEC_ID_NONE; i++) - if (ff_mkv_mime_tags[i].id == st->codec->codec_id) { - mimetype = ff_mkv_mime_tags[i].str; - break; - } - } - if (!mimetype) { - av_log(s, AV_LOG_ERROR, "Attachment stream %d has no mimetype tag and " - "it cannot be deduced from the codec id.\n", i); - return AVERROR(EINVAL); - } - - if (st->codec->flags & CODEC_FLAG_BITEXACT) { - struct AVSHA *sha = av_sha_alloc(); - uint8_t digest[20]; - if (!sha) - return AVERROR(ENOMEM); - av_sha_init(sha, 160); - av_sha_update(sha, st->codec->extradata, st->codec->extradata_size); - av_sha_final(sha, digest); - av_free(sha); - fileuid = AV_RL64(digest); - } else { - fileuid = av_lfg_get(&c); - } - av_log(s, AV_LOG_VERBOSE, "Using %.16"PRIx64" for attachment %d\n", - fileuid, i); - - put_ebml_string(pb, MATROSKA_ID_FILEMIMETYPE, mimetype); - put_ebml_binary(pb, MATROSKA_ID_FILEDATA, st->codec->extradata, st->codec->extradata_size); - put_ebml_uint(pb, MATROSKA_ID_FILEUID, fileuid); - end_ebml_master(pb, attached_file); - } - end_ebml_master(pb, attachments); - - return 0; -} - -static int mkv_write_header(AVFormatContext *s) -{ - MatroskaMuxContext *mkv = s->priv_data; - AVIOContext *pb = s->pb; - ebml_master ebml_header, segment_info; - AVDictionaryEntry *tag; - int ret, i; - - if (!strcmp(s->oformat->name, "webm")) mkv->mode = MODE_WEBM; - else mkv->mode = MODE_MATROSKAv2; - - if (s->avoid_negative_ts < 0) - s->avoid_negative_ts = 1; - - for (i = 0; i < s->nb_streams; i++) - if (s->streams[i]->codec->codec_id == AV_CODEC_ID_ATRAC3 || - s->streams[i]->codec->codec_id == AV_CODEC_ID_COOK || - s->streams[i]->codec->codec_id == AV_CODEC_ID_RA_288 || - s->streams[i]->codec->codec_id == AV_CODEC_ID_SIPR || - s->streams[i]->codec->codec_id == AV_CODEC_ID_RV10 || - s->streams[i]->codec->codec_id == AV_CODEC_ID_RV20) { - av_log(s, AV_LOG_ERROR, - "The Matroska muxer does not yet support muxing %s\n", - avcodec_get_name(s->streams[i]->codec->codec_id)); - return AVERROR_PATCHWELCOME; - } - - mkv->tracks = av_mallocz(s->nb_streams * sizeof(*mkv->tracks)); - if (!mkv->tracks) - return AVERROR(ENOMEM); - - ebml_header = start_ebml_master(pb, EBML_ID_HEADER, 0); - put_ebml_uint (pb, EBML_ID_EBMLVERSION , 1); - put_ebml_uint (pb, EBML_ID_EBMLREADVERSION , 1); - put_ebml_uint (pb, EBML_ID_EBMLMAXIDLENGTH , 4); - put_ebml_uint (pb, EBML_ID_EBMLMAXSIZELENGTH , 8); - put_ebml_string (pb, EBML_ID_DOCTYPE , s->oformat->name); - put_ebml_uint (pb, EBML_ID_DOCTYPEVERSION , 2); - put_ebml_uint (pb, EBML_ID_DOCTYPEREADVERSION , 2); - end_ebml_master(pb, ebml_header); - - mkv->segment = start_ebml_master(pb, MATROSKA_ID_SEGMENT, 0); - mkv->segment_offset = avio_tell(pb); - - // we write 2 seek heads - one at the end of the file to point to each - // cluster, and one at the beginning to point to all other level one - // elements (including the seek head at the end of the file), which - // isn't more than 10 elements if we only write one of each other - // currently defined level 1 element - mkv->main_seekhead = mkv_start_seekhead(pb, mkv->segment_offset, 10); - if (!mkv->main_seekhead) - return AVERROR(ENOMEM); - - ret = mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_INFO, avio_tell(pb)); - if (ret < 0) return ret; - - segment_info = start_ebml_master(pb, MATROSKA_ID_INFO, 0); - put_ebml_uint(pb, MATROSKA_ID_TIMECODESCALE, 1000000); - if ((tag = av_dict_get(s->metadata, "title", NULL, 0))) - put_ebml_string(pb, MATROSKA_ID_TITLE, tag->value); - if (!(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT)) { - uint32_t segment_uid[4]; - AVLFG lfg; - - av_lfg_init(&lfg, av_get_random_seed()); - - for (i = 0; i < 4; i++) - segment_uid[i] = av_lfg_get(&lfg); - - put_ebml_string(pb, MATROSKA_ID_MUXINGAPP , LIBAVFORMAT_IDENT); - put_ebml_string(pb, MATROSKA_ID_WRITINGAPP, LIBAVFORMAT_IDENT); - put_ebml_binary(pb, MATROSKA_ID_SEGMENTUID, segment_uid, 16); - } - - if (tag = av_dict_get(s->metadata, "creation_time", NULL, 0)) { - // Adjust time so it's relative to 2001-01-01 and convert to nanoseconds. - int64_t date_utc = (ff_iso8601_to_unix_time(tag->value) - 978307200) * 1000000000; - uint8_t date_utc_buf[8]; - AV_WB64(date_utc_buf, date_utc); - put_ebml_binary(pb, MATROSKA_ID_DATEUTC, date_utc_buf, 8); - } - - // reserve space for the duration - mkv->duration = 0; - mkv->duration_offset = avio_tell(pb); - put_ebml_void(pb, 11); // assumes double-precision float to be written - end_ebml_master(pb, segment_info); - - ret = mkv_write_tracks(s); - if (ret < 0) return ret; - - if (mkv->mode != MODE_WEBM) { - ret = mkv_write_chapters(s); - if (ret < 0) return ret; - - ret = mkv_write_tags(s); - if (ret < 0) return ret; - - ret = mkv_write_attachments(s); - if (ret < 0) return ret; - } - - if (!s->pb->seekable) - mkv_write_seekhead(pb, mkv->main_seekhead); - - mkv->cues = mkv_start_cues(mkv->segment_offset); - if (mkv->cues == NULL) - return AVERROR(ENOMEM); - - av_init_packet(&mkv->cur_audio_pkt); - mkv->cur_audio_pkt.size = 0; - mkv->cluster_pos = -1; - - avio_flush(pb); - return 0; -} - -static int mkv_blockgroup_size(int pkt_size) -{ - int size = pkt_size + 4; - size += ebml_num_size(size); - size += 2; // EBML ID for block and block duration - size += 8; // max size of block duration - size += ebml_num_size(size); - size += 1; // blockgroup EBML ID - return size; -} - -static int ass_get_duration(const uint8_t *p) -{ - int sh, sm, ss, sc, eh, em, es, ec; - uint64_t start, end; - - if (sscanf(p, "%*[^,],%d:%d:%d%*c%d,%d:%d:%d%*c%d", - &sh, &sm, &ss, &sc, &eh, &em, &es, &ec) != 8) - return 0; - start = 3600000LL*sh + 60000LL*sm + 1000LL*ss + 10LL*sc; - end = 3600000LL*eh + 60000LL*em + 1000LL*es + 10LL*ec; - return end - start; -} - -static int mkv_write_ass_blocks(AVFormatContext *s, AVIOContext *pb, AVPacket *pkt) -{ - MatroskaMuxContext *mkv = s->priv_data; - int i, layer = 0, max_duration = 0, size, line_size, data_size = pkt->size; - uint8_t *start, *end, *data = pkt->data; - ebml_master blockgroup; - char buffer[2048]; - - while (data_size) { - int duration = ass_get_duration(data); - max_duration = FFMAX(duration, max_duration); - end = memchr(data, '\n', data_size); - size = line_size = end ? end-data+1 : data_size; - size -= end ? (end[-1]=='\r')+1 : 0; - start = data; - for (i=0; i<3; i++, start++) - if (!(start = memchr(start, ',', size-(start-data)))) - return max_duration; - size -= start - data; - sscanf(data, "Dialogue: %d,", &layer); - i = snprintf(buffer, sizeof(buffer), "%"PRId64",%d,", - s->streams[pkt->stream_index]->nb_frames, layer); - size = FFMIN(i+size, sizeof(buffer)); - memcpy(buffer+i, start, size-i); - - av_log(s, AV_LOG_DEBUG, "Writing block at offset %" PRIu64 ", size %d, " - "pts %" PRId64 ", duration %d\n", - avio_tell(pb), size, pkt->pts, duration); - blockgroup = start_ebml_master(pb, MATROSKA_ID_BLOCKGROUP, mkv_blockgroup_size(size)); - put_ebml_id(pb, MATROSKA_ID_BLOCK); - put_ebml_num(pb, size+4, 0); - avio_w8(pb, 0x80 | (pkt->stream_index + 1)); // this assumes stream_index is less than 126 - avio_wb16(pb, pkt->pts - mkv->cluster_pts); - avio_w8(pb, 0); - avio_write(pb, buffer, size); - put_ebml_uint(pb, MATROSKA_ID_BLOCKDURATION, duration); - end_ebml_master(pb, blockgroup); - - data += line_size; - data_size -= line_size; - } - - return max_duration; -} - -static void mkv_write_block(AVFormatContext *s, AVIOContext *pb, - unsigned int blockid, AVPacket *pkt, int flags) -{ - MatroskaMuxContext *mkv = s->priv_data; - AVCodecContext *codec = s->streams[pkt->stream_index]->codec; - uint8_t *data = NULL; - int offset = 0, size = pkt->size; - int64_t ts = mkv->tracks[pkt->stream_index].write_dts ? pkt->dts : pkt->pts; - - av_log(s, AV_LOG_DEBUG, "Writing block at offset %" PRIu64 ", size %d, " - "pts %" PRId64 ", dts %" PRId64 ", duration %d, flags %d\n", - avio_tell(pb), pkt->size, pkt->pts, pkt->dts, pkt->duration, flags); - if (codec->codec_id == AV_CODEC_ID_H264 && codec->extradata_size > 0 && - (AV_RB24(codec->extradata) == 1 || AV_RB32(codec->extradata) == 1)) - ff_avc_parse_nal_units_buf(pkt->data, &data, &size); - else - data = pkt->data; - - if (codec->codec_id == AV_CODEC_ID_PRORES) { - /* Matroska specification requires to remove the first QuickTime atom - */ - size -= 8; - offset = 8; - } - - put_ebml_id(pb, blockid); - put_ebml_num(pb, size+4, 0); - avio_w8(pb, 0x80 | (pkt->stream_index + 1)); // this assumes stream_index is less than 126 - avio_wb16(pb, ts - mkv->cluster_pts); - avio_w8(pb, flags); - avio_write(pb, data + offset, size); - if (data != pkt->data) - av_free(data); -} - -static int srt_get_duration(uint8_t **buf) -{ - int i, duration = 0; - - for (i=0; i<2 && !duration; i++) { - int s_hour, s_min, s_sec, s_hsec, e_hour, e_min, e_sec, e_hsec; - if (sscanf(*buf, "%d:%2d:%2d%*1[,.]%3d --> %d:%2d:%2d%*1[,.]%3d", - &s_hour, &s_min, &s_sec, &s_hsec, - &e_hour, &e_min, &e_sec, &e_hsec) == 8) { - s_min += 60*s_hour; e_min += 60*e_hour; - s_sec += 60*s_min; e_sec += 60*e_min; - s_hsec += 1000*s_sec; e_hsec += 1000*e_sec; - duration = e_hsec - s_hsec; - } - *buf += strcspn(*buf, "\n") + 1; - } - return duration; -} - -static int mkv_write_srt_blocks(AVFormatContext *s, AVIOContext *pb, AVPacket *pkt) -{ - ebml_master blockgroup; - AVPacket pkt2 = *pkt; - int64_t duration = srt_get_duration(&pkt2.data); - pkt2.size -= pkt2.data - pkt->data; - - blockgroup = start_ebml_master(pb, MATROSKA_ID_BLOCKGROUP, - mkv_blockgroup_size(pkt2.size)); - mkv_write_block(s, pb, MATROSKA_ID_BLOCK, &pkt2, 0); - put_ebml_uint(pb, MATROSKA_ID_BLOCKDURATION, duration); - end_ebml_master(pb, blockgroup); - - return duration; -} - -static void mkv_flush_dynbuf(AVFormatContext *s) -{ - MatroskaMuxContext *mkv = s->priv_data; - int bufsize; - uint8_t *dyn_buf; - - if (!mkv->dyn_bc) - return; - - bufsize = avio_close_dyn_buf(mkv->dyn_bc, &dyn_buf); - avio_write(s->pb, dyn_buf, bufsize); - av_free(dyn_buf); - mkv->dyn_bc = NULL; -} - -static int mkv_write_packet_internal(AVFormatContext *s, AVPacket *pkt) -{ - MatroskaMuxContext *mkv = s->priv_data; - AVIOContext *pb = s->pb; - AVCodecContext *codec = s->streams[pkt->stream_index]->codec; - int keyframe = !!(pkt->flags & AV_PKT_FLAG_KEY); - int duration = pkt->duration; - int ret; - int64_t ts = mkv->tracks[pkt->stream_index].write_dts ? pkt->dts : pkt->pts; - - if (ts == AV_NOPTS_VALUE) { - av_log(s, AV_LOG_ERROR, "Can't write packet with unknown timestamp\n"); - return AVERROR(EINVAL); - } - - if (!s->pb->seekable) { - if (!mkv->dyn_bc) { - if ((ret = avio_open_dyn_buf(&mkv->dyn_bc)) < 0) { - av_log(s, AV_LOG_ERROR, "Failed to open dynamic buffer\n"); - return ret; - } - } - pb = mkv->dyn_bc; - } - - if (mkv->cluster_pos == -1) { - mkv->cluster_pos = avio_tell(s->pb); - mkv->cluster = start_ebml_master(pb, MATROSKA_ID_CLUSTER, 0); - put_ebml_uint(pb, MATROSKA_ID_CLUSTERTIMECODE, FFMAX(0, ts)); - mkv->cluster_pts = FFMAX(0, ts); - } - - if (codec->codec_type != AVMEDIA_TYPE_SUBTITLE) { - mkv_write_block(s, pb, MATROSKA_ID_SIMPLEBLOCK, pkt, keyframe << 7); - } else if (codec->codec_id == AV_CODEC_ID_SSA) { - duration = mkv_write_ass_blocks(s, pb, pkt); - } else if (codec->codec_id == AV_CODEC_ID_SRT) { - duration = mkv_write_srt_blocks(s, pb, pkt); - } else { - ebml_master blockgroup = start_ebml_master(pb, MATROSKA_ID_BLOCKGROUP, mkv_blockgroup_size(pkt->size)); - /* For backward compatibility, prefer convergence_duration. */ - if (pkt->convergence_duration > 0) { - duration = pkt->convergence_duration; - } - mkv_write_block(s, pb, MATROSKA_ID_BLOCK, pkt, 0); - put_ebml_uint(pb, MATROSKA_ID_BLOCKDURATION, duration); - end_ebml_master(pb, blockgroup); - } - - if (codec->codec_type == AVMEDIA_TYPE_VIDEO && keyframe) { - ret = mkv_add_cuepoint(mkv->cues, pkt->stream_index, ts, mkv->cluster_pos); - if (ret < 0) return ret; - } - - mkv->duration = FFMAX(mkv->duration, ts + duration); - return 0; -} - -static int mkv_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - MatroskaMuxContext *mkv = s->priv_data; - AVIOContext *pb = s->pb->seekable ? s->pb : mkv->dyn_bc; - AVCodecContext *codec = s->streams[pkt->stream_index]->codec; - int ret, keyframe = !!(pkt->flags & AV_PKT_FLAG_KEY); - int64_t ts = mkv->tracks[pkt->stream_index].write_dts ? pkt->dts : pkt->pts; - int cluster_size = avio_tell(pb) - (s->pb->seekable ? mkv->cluster_pos : 0); - - // start a new cluster every 5 MB or 5 sec, or 32k / 1 sec for streaming or - // after 4k and on a keyframe - if (mkv->cluster_pos != -1 && - ((!s->pb->seekable && (cluster_size > 32*1024 || ts > mkv->cluster_pts + 1000)) - || cluster_size > 5*1024*1024 || ts > mkv->cluster_pts + 5000 - || (codec->codec_type == AVMEDIA_TYPE_VIDEO && keyframe && cluster_size > 4*1024))) { - av_log(s, AV_LOG_DEBUG, "Starting new cluster at offset %" PRIu64 - " bytes, pts %" PRIu64 "\n", avio_tell(pb), ts); - end_ebml_master(pb, mkv->cluster); - mkv->cluster_pos = -1; - if (mkv->dyn_bc) - mkv_flush_dynbuf(s); - } - - // check if we have an audio packet cached - if (mkv->cur_audio_pkt.size > 0) { - ret = mkv_write_packet_internal(s, &mkv->cur_audio_pkt); - av_free_packet(&mkv->cur_audio_pkt); - if (ret < 0) { - av_log(s, AV_LOG_ERROR, "Could not write cached audio packet ret:%d\n", ret); - return ret; - } - } - - // buffer an audio packet to ensure the packet containing the video - // keyframe's timecode is contained in the same cluster for WebM - if (codec->codec_type == AVMEDIA_TYPE_AUDIO) { - mkv->cur_audio_pkt = *pkt; - mkv->cur_audio_pkt.buf = av_buffer_ref(pkt->buf); - ret = mkv->cur_audio_pkt.buf ? 0 : AVERROR(ENOMEM); - } else - ret = mkv_write_packet_internal(s, pkt); - return ret; -} - -static int mkv_write_trailer(AVFormatContext *s) -{ - MatroskaMuxContext *mkv = s->priv_data; - AVIOContext *pb = s->pb; - int64_t currentpos, cuespos; - int ret; - - // check if we have an audio packet cached - if (mkv->cur_audio_pkt.size > 0) { - ret = mkv_write_packet_internal(s, &mkv->cur_audio_pkt); - av_free_packet(&mkv->cur_audio_pkt); - if (ret < 0) { - av_log(s, AV_LOG_ERROR, "Could not write cached audio packet ret:%d\n", ret); - return ret; - } - } - - if (mkv->dyn_bc) { - end_ebml_master(mkv->dyn_bc, mkv->cluster); - mkv_flush_dynbuf(s); - } else if (mkv->cluster_pos != -1) { - end_ebml_master(pb, mkv->cluster); - } - - if (pb->seekable) { - if (mkv->cues->num_entries) { - cuespos = mkv_write_cues(pb, mkv->cues, mkv->tracks, s->nb_streams); - - ret = mkv_add_seekhead_entry(mkv->main_seekhead, MATROSKA_ID_CUES, cuespos); - if (ret < 0) return ret; - } - - mkv_write_seekhead(pb, mkv->main_seekhead); - - // update the duration - av_log(s, AV_LOG_DEBUG, "end duration = %" PRIu64 "\n", mkv->duration); - currentpos = avio_tell(pb); - avio_seek(pb, mkv->duration_offset, SEEK_SET); - put_ebml_float(pb, MATROSKA_ID_DURATION, mkv->duration); - - avio_seek(pb, currentpos, SEEK_SET); - } - - end_ebml_master(pb, mkv->segment); - av_free(mkv->tracks); - av_freep(&mkv->cues->entries); - av_freep(&mkv->cues); - - return 0; -} - -static int mkv_query_codec(enum AVCodecID codec_id, int std_compliance) -{ - int i; - for (i = 0; ff_mkv_codec_tags[i].id != AV_CODEC_ID_NONE; i++) - if (ff_mkv_codec_tags[i].id == codec_id) - return 1; - - if (std_compliance < FF_COMPLIANCE_NORMAL) { // mkv theoretically supports any - enum AVMediaType type = avcodec_get_type(codec_id); // video/audio through VFW/ACM - if (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO) - return 1; - } - - return 0; -} - -const AVCodecTag additional_audio_tags[] = { - { AV_CODEC_ID_ALAC, 0XFFFFFFFF }, - { AV_CODEC_ID_EAC3, 0XFFFFFFFF }, - { AV_CODEC_ID_MLP, 0xFFFFFFFF }, - { AV_CODEC_ID_OPUS, 0xFFFFFFFF }, - { AV_CODEC_ID_PCM_S16BE, 0xFFFFFFFF }, - { AV_CODEC_ID_PCM_S24BE, 0xFFFFFFFF }, - { AV_CODEC_ID_PCM_S32BE, 0xFFFFFFFF }, - { AV_CODEC_ID_QDM2, 0xFFFFFFFF }, - { AV_CODEC_ID_RA_144, 0xFFFFFFFF }, - { AV_CODEC_ID_RA_288, 0xFFFFFFFF }, - { AV_CODEC_ID_COOK, 0xFFFFFFFF }, - { AV_CODEC_ID_TRUEHD, 0xFFFFFFFF }, - { AV_CODEC_ID_WAVPACK, 0xFFFFFFFF }, - { AV_CODEC_ID_NONE, 0xFFFFFFFF } -}; - -const AVCodecTag additional_video_tags[] = { - { AV_CODEC_ID_PRORES, 0xFFFFFFFF }, - { AV_CODEC_ID_RV10, 0xFFFFFFFF }, - { AV_CODEC_ID_RV20, 0xFFFFFFFF }, - { AV_CODEC_ID_RV30, 0xFFFFFFFF }, - { AV_CODEC_ID_RV40, 0xFFFFFFFF }, - { AV_CODEC_ID_VP9, 0xFFFFFFFF }, - { AV_CODEC_ID_NONE, 0xFFFFFFFF } -}; - -#if CONFIG_MATROSKA_MUXER -AVOutputFormat ff_matroska_muxer = { - .name = "matroska", - .long_name = NULL_IF_CONFIG_SMALL("Matroska"), - .mime_type = "video/x-matroska", - .extensions = "mkv", - .priv_data_size = sizeof(MatroskaMuxContext), - .audio_codec = CONFIG_LIBVORBIS_ENCODER ? - AV_CODEC_ID_VORBIS : AV_CODEC_ID_AC3, - .video_codec = CONFIG_LIBX264_ENCODER ? - AV_CODEC_ID_H264 : AV_CODEC_ID_MPEG4, - .write_header = mkv_write_header, - .write_packet = mkv_write_packet, - .write_trailer = mkv_write_trailer, - .flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS | - AVFMT_TS_NONSTRICT, - .codec_tag = (const AVCodecTag* const []){ - ff_codec_bmp_tags, ff_codec_wav_tags, - additional_audio_tags, additional_video_tags, 0 - }, - .subtitle_codec = AV_CODEC_ID_SSA, - .query_codec = mkv_query_codec, -}; -#endif - -#if CONFIG_WEBM_MUXER -AVOutputFormat ff_webm_muxer = { - .name = "webm", - .long_name = NULL_IF_CONFIG_SMALL("WebM"), - .mime_type = "video/webm", - .extensions = "webm", - .priv_data_size = sizeof(MatroskaMuxContext), - .audio_codec = AV_CODEC_ID_VORBIS, - .video_codec = AV_CODEC_ID_VP8, - .write_header = mkv_write_header, - .write_packet = mkv_write_packet, - .write_trailer = mkv_write_trailer, - .flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS | - AVFMT_TS_NONSTRICT, -}; -#endif - -#if CONFIG_MATROSKA_AUDIO_MUXER -AVOutputFormat ff_matroska_audio_muxer = { - .name = "matroska", - .long_name = NULL_IF_CONFIG_SMALL("Matroska"), - .mime_type = "audio/x-matroska", - .extensions = "mka", - .priv_data_size = sizeof(MatroskaMuxContext), - .audio_codec = CONFIG_LIBVORBIS_ENCODER ? - AV_CODEC_ID_VORBIS : AV_CODEC_ID_AC3, - .video_codec = AV_CODEC_ID_NONE, - .write_header = mkv_write_header, - .write_packet = mkv_write_packet, - .write_trailer = mkv_write_trailer, - .flags = AVFMT_GLOBALHEADER | AVFMT_TS_NONSTRICT, - .codec_tag = (const AVCodecTag* const []){ - ff_codec_wav_tags, additional_audio_tags, 0 - }, -}; -#endif diff --git a/ffmpeg1/libavformat/md5enc.c b/ffmpeg1/libavformat/md5enc.c deleted file mode 100644 index 050efb1..0000000 --- a/ffmpeg1/libavformat/md5enc.c +++ /dev/null @@ -1,130 +0,0 @@ -/* - * MD5 encoder (for codec/format testing) - * Copyright (c) 2009 Reimar Döffinger, based on crcenc (c) 2002 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 "libavutil/md5.h" -#include "avformat.h" -#include "internal.h" - -struct MD5Context { - struct AVMD5 *md5; -}; - -static void md5_finish(struct AVFormatContext *s, char *buf) -{ - struct MD5Context *c = s->priv_data; - uint8_t md5[16]; - int i, offset = strlen(buf); - av_md5_final(c->md5, md5); - for (i = 0; i < sizeof(md5); i++) { - snprintf(buf + offset, 3, "%02"PRIx8, md5[i]); - offset += 2; - } - buf[offset] = '\n'; - buf[offset+1] = 0; - - avio_write(s->pb, buf, strlen(buf)); - avio_flush(s->pb); -} - -#if CONFIG_MD5_MUXER -static int write_header(struct AVFormatContext *s) -{ - struct MD5Context *c = s->priv_data; - c->md5 = av_md5_alloc(); - if (!c->md5) - return AVERROR(ENOMEM); - av_md5_init(c->md5); - return 0; -} - -static int write_packet(struct AVFormatContext *s, AVPacket *pkt) -{ - struct MD5Context *c = s->priv_data; - av_md5_update(c->md5, pkt->data, pkt->size); - return 0; -} - -static int write_trailer(struct AVFormatContext *s) -{ - struct MD5Context *c = s->priv_data; - char buf[64] = "MD5="; - - md5_finish(s, buf); - - av_freep(&c->md5); - return 0; -} - -AVOutputFormat ff_md5_muxer = { - .name = "md5", - .long_name = NULL_IF_CONFIG_SMALL("MD5 testing"), - .priv_data_size = sizeof(struct MD5Context), - .audio_codec = AV_CODEC_ID_PCM_S16LE, - .video_codec = AV_CODEC_ID_RAWVIDEO, - .write_header = write_header, - .write_packet = write_packet, - .write_trailer = write_trailer, - .flags = AVFMT_NOTIMESTAMPS, -}; -#endif - -#if CONFIG_FRAMEMD5_MUXER -static int framemd5_write_header(struct AVFormatContext *s) -{ - struct MD5Context *c = s->priv_data; - c->md5 = av_md5_alloc(); - if (!c->md5) - return AVERROR(ENOMEM); - return ff_framehash_write_header(s); -} - -static int framemd5_write_packet(struct AVFormatContext *s, AVPacket *pkt) -{ - struct MD5Context *c = s->priv_data; - char buf[256]; - av_md5_init(c->md5); - av_md5_update(c->md5, pkt->data, pkt->size); - - snprintf(buf, sizeof(buf) - 64, "%d, %10"PRId64", %10"PRId64", %8d, %8d, ", - pkt->stream_index, pkt->dts, pkt->pts, pkt->duration, pkt->size); - md5_finish(s, buf); - return 0; -} - -static int framemd5_write_trailer(struct AVFormatContext *s) -{ - struct MD5Context *c = s->priv_data; - av_freep(&c->md5); - return 0; -} - -AVOutputFormat ff_framemd5_muxer = { - .name = "framemd5", - .long_name = NULL_IF_CONFIG_SMALL("Per-frame MD5 testing"), - .priv_data_size = sizeof(struct MD5Context), - .audio_codec = AV_CODEC_ID_PCM_S16LE, - .video_codec = AV_CODEC_ID_RAWVIDEO, - .write_header = framemd5_write_header, - .write_packet = framemd5_write_packet, - .write_trailer = framemd5_write_trailer, - .flags = AVFMT_VARIABLE_FPS | AVFMT_TS_NONSTRICT, -}; -#endif diff --git a/ffmpeg1/libavformat/md5proto.c b/ffmpeg1/libavformat/md5proto.c deleted file mode 100644 index 6af0a6e..0000000 --- a/ffmpeg1/libavformat/md5proto.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2010 Mans Rullgard - * - * 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 -#include "libavutil/avstring.h" -#include "libavutil/md5.h" -#include "libavutil/mem.h" -#include "libavutil/error.h" -#include "avformat.h" -#include "avio.h" -#include "url.h" - -struct MD5Context { - struct AVMD5 *md5; -}; - -static int md5_open(URLContext *h, const char *filename, int flags) -{ - struct MD5Context *c = h->priv_data; - - if (!(flags & AVIO_FLAG_WRITE)) - return AVERROR(EINVAL); - - c->md5 = av_md5_alloc(); - if (!c->md5) - return AVERROR(ENOMEM); - av_md5_init(c->md5); - - return 0; -} - -static int md5_write(URLContext *h, const unsigned char *buf, int size) -{ - struct MD5Context *c = h->priv_data; - av_md5_update(c->md5, buf, size); - return size; -} - -static int md5_close(URLContext *h) -{ - struct MD5Context *c = h->priv_data; - const char *filename = h->filename; - uint8_t md5[16], buf[64]; - URLContext *out; - int i, err = 0; - - av_md5_final(c->md5, md5); - for (i = 0; i < sizeof(md5); i++) - snprintf(buf + i*2, 3, "%02x", md5[i]); - buf[i*2] = '\n'; - - av_strstart(filename, "md5:", &filename); - - if (*filename) { - err = ffurl_open(&out, filename, AVIO_FLAG_WRITE, - &h->interrupt_callback, NULL); - if (err) - return err; - err = ffurl_write(out, buf, i*2+1); - ffurl_close(out); - } else { - if (fwrite(buf, 1, i*2+1, stdout) < i*2+1) - err = AVERROR(errno); - } - - av_freep(&c->md5); - - return err; -} - - -URLProtocol ff_md5_protocol = { - .name = "md5", - .url_open = md5_open, - .url_write = md5_write, - .url_close = md5_close, - .priv_data_size = sizeof(struct MD5Context), -}; diff --git a/ffmpeg1/libavformat/metadata.c b/ffmpeg1/libavformat/metadata.c deleted file mode 100644 index fc3a9d7..0000000 --- a/ffmpeg1/libavformat/metadata.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * copyright (c) 2009 Michael Niedermayer - * - * 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 "metadata.h" -#include "libavutil/dict.h" -#include "libavutil/avstring.h" - -void ff_metadata_conv(AVDictionary **pm, const AVMetadataConv *d_conv, - const AVMetadataConv *s_conv) -{ - /* TODO: use binary search to look up the two conversion tables - if the tables are getting big enough that it would matter speed wise */ - const AVMetadataConv *sc, *dc; - AVDictionaryEntry *mtag = NULL; - AVDictionary *dst = NULL; - const char *key; - - if (d_conv == s_conv) - return; - - while ((mtag = av_dict_get(*pm, "", mtag, AV_DICT_IGNORE_SUFFIX))) { - key = mtag->key; - if (s_conv) - for (sc=s_conv; sc->native; sc++) - if (!av_strcasecmp(key, sc->native)) { - key = sc->generic; - break; - } - if (d_conv) - for (dc=d_conv; dc->native; dc++) - if (!av_strcasecmp(key, dc->generic)) { - key = dc->native; - break; - } - av_dict_set(&dst, key, mtag->value, 0); - } - av_dict_free(pm); - *pm = dst; -} - -void ff_metadata_conv_ctx(AVFormatContext *ctx, const AVMetadataConv *d_conv, - const AVMetadataConv *s_conv) -{ - int i; - ff_metadata_conv(&ctx->metadata, d_conv, s_conv); - for (i=0; inb_streams ; i++) - ff_metadata_conv(&ctx->streams [i]->metadata, d_conv, s_conv); - for (i=0; inb_chapters; i++) - ff_metadata_conv(&ctx->chapters[i]->metadata, d_conv, s_conv); - for (i=0; inb_programs; i++) - ff_metadata_conv(&ctx->programs[i]->metadata, d_conv, s_conv); -} diff --git a/ffmpeg1/libavformat/metadata.h b/ffmpeg1/libavformat/metadata.h deleted file mode 100644 index 6586094..0000000 --- a/ffmpeg1/libavformat/metadata.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * copyright (c) 2009 Michael Niedermayer - * - * 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 AVFORMAT_METADATA_H -#define AVFORMAT_METADATA_H - -/** - * @file - * internal metadata API header - * see avformat.h or the public API! - */ - - -#include "avformat.h" -#include "libavutil/dict.h" - -typedef struct AVMetadataConv { - const char *native; - const char *generic; -} AVMetadataConv; - -void ff_metadata_conv(AVDictionary **pm, const AVMetadataConv *d_conv, - const AVMetadataConv *s_conv); -void ff_metadata_conv_ctx(AVFormatContext *ctx, const AVMetadataConv *d_conv, - const AVMetadataConv *s_conv); - -#endif /* AVFORMAT_METADATA_H */ diff --git a/ffmpeg1/libavformat/mgsts.c b/ffmpeg1/libavformat/mgsts.c deleted file mode 100644 index dec6bfc..0000000 --- a/ffmpeg1/libavformat/mgsts.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Metar Gear Solid: The Twin Snakes demuxer - * Copyright (c) 2012 Paul B Mahol - * - * 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 "libavutil/intreadwrite.h" -#include "libavutil/intfloat.h" -#include "avformat.h" -#include "riff.h" - -static int read_probe(AVProbeData *p) -{ - if (AV_RB32(p->buf ) != 0x000E || - AV_RB32(p->buf + 4) != 0x0050 || - AV_RB32(p->buf + 12) != 0x0034) - return 0; - return AVPROBE_SCORE_MAX; -} - -static int read_header(AVFormatContext *s) -{ - AVIOContext *pb = s->pb; - AVStream *st; - AVRational fps; - uint32_t chunk_size; - - avio_skip(pb, 4); - chunk_size = avio_rb32(pb); - if (chunk_size != 80) - return AVERROR(EIO); - avio_skip(pb, 20); - - st = avformat_new_stream(s, 0); - if (!st) - return AVERROR(ENOMEM); - - st->need_parsing = AVSTREAM_PARSE_HEADERS; - st->start_time = 0; - st->nb_frames = - st->duration = avio_rb32(pb); - fps = av_d2q(av_int2float(avio_rb32(pb)), INT_MAX); - st->codec->width = avio_rb32(pb); - st->codec->height = avio_rb32(pb); - avio_skip(pb, 12); - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_tag = avio_rb32(pb); - st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, - st->codec->codec_tag); - avpriv_set_pts_info(st, 64, fps.den, fps.num); - avio_skip(pb, 20); - - return 0; -} - -static int read_packet(AVFormatContext *s, AVPacket *pkt) -{ - AVIOContext *pb = s->pb; - uint32_t chunk_size, payload_size; - int ret; - - if (url_feof(pb)) - return AVERROR_EOF; - - avio_skip(pb, 4); - chunk_size = avio_rb32(pb); - avio_skip(pb, 4); - payload_size = avio_rb32(pb); - - if (chunk_size < payload_size + 16) - return AVERROR(EIO); - - ret = av_get_packet(pb, pkt, payload_size); - if (ret < 0) - return ret; - - pkt->pos -= 16; - pkt->duration = 1; - avio_skip(pb, chunk_size - (ret + 16)); - - return ret; -} - -AVInputFormat ff_mgsts_demuxer = { - .name = "mgsts", - .long_name = NULL_IF_CONFIG_SMALL("Metal Gear Solid: The Twin Snakes"), - .read_probe = read_probe, - .read_header = read_header, - .read_packet = read_packet, - .flags = AVFMT_GENERIC_INDEX, -}; diff --git a/ffmpeg1/libavformat/microdvddec.c b/ffmpeg1/libavformat/microdvddec.c deleted file mode 100644 index 4b42846..0000000 --- a/ffmpeg1/libavformat/microdvddec.c +++ /dev/null @@ -1,167 +0,0 @@ -/* - * MicroDVD subtitle demuxer - * Copyright (c) 2010 Aurelien Jacobs - * Copyright (c) 2012 Clément BÅ“sch - * - * 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 "internal.h" -#include "subtitles.h" -#include "libavutil/intreadwrite.h" - -#define MAX_LINESIZE 2048 - - -typedef struct { - FFDemuxSubtitlesQueue q; -} MicroDVDContext; - - -static int microdvd_probe(AVProbeData *p) -{ - unsigned char c; - const uint8_t *ptr = p->buf; - int i; - - if (AV_RB24(ptr) == 0xEFBBBF) - ptr += 3; /* skip UTF-8 BOM */ - - for (i=0; i<3; i++) { - if (sscanf(ptr, "{%*d}{}%c", &c) != 1 && - sscanf(ptr, "{%*d}{%*d}%c", &c) != 1 && - sscanf(ptr, "{DEFAULT}{}%c", &c) != 1) - return 0; - ptr += strcspn(ptr, "\n") + 1; - } - return AVPROBE_SCORE_MAX; -} - -static int64_t get_pts(const char *buf) -{ - int frame; - char c; - - if (sscanf(buf, "{%d}{%c", &frame, &c) == 2) - return frame; - return AV_NOPTS_VALUE; -} - -static int get_duration(const char *buf) -{ - int frame_start, frame_end; - - if (sscanf(buf, "{%d}{%d}", &frame_start, &frame_end) == 2) - return frame_end - frame_start; - return -1; -} - -static int microdvd_read_header(AVFormatContext *s) -{ - AVRational pts_info = (AVRational){ 2997, 125 }; /* default: 23.976 fps */ - MicroDVDContext *microdvd = s->priv_data; - AVStream *st = avformat_new_stream(s, NULL); - int i = 0; - char line[MAX_LINESIZE]; - - if (!st) - return AVERROR(ENOMEM); - - while (!url_feof(s->pb)) { - char *p = line; - AVPacket *sub; - int64_t pos = avio_tell(s->pb); - int len = ff_get_line(s->pb, line, sizeof(line)); - - if (!len) - break; - line[strcspn(line, "\r\n")] = 0; - if (i++ < 3) { - int frame; - double fps; - char c; - - if ((sscanf(line, "{%d}{}%6lf", &frame, &fps) == 2 || - sscanf(line, "{%d}{%*d}%6lf", &frame, &fps) == 2) - && frame <= 1 && fps > 3 && fps < 100) - pts_info = av_d2q(fps, 100000); - if (!st->codec->extradata && sscanf(line, "{DEFAULT}{}%c", &c) == 1) { - st->codec->extradata = av_strdup(line + 11); - if (!st->codec->extradata) - return AVERROR(ENOMEM); - st->codec->extradata_size = strlen(st->codec->extradata) + 1; - continue; - } - } -#define SKIP_FRAME_ID \ - p = strchr(p, '}'); \ - if (!p) { \ - av_log(s, AV_LOG_WARNING, "Invalid event \"%s\"" \ - " at line %d\n", line, i); \ - continue; \ - } \ - p++ - SKIP_FRAME_ID; - SKIP_FRAME_ID; - if (!*p) - continue; - sub = ff_subtitles_queue_insert(µdvd->q, p, strlen(p), 0); - if (!sub) - return AVERROR(ENOMEM); - sub->pos = pos; - sub->pts = get_pts(line); - sub->duration = get_duration(line); - } - ff_subtitles_queue_finalize(µdvd->q); - avpriv_set_pts_info(st, 64, pts_info.den, pts_info.num); - st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE; - st->codec->codec_id = AV_CODEC_ID_MICRODVD; - return 0; -} - -static int microdvd_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - MicroDVDContext *microdvd = s->priv_data; - return ff_subtitles_queue_read_packet(µdvd->q, pkt); -} - -static int microdvd_read_seek(AVFormatContext *s, int stream_index, - int64_t min_ts, int64_t ts, int64_t max_ts, int flags) -{ - MicroDVDContext *microdvd = s->priv_data; - return ff_subtitles_queue_seek(µdvd->q, s, stream_index, - min_ts, ts, max_ts, flags); -} - -static int microdvd_read_close(AVFormatContext *s) -{ - MicroDVDContext *microdvd = s->priv_data; - ff_subtitles_queue_clean(µdvd->q); - return 0; -} - -AVInputFormat ff_microdvd_demuxer = { - .name = "microdvd", - .long_name = NULL_IF_CONFIG_SMALL("MicroDVD subtitle format"), - .priv_data_size = sizeof(MicroDVDContext), - .read_probe = microdvd_probe, - .read_header = microdvd_read_header, - .read_packet = microdvd_read_packet, - .read_seek2 = microdvd_read_seek, - .read_close = microdvd_read_close, -}; diff --git a/ffmpeg1/libavformat/microdvdenc.c b/ffmpeg1/libavformat/microdvdenc.c deleted file mode 100644 index 30fd0ea..0000000 --- a/ffmpeg1/libavformat/microdvdenc.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * MicroDVD subtitle muxer - * Copyright (c) 2010 Aurelien Jacobs - * - * 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 -#include "avformat.h" -#include "internal.h" - -static int microdvd_write_header(struct AVFormatContext *s) -{ - AVCodecContext *avctx = s->streams[0]->codec; - AVRational tb = avctx->time_base; - - if (s->nb_streams != 1 || avctx->codec_id != AV_CODEC_ID_MICRODVD) { - av_log(s, AV_LOG_ERROR, "Exactly one MicroDVD stream is needed.\n"); - return -1; - } - - if (avctx->extradata && avctx->extradata_size > 0) { - avio_write(s->pb, "{DEFAULT}{}", 11); - avio_write(s->pb, avctx->extradata, avctx->extradata_size); - avio_flush(s->pb); - } - - avpriv_set_pts_info(s->streams[0], 64, tb.num, tb.den); - return 0; -} - -static int microdvd_write_packet(AVFormatContext *avf, AVPacket *pkt) -{ - avio_printf(avf->pb, "{%"PRId64"}", pkt->pts); - if (pkt->duration < 0) - avio_write(avf->pb, "{}", 2); - else - avio_printf(avf->pb, "{%"PRId64"}", pkt->pts + pkt->duration); - avio_write(avf->pb, pkt->data, pkt->size); - avio_write(avf->pb, "\n", 1); - avio_flush(avf->pb); - return 0; -} - -AVOutputFormat ff_microdvd_muxer = { - .name = "microdvd", - .long_name = NULL_IF_CONFIG_SMALL("MicroDVD subtitle format"), - .mime_type = "text/x-microdvd", - .extensions = "sub", - .write_header = microdvd_write_header, - .write_packet = microdvd_write_packet, - .flags = AVFMT_NOTIMESTAMPS, - .subtitle_codec = AV_CODEC_ID_MICRODVD, -}; diff --git a/ffmpeg1/libavformat/mkvtimestamp_v2.c b/ffmpeg1/libavformat/mkvtimestamp_v2.c deleted file mode 100644 index 3ed195a..0000000 --- a/ffmpeg1/libavformat/mkvtimestamp_v2.c +++ /dev/null @@ -1,51 +0,0 @@ -/* - * extract pts as timecode v2, as defined by mkvtoolnix - * Copyright (c) 2009 David Conrad - * - * 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 "internal.h" - -static int write_header(AVFormatContext *s) -{ - static const char *header = "# timecode format v2\n"; - avio_write(s->pb, header, strlen(header)); - avpriv_set_pts_info(s->streams[0], 64, 1, 1000); - return 0; -} - -static int write_packet(AVFormatContext *s, AVPacket *pkt) -{ - char buf[256]; - if (pkt->stream_index) - av_log(s, AV_LOG_WARNING, "More than one stream unsupported\n"); - snprintf(buf, sizeof(buf), "%" PRId64 "\n", pkt->dts); - avio_write(s->pb, buf, strlen(buf)); - avio_flush(s->pb); - return 0; -} - -AVOutputFormat ff_mkvtimestamp_v2_muxer = { - .name = "mkvtimestamp_v2", - .long_name = NULL_IF_CONFIG_SMALL("extract pts as timecode v2 format, as defined by mkvtoolnix"), - .audio_codec = AV_CODEC_ID_NONE, - .video_codec = AV_CODEC_ID_RAWVIDEO, - .write_header = write_header, - .write_packet = write_packet, -}; diff --git a/ffmpeg1/libavformat/mm.c b/ffmpeg1/libavformat/mm.c deleted file mode 100644 index 12a11ac..0000000 --- a/ffmpeg1/libavformat/mm.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - * American Laser Games MM Format Demuxer - * Copyright (c) 2006 Peter Ross - * - * 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 - */ - -/** - * @file - * American Laser Games MM Format Demuxer - * by Peter Ross (pross@xvid.org) - * - * The MM format was used by IBM-PC ports of ALG's "arcade shooter" games, - * including Mad Dog McCree and Crime Patrol. - * - * Technical details here: - * http://wiki.multimedia.cx/index.php?title=American_Laser_Games_MM - */ - -#include "libavutil/channel_layout.h" -#include "libavutil/intreadwrite.h" -#include "avformat.h" -#include "internal.h" - -#define MM_PREAMBLE_SIZE 6 - -#define MM_TYPE_HEADER 0x0 -#define MM_TYPE_INTER 0x5 -#define MM_TYPE_INTRA 0x8 -#define MM_TYPE_INTRA_HH 0xc -#define MM_TYPE_INTER_HH 0xd -#define MM_TYPE_INTRA_HHV 0xe -#define MM_TYPE_INTER_HHV 0xf -#define MM_TYPE_AUDIO 0x15 -#define MM_TYPE_PALETTE 0x31 - -#define MM_HEADER_LEN_V 0x16 /* video only */ -#define MM_HEADER_LEN_AV 0x18 /* video + audio */ - -#define MM_PALETTE_COUNT 128 -#define MM_PALETTE_SIZE (MM_PALETTE_COUNT*3) - -typedef struct { - unsigned int audio_pts, video_pts; -} MmDemuxContext; - -static int probe(AVProbeData *p) -{ - int len, type, fps, w, h; - if (p->buf_size < MM_HEADER_LEN_AV + MM_PREAMBLE_SIZE) - return 0; - /* the first chunk is always the header */ - if (AV_RL16(&p->buf[0]) != MM_TYPE_HEADER) - return 0; - len = AV_RL32(&p->buf[2]); - if (len != MM_HEADER_LEN_V && len != MM_HEADER_LEN_AV) - return 0; - fps = AV_RL16(&p->buf[8]); - w = AV_RL16(&p->buf[12]); - h = AV_RL16(&p->buf[14]); - if (!fps || fps > 60 || !w || w > 2048 || !h || h > 2048) - return 0; - type = AV_RL16(&p->buf[len]); - if (!type || type > 0x31) - return 0; - - /* only return half certainty since this check is a bit sketchy */ - return AVPROBE_SCORE_MAX / 2; -} - -static int read_header(AVFormatContext *s) -{ - MmDemuxContext *mm = s->priv_data; - AVIOContext *pb = s->pb; - AVStream *st; - - unsigned int type, length; - unsigned int frame_rate, width, height; - - type = avio_rl16(pb); - length = avio_rl32(pb); - - if (type != MM_TYPE_HEADER) - return AVERROR_INVALIDDATA; - - /* read header */ - avio_rl16(pb); /* total number of chunks */ - frame_rate = avio_rl16(pb); - avio_rl16(pb); /* ibm-pc video bios mode */ - width = avio_rl16(pb); - height = avio_rl16(pb); - avio_skip(pb, length - 10); /* unknown data */ - - /* video stream */ - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = AV_CODEC_ID_MMVIDEO; - st->codec->codec_tag = 0; /* no fourcc */ - st->codec->width = width; - st->codec->height = height; - avpriv_set_pts_info(st, 64, 1, frame_rate); - - /* audio stream */ - if (length == MM_HEADER_LEN_AV) { - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_tag = 0; /* no fourcc */ - st->codec->codec_id = AV_CODEC_ID_PCM_U8; - st->codec->channels = 1; - st->codec->channel_layout = AV_CH_LAYOUT_MONO; - st->codec->sample_rate = 8000; - avpriv_set_pts_info(st, 64, 1, 8000); /* 8000 hz */ - } - - mm->audio_pts = 0; - mm->video_pts = 0; - return 0; -} - -static int read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - MmDemuxContext *mm = s->priv_data; - AVIOContext *pb = s->pb; - unsigned char preamble[MM_PREAMBLE_SIZE]; - unsigned int type, length; - - while(1) { - - if (avio_read(pb, preamble, MM_PREAMBLE_SIZE) != MM_PREAMBLE_SIZE) { - return AVERROR(EIO); - } - - type = AV_RL16(&preamble[0]); - length = AV_RL16(&preamble[2]); - - switch(type) { - case MM_TYPE_PALETTE : - case MM_TYPE_INTER : - case MM_TYPE_INTRA : - case MM_TYPE_INTRA_HH : - case MM_TYPE_INTER_HH : - case MM_TYPE_INTRA_HHV : - case MM_TYPE_INTER_HHV : - /* output preamble + data */ - if (av_new_packet(pkt, length + MM_PREAMBLE_SIZE)) - return AVERROR(ENOMEM); - memcpy(pkt->data, preamble, MM_PREAMBLE_SIZE); - if (avio_read(pb, pkt->data + MM_PREAMBLE_SIZE, length) != length) - return AVERROR(EIO); - pkt->size = length + MM_PREAMBLE_SIZE; - pkt->stream_index = 0; - pkt->pts = mm->video_pts; - if (type!=MM_TYPE_PALETTE) - mm->video_pts++; - return 0; - - case MM_TYPE_AUDIO : - if (av_get_packet(s->pb, pkt, length)<0) - return AVERROR(ENOMEM); - pkt->stream_index = 1; - pkt->pts = mm->audio_pts++; - return 0; - - default : - av_log(s, AV_LOG_INFO, "unknown chunk type 0x%x\n", type); - avio_skip(pb, length); - } - } -} - -AVInputFormat ff_mm_demuxer = { - .name = "mm", - .long_name = NULL_IF_CONFIG_SMALL("American Laser Games MM"), - .priv_data_size = sizeof(MmDemuxContext), - .read_probe = probe, - .read_header = read_header, - .read_packet = read_packet, -}; diff --git a/ffmpeg1/libavformat/mmf.c b/ffmpeg1/libavformat/mmf.c deleted file mode 100644 index d074d7c..0000000 --- a/ffmpeg1/libavformat/mmf.c +++ /dev/null @@ -1,319 +0,0 @@ -/* - * Yamaha SMAF format - * Copyright (c) 2005 Vidar Madsen - * - * 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 "libavutil/channel_layout.h" -#include "avformat.h" -#include "internal.h" -#include "avio_internal.h" -#include "pcm.h" -#include "rawenc.h" -#include "riff.h" - -typedef struct { - int64_t atrpos, atsqpos, awapos; - int64_t data_end; - int stereo; -} MMFContext; - -static const int mmf_rates[] = { 4000, 8000, 11025, 22050, 44100 }; - -static int mmf_rate(int code) -{ - if((code < 0) || (code > 4)) - return -1; - return mmf_rates[code]; -} - -#if CONFIG_MMF_MUXER -static int mmf_rate_code(int rate) -{ - int i; - for(i = 0; i < 5; i++) - if(mmf_rates[i] == rate) - return i; - return -1; -} - -/* Copy of end_tag() from avienc.c, but for big-endian chunk size */ -static void end_tag_be(AVIOContext *pb, int64_t start) -{ - int64_t pos; - - pos = avio_tell(pb); - avio_seek(pb, start - 4, SEEK_SET); - avio_wb32(pb, (uint32_t)(pos - start)); - avio_seek(pb, pos, SEEK_SET); -} - -static int mmf_write_header(AVFormatContext *s) -{ - MMFContext *mmf = s->priv_data; - AVIOContext *pb = s->pb; - int64_t pos; - int rate; - const char *version = s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT ? - "VN:Lavf," : - "VN:"LIBAVFORMAT_IDENT","; - - rate = mmf_rate_code(s->streams[0]->codec->sample_rate); - if(rate < 0) { - av_log(s, AV_LOG_ERROR, "Unsupported sample rate %d, supported are 4000, 8000, 11025, 22050 and 44100\n", s->streams[0]->codec->sample_rate); - return AVERROR(EINVAL); - } - - mmf->stereo = s->streams[0]->codec->channels > 1; - if (mmf->stereo && - s->streams[0]->codec->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) { - av_log(s, AV_LOG_ERROR, "Yamaha SMAF stereo is experimental, " - "add '-strict %d' if you want to use it.\n", - FF_COMPLIANCE_EXPERIMENTAL); - return AVERROR(EINVAL); - } - - ffio_wfourcc(pb, "MMMD"); - avio_wb32(pb, 0); - pos = ff_start_tag(pb, "CNTI"); - avio_w8(pb, 0); /* class */ - avio_w8(pb, 1); /* type */ - avio_w8(pb, 1); /* code type */ - avio_w8(pb, 0); /* status */ - avio_w8(pb, 0); /* counts */ - end_tag_be(pb, pos); - pos = ff_start_tag(pb, "OPDA"); - avio_write(pb, version, strlen(version)); /* metadata ("ST:songtitle,VN:version,...") */ - end_tag_be(pb, pos); - - avio_write(pb, "ATR\x00", 4); - avio_wb32(pb, 0); - mmf->atrpos = avio_tell(pb); - avio_w8(pb, 0); /* format type */ - avio_w8(pb, 0); /* sequence type */ - avio_w8(pb, (mmf->stereo << 7) | (1 << 4) | rate); /* (channel << 7) | (format << 4) | rate */ - avio_w8(pb, 0); /* wave base bit */ - avio_w8(pb, 2); /* time base d */ - avio_w8(pb, 2); /* time base g */ - - ffio_wfourcc(pb, "Atsq"); - avio_wb32(pb, 16); - mmf->atsqpos = avio_tell(pb); - /* Will be filled on close */ - avio_write(pb, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 16); - - mmf->awapos = ff_start_tag(pb, "Awa\x01"); - - avpriv_set_pts_info(s->streams[0], 64, 1, s->streams[0]->codec->sample_rate); - - avio_flush(pb); - - return 0; -} - -/* Write a variable-length symbol */ -static void put_varlength(AVIOContext *pb, int val) -{ - if(val < 128) - avio_w8(pb, val); - else { - val -= 128; - avio_w8(pb, 0x80 | val >> 7); - avio_w8(pb, 0x7f & val); - } -} - -static int mmf_write_trailer(AVFormatContext *s) -{ - AVIOContext *pb = s->pb; - MMFContext *mmf = s->priv_data; - int64_t pos, size; - int gatetime; - - if (s->pb->seekable) { - /* Fill in length fields */ - end_tag_be(pb, mmf->awapos); - end_tag_be(pb, mmf->atrpos); - end_tag_be(pb, 8); - - pos = avio_tell(pb); - size = pos - mmf->awapos; - - /* Fill Atsq chunk */ - avio_seek(pb, mmf->atsqpos, SEEK_SET); - - /* "play wav" */ - avio_w8(pb, 0); /* start time */ - avio_w8(pb, (mmf->stereo << 6) | 1); /* (channel << 6) | wavenum */ - gatetime = size * 500 / s->streams[0]->codec->sample_rate; - put_varlength(pb, gatetime); /* duration */ - - /* "nop" */ - put_varlength(pb, gatetime); /* start time */ - avio_write(pb, "\xff\x00", 2); /* nop */ - - /* "end of sequence" */ - avio_write(pb, "\x00\x00\x00\x00", 4); - - avio_seek(pb, pos, SEEK_SET); - - avio_flush(pb); - } - return 0; -} -#endif /* CONFIG_MMF_MUXER */ - -static int mmf_probe(AVProbeData *p) -{ - /* check file header */ - if (p->buf[0] == 'M' && p->buf[1] == 'M' && - p->buf[2] == 'M' && p->buf[3] == 'D' && - p->buf[8] == 'C' && p->buf[9] == 'N' && - p->buf[10] == 'T' && p->buf[11] == 'I') - return AVPROBE_SCORE_MAX; - else - return 0; -} - -/* mmf input */ -static int mmf_read_header(AVFormatContext *s) -{ - MMFContext *mmf = s->priv_data; - unsigned int tag; - AVIOContext *pb = s->pb; - AVStream *st; - int64_t size; - int rate, params; - - tag = avio_rl32(pb); - if (tag != MKTAG('M', 'M', 'M', 'D')) - return AVERROR_INVALIDDATA; - avio_skip(pb, 4); /* file_size */ - - /* Skip some unused chunks that may or may not be present */ - for(;; avio_skip(pb, size)) { - tag = avio_rl32(pb); - size = avio_rb32(pb); - if(tag == MKTAG('C','N','T','I')) continue; - if(tag == MKTAG('O','P','D','A')) continue; - break; - } - - /* Tag = "ATRx", where "x" = track number */ - if ((tag & 0xffffff) == MKTAG('M', 'T', 'R', 0)) { - av_log(s, AV_LOG_ERROR, "MIDI like format found, unsupported\n"); - return AVERROR_PATCHWELCOME; - } - if ((tag & 0xffffff) != MKTAG('A', 'T', 'R', 0)) { - av_log(s, AV_LOG_ERROR, "Unsupported SMAF chunk %08x\n", tag); - return AVERROR_PATCHWELCOME; - } - - avio_r8(pb); /* format type */ - avio_r8(pb); /* sequence type */ - params = avio_r8(pb); /* (channel << 7) | (format << 4) | rate */ - rate = mmf_rate(params & 0x0f); - if(rate < 0) { - av_log(s, AV_LOG_ERROR, "Invalid sample rate\n"); - return AVERROR_INVALIDDATA; - } - avio_r8(pb); /* wave base bit */ - avio_r8(pb); /* time base d */ - avio_r8(pb); /* time base g */ - - /* Skip some unused chunks that may or may not be present */ - for(;; avio_skip(pb, size)) { - tag = avio_rl32(pb); - size = avio_rb32(pb); - if(tag == MKTAG('A','t','s','q')) continue; - if(tag == MKTAG('A','s','p','I')) continue; - break; - } - - /* Make sure it's followed by an Awa chunk, aka wave data */ - if ((tag & 0xffffff) != MKTAG('A', 'w', 'a', 0)) { - av_log(s, AV_LOG_ERROR, "Unexpected SMAF chunk %08x\n", tag); - return AVERROR_INVALIDDATA; - } - mmf->data_end = avio_tell(pb) + size; - - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = AV_CODEC_ID_ADPCM_YAMAHA; - st->codec->sample_rate = rate; - st->codec->channels = (params >> 7) + 1; - st->codec->channel_layout = params >> 7 ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO; - st->codec->bits_per_coded_sample = 4; - st->codec->bit_rate = st->codec->sample_rate * st->codec->bits_per_coded_sample; - - avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); - - return 0; -} - -#define MAX_SIZE 4096 - -static int mmf_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - MMFContext *mmf = s->priv_data; - int64_t left, size; - int ret; - - left = mmf->data_end - avio_tell(s->pb); - size = FFMIN(left, MAX_SIZE); - if (url_feof(s->pb) || size <= 0) - return AVERROR_EOF; - - ret = av_get_packet(s->pb, pkt, size); - if (ret < 0) - return ret; - - pkt->stream_index = 0; - - return ret; -} - -#if CONFIG_MMF_DEMUXER -AVInputFormat ff_mmf_demuxer = { - .name = "mmf", - .long_name = NULL_IF_CONFIG_SMALL("Yamaha SMAF"), - .priv_data_size = sizeof(MMFContext), - .read_probe = mmf_probe, - .read_header = mmf_read_header, - .read_packet = mmf_read_packet, - .flags = AVFMT_GENERIC_INDEX, -}; -#endif -#if CONFIG_MMF_MUXER -AVOutputFormat ff_mmf_muxer = { - .name = "mmf", - .long_name = NULL_IF_CONFIG_SMALL("Yamaha SMAF"), - .mime_type = "application/vnd.smaf", - .extensions = "mmf", - .priv_data_size = sizeof(MMFContext), - .audio_codec = AV_CODEC_ID_ADPCM_YAMAHA, - .video_codec = AV_CODEC_ID_NONE, - .write_header = mmf_write_header, - .write_packet = ff_raw_write_packet, - .write_trailer = mmf_write_trailer, -}; -#endif diff --git a/ffmpeg1/libavformat/mms.c b/ffmpeg1/libavformat/mms.c deleted file mode 100644 index 46fbede..0000000 --- a/ffmpeg1/libavformat/mms.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - * MMS protocol common definitions. - * Copyright (c) 2006,2007 Ryan Martell - * Copyright (c) 2007 Björn Axelsson - * Copyright (c) 2010 Zhentan Feng - * - * 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 "mms.h" -#include "asf.h" -#include "libavutil/intreadwrite.h" - -#define MMS_MAX_STREAMS 256 /**< arbitrary sanity check value */ - -int ff_mms_read_header(MMSContext *mms, uint8_t *buf, const int size) -{ - char *pos; - int size_to_copy; - int remaining_size = mms->asf_header_size - mms->asf_header_read_size; - size_to_copy = FFMIN(size, remaining_size); - pos = mms->asf_header + mms->asf_header_read_size; - memcpy(buf, pos, size_to_copy); - if (mms->asf_header_read_size == mms->asf_header_size) { - av_freep(&mms->asf_header); // which contains asf header - } - mms->asf_header_read_size += size_to_copy; - return size_to_copy; -} - -int ff_mms_read_data(MMSContext *mms, uint8_t *buf, const int size) -{ - int read_size; - read_size = FFMIN(size, mms->remaining_in_len); - memcpy(buf, mms->read_in_ptr, read_size); - mms->remaining_in_len -= read_size; - mms->read_in_ptr += read_size; - return read_size; -} - -int ff_mms_asf_header_parser(MMSContext *mms) -{ - uint8_t *p = mms->asf_header; - uint8_t *end; - int flags, stream_id; - mms->stream_num = 0; - - if (mms->asf_header_size < sizeof(ff_asf_guid) * 2 + 22 || - memcmp(p, ff_asf_header, sizeof(ff_asf_guid))) { - av_log(NULL, AV_LOG_ERROR, - "Corrupt stream (invalid ASF header, size=%d)\n", - mms->asf_header_size); - return AVERROR_INVALIDDATA; - } - - end = mms->asf_header + mms->asf_header_size; - - p += sizeof(ff_asf_guid) + 14; - while(end - p >= sizeof(ff_asf_guid) + 8) { - uint64_t chunksize; - if (!memcmp(p, ff_asf_data_header, sizeof(ff_asf_guid))) { - chunksize = 50; // see Reference [2] section 5.1 - } else { - chunksize = AV_RL64(p + sizeof(ff_asf_guid)); - } - if (!chunksize || chunksize > end - p) { - av_log(NULL, AV_LOG_ERROR, - "Corrupt stream (header chunksize %"PRId64" is invalid)\n", - chunksize); - return AVERROR_INVALIDDATA; - } - if (!memcmp(p, ff_asf_file_header, sizeof(ff_asf_guid))) { - /* read packet size */ - if (end - p > sizeof(ff_asf_guid) * 2 + 68) { - mms->asf_packet_len = AV_RL32(p + sizeof(ff_asf_guid) * 2 + 64); - if (mms->asf_packet_len <= 0 || mms->asf_packet_len > sizeof(mms->in_buffer)) { - av_log(NULL, AV_LOG_ERROR, - "Corrupt stream (too large pkt_len %d)\n", - mms->asf_packet_len); - return AVERROR_INVALIDDATA; - } - } - } else if (!memcmp(p, ff_asf_stream_header, sizeof(ff_asf_guid))) { - flags = AV_RL16(p + sizeof(ff_asf_guid)*3 + 24); - stream_id = flags & 0x7F; - //The second condition is for checking CS_PKT_STREAM_ID_REQUEST packet size, - //we can calcuate the packet size by stream_num. - //Please see function send_stream_selection_request(). - if (mms->stream_num < MMS_MAX_STREAMS && - 46 + mms->stream_num * 6 < sizeof(mms->out_buffer)) { - mms->streams = av_fast_realloc(mms->streams, - &mms->nb_streams_allocated, - (mms->stream_num + 1) * sizeof(MMSStream)); - mms->streams[mms->stream_num].id = stream_id; - mms->stream_num++; - } else { - av_log(NULL, AV_LOG_ERROR, - "Corrupt stream (too many A/V streams)\n"); - return AVERROR_INVALIDDATA; - } - } else if (!memcmp(p, ff_asf_ext_stream_header, sizeof(ff_asf_guid))) { - if (end - p >= 88) { - int stream_count = AV_RL16(p + 84), ext_len_count = AV_RL16(p + 86); - uint64_t skip_bytes = 88; - while (stream_count--) { - if (end - p < skip_bytes + 4) { - av_log(NULL, AV_LOG_ERROR, - "Corrupt stream (next stream name length is not in the buffer)\n"); - return AVERROR_INVALIDDATA; - } - skip_bytes += 4 + AV_RL16(p + skip_bytes + 2); - } - while (ext_len_count--) { - if (end - p < skip_bytes + 22) { - av_log(NULL, AV_LOG_ERROR, - "Corrupt stream (next extension system info length is not in the buffer)\n"); - return AVERROR_INVALIDDATA; - } - skip_bytes += 22 + AV_RL32(p + skip_bytes + 18); - } - if (end - p < skip_bytes) { - av_log(NULL, AV_LOG_ERROR, - "Corrupt stream (the last extension system info length is invalid)\n"); - return AVERROR_INVALIDDATA; - } - if (chunksize - skip_bytes > 24) - chunksize = skip_bytes; - } - } else if (!memcmp(p, ff_asf_head1_guid, sizeof(ff_asf_guid))) { - chunksize = 46; // see references [2] section 3.4. This should be set 46. - } - p += chunksize; - } - - return 0; -} diff --git a/ffmpeg1/libavformat/mms.h b/ffmpeg1/libavformat/mms.h deleted file mode 100644 index 57e3d7e..0000000 --- a/ffmpeg1/libavformat/mms.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * MMS protocol common definitions. - * Copyright (c) 2010 Zhentan Feng - * - * 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 AVFORMAT_MMS_H -#define AVFORMAT_MMS_H - -#include "url.h" - -typedef struct MMSStream { - int id; -}MMSStream; - -typedef struct MMSContext { - URLContext *mms_hd; ///< TCP connection handle - MMSStream *streams; - - /** Buffer for outgoing packets. */ - /*@{*/ - uint8_t *write_out_ptr; ///< Pointer for writing the buffer. - uint8_t out_buffer[512]; ///< Buffer for outgoing packet. - /*@}*/ - - /** Buffer for incoming packets. */ - /*@{*/ - uint8_t in_buffer[65536]; ///< Buffer for incoming packets. - uint8_t *read_in_ptr; ///< Pointer for reading from incoming buffer. - int remaining_in_len; ///< Reading length from incoming buffer. - /*@}*/ - - /** Internal handling of the ASF header */ - /*@{*/ - uint8_t *asf_header; ///< Stored ASF header. - int asf_header_size; ///< Size of stored ASF header. - int header_parsed; ///< The header has been received and parsed. - int asf_packet_len; - int asf_header_read_size; - /*@}*/ - - int stream_num; ///< stream numbers. - unsigned int nb_streams_allocated; ///< allocated size of streams -} MMSContext; - -int ff_mms_asf_header_parser(MMSContext * mms); -int ff_mms_read_data(MMSContext *mms, uint8_t *buf, const int size); -int ff_mms_read_header(MMSContext * mms, uint8_t * buf, const int size); - -#endif /* AVFORMAT_MMS_H */ diff --git a/ffmpeg1/libavformat/mmsh.c b/ffmpeg1/libavformat/mmsh.c deleted file mode 100644 index 86a0575..0000000 --- a/ffmpeg1/libavformat/mmsh.c +++ /dev/null @@ -1,410 +0,0 @@ -/* - * MMS protocol over HTTP - * Copyright (c) 2010 Zhentan Feng - * - * 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 - */ - -/* - * Reference - * Windows Media HTTP Streaming Protocol. - * http://msdn.microsoft.com/en-us/library/cc251059(PROT.10).aspx - */ - -#include -#include "libavutil/intreadwrite.h" -#include "libavutil/avstring.h" -#include "libavutil/opt.h" -#include "internal.h" -#include "mms.h" -#include "asf.h" -#include "http.h" -#include "url.h" - -#define CHUNK_HEADER_LENGTH 4 // 2bytes chunk type and 2bytes chunk length. -#define EXT_HEADER_LENGTH 8 // 4bytes sequence, 2bytes useless and 2bytes chunk length. - -// see Ref 2.2.1.8 -#define USERAGENT "User-Agent: NSPlayer/4.1.0.3856\r\n" -// see Ref 2.2.1.4.33 -// the guid value can be changed to any valid value. -#define CLIENTGUID "Pragma: xClientGUID={c77e7400-738a-11d2-9add-0020af0a3278}\r\n" - -// see Ref 2.2.3 for packet type define: -// chunk type contains 2 fields: Frame and PacketID. -// Frame is 0x24 or 0xA4(rarely), different PacketID indicates different packet type. -typedef enum { - CHUNK_TYPE_DATA = 0x4424, - CHUNK_TYPE_ASF_HEADER = 0x4824, - CHUNK_TYPE_END = 0x4524, - CHUNK_TYPE_STREAM_CHANGE = 0x4324, -} ChunkType; - -typedef struct { - MMSContext mms; - uint8_t location[1024]; - int request_seq; ///< request packet sequence - int chunk_seq; ///< data packet sequence -} MMSHContext; - -static int mmsh_close(URLContext *h) -{ - MMSHContext *mmsh = (MMSHContext *)h->priv_data; - MMSContext *mms = &mmsh->mms; - if (mms->mms_hd) - ffurl_close(mms->mms_hd); - av_free(mms->streams); - av_free(mms->asf_header); - return 0; -} - -static ChunkType get_chunk_header(MMSHContext *mmsh, int *len) -{ - MMSContext *mms = &mmsh->mms; - uint8_t chunk_header[CHUNK_HEADER_LENGTH]; - uint8_t ext_header[EXT_HEADER_LENGTH]; - ChunkType chunk_type; - int chunk_len, res, ext_header_len; - - res = ffurl_read_complete(mms->mms_hd, chunk_header, CHUNK_HEADER_LENGTH); - if (res != CHUNK_HEADER_LENGTH) { - av_log(NULL, AV_LOG_ERROR, "Read data packet header failed!\n"); - return AVERROR(EIO); - } - chunk_type = AV_RL16(chunk_header); - chunk_len = AV_RL16(chunk_header + 2); - - switch (chunk_type) { - case CHUNK_TYPE_END: - case CHUNK_TYPE_STREAM_CHANGE: - ext_header_len = 4; - break; - case CHUNK_TYPE_ASF_HEADER: - case CHUNK_TYPE_DATA: - ext_header_len = 8; - break; - default: - av_log(NULL, AV_LOG_ERROR, "Strange chunk type %d\n", chunk_type); - return AVERROR_INVALIDDATA; - } - - res = ffurl_read_complete(mms->mms_hd, ext_header, ext_header_len); - if (res != ext_header_len) { - av_log(NULL, AV_LOG_ERROR, "Read ext header failed!\n"); - return AVERROR(EIO); - } - *len = chunk_len - ext_header_len; - if (chunk_type == CHUNK_TYPE_END || chunk_type == CHUNK_TYPE_DATA) - mmsh->chunk_seq = AV_RL32(ext_header); - return chunk_type; -} - -static int read_data_packet(MMSHContext *mmsh, const int len) -{ - MMSContext *mms = &mmsh->mms; - int res; - if (len > sizeof(mms->in_buffer)) { - av_log(NULL, AV_LOG_ERROR, - "Data packet length %d exceeds the in_buffer size %zu\n", - len, sizeof(mms->in_buffer)); - return AVERROR(EIO); - } - res = ffurl_read_complete(mms->mms_hd, mms->in_buffer, len); - av_dlog(NULL, "Data packet len = %d\n", len); - if (res != len) { - av_log(NULL, AV_LOG_ERROR, "Read data packet failed!\n"); - return AVERROR(EIO); - } - if (len > mms->asf_packet_len) { - av_log(NULL, AV_LOG_ERROR, - "Chunk length %d exceed packet length %d\n",len, mms->asf_packet_len); - return AVERROR_INVALIDDATA; - } else { - memset(mms->in_buffer + len, 0, mms->asf_packet_len - len); // padding - } - mms->read_in_ptr = mms->in_buffer; - mms->remaining_in_len = mms->asf_packet_len; - return 0; -} - -static int get_http_header_data(MMSHContext *mmsh) -{ - MMSContext *mms = &mmsh->mms; - int res, len; - ChunkType chunk_type; - - for (;;) { - len = 0; - res = chunk_type = get_chunk_header(mmsh, &len); - if (res < 0) { - return res; - } else if (chunk_type == CHUNK_TYPE_ASF_HEADER){ - // get asf header and stored it - if (!mms->header_parsed) { - if (mms->asf_header) { - if (len != mms->asf_header_size) { - mms->asf_header_size = len; - av_dlog(NULL, "Header len changed from %d to %d\n", - mms->asf_header_size, len); - av_freep(&mms->asf_header); - } - } - mms->asf_header = av_mallocz(len); - if (!mms->asf_header) { - return AVERROR(ENOMEM); - } - mms->asf_header_size = len; - } - if (len > mms->asf_header_size) { - av_log(NULL, AV_LOG_ERROR, - "Asf header packet len = %d exceed the asf header buf size %d\n", - len, mms->asf_header_size); - return AVERROR(EIO); - } - res = ffurl_read_complete(mms->mms_hd, mms->asf_header, len); - if (res != len) { - av_log(NULL, AV_LOG_ERROR, - "Recv asf header data len %d != expected len %d\n", res, len); - return AVERROR(EIO); - } - mms->asf_header_size = len; - if (!mms->header_parsed) { - res = ff_mms_asf_header_parser(mms); - mms->header_parsed = 1; - return res; - } - } else if (chunk_type == CHUNK_TYPE_DATA) { - // read data packet and do padding - return read_data_packet(mmsh, len); - } else { - if (len) { - if (len > sizeof(mms->in_buffer)) { - av_log(NULL, AV_LOG_ERROR, - "Other packet len = %d exceed the in_buffer size %zu\n", - len, sizeof(mms->in_buffer)); - return AVERROR(EIO); - } - res = ffurl_read_complete(mms->mms_hd, mms->in_buffer, len); - if (res != len) { - av_log(NULL, AV_LOG_ERROR, "Read other chunk type data failed!\n"); - return AVERROR(EIO); - } else { - av_dlog(NULL, "Skip chunk type %d \n", chunk_type); - continue; - } - } - } - } -} - -static int mmsh_open_internal(URLContext *h, const char *uri, int flags, int timestamp, int64_t pos) -{ - int i, port, err; - char httpname[256], path[256], host[128]; - char *stream_selection = NULL; - char headers[1024]; - MMSHContext *mmsh = h->priv_data; - MMSContext *mms; - - mmsh->request_seq = h->is_streamed = 1; - mms = &mmsh->mms; - av_strlcpy(mmsh->location, uri, sizeof(mmsh->location)); - - av_url_split(NULL, 0, NULL, 0, - host, sizeof(host), &port, path, sizeof(path), mmsh->location); - if (port<0) - port = 80; // default mmsh protocol port - ff_url_join(httpname, sizeof(httpname), "http", NULL, host, port, "%s", path); - - if (ffurl_alloc(&mms->mms_hd, httpname, AVIO_FLAG_READ, - &h->interrupt_callback) < 0) { - return AVERROR(EIO); - } - - snprintf(headers, sizeof(headers), - "Accept: */*\r\n" - USERAGENT - "Host: %s:%d\r\n" - "Pragma: no-cache,rate=1.000000,stream-time=0," - "stream-offset=0:0,request-context=%u,max-duration=0\r\n" - CLIENTGUID - "Connection: Close\r\n", - host, port, mmsh->request_seq++); - av_opt_set(mms->mms_hd->priv_data, "headers", headers, 0); - - err = ffurl_connect(mms->mms_hd, NULL); - if (err) { - goto fail; - } - err = get_http_header_data(mmsh); - if (err) { - av_log(NULL, AV_LOG_ERROR, "Get http header data failed!\n"); - goto fail; - } - - // close the socket and then reopen it for sending the second play request. - ffurl_close(mms->mms_hd); - memset(headers, 0, sizeof(headers)); - if ((err = ffurl_alloc(&mms->mms_hd, httpname, AVIO_FLAG_READ, - &h->interrupt_callback)) < 0) { - goto fail; - } - stream_selection = av_mallocz(mms->stream_num * 19 + 1); - if (!stream_selection) - return AVERROR(ENOMEM); - for (i = 0; i < mms->stream_num; i++) { - char tmp[20]; - err = snprintf(tmp, sizeof(tmp), "ffff:%d:0 ", mms->streams[i].id); - if (err < 0) - goto fail; - av_strlcat(stream_selection, tmp, mms->stream_num * 19 + 1); - } - // send play request - err = snprintf(headers, sizeof(headers), - "Accept: */*\r\n" - USERAGENT - "Host: %s:%d\r\n" - "Pragma: no-cache,rate=1.000000,request-context=%u\r\n" - "Pragma: xPlayStrm=1\r\n" - CLIENTGUID - "Pragma: stream-switch-count=%d\r\n" - "Pragma: stream-switch-entry=%s\r\n" - "Pragma: no-cache,rate=1.000000,stream-time=%u" - "Connection: Close\r\n", - host, port, mmsh->request_seq++, mms->stream_num, stream_selection, timestamp); - av_freep(&stream_selection); - if (err < 0) { - av_log(NULL, AV_LOG_ERROR, "Build play request failed!\n"); - goto fail; - } - av_dlog(NULL, "out_buffer is %s", headers); - av_opt_set(mms->mms_hd->priv_data, "headers", headers, 0); - - err = ffurl_connect(mms->mms_hd, NULL); - if (err) { - goto fail; - } - - err = get_http_header_data(mmsh); - if (err) { - av_log(NULL, AV_LOG_ERROR, "Get http header data failed!\n"); - goto fail; - } - - av_dlog(NULL, "Connection successfully open\n"); - return 0; -fail: - av_freep(&stream_selection); - mmsh_close(h); - av_dlog(NULL, "Connection failed with error %d\n", err); - return err; -} - -static int mmsh_open(URLContext *h, const char *uri, int flags) -{ - return mmsh_open_internal(h, uri, flags, 0, 0); -} - -static int handle_chunk_type(MMSHContext *mmsh) -{ - MMSContext *mms = &mmsh->mms; - int res, len = 0; - ChunkType chunk_type; - chunk_type = get_chunk_header(mmsh, &len); - - switch (chunk_type) { - case CHUNK_TYPE_END: - mmsh->chunk_seq = 0; - av_log(NULL, AV_LOG_ERROR, "Stream ended!\n"); - return AVERROR(EIO); - case CHUNK_TYPE_STREAM_CHANGE: - mms->header_parsed = 0; - if (res = get_http_header_data(mmsh)) { - av_log(NULL, AV_LOG_ERROR,"Stream changed! Failed to get new header!\n"); - return res; - } - break; - case CHUNK_TYPE_DATA: - return read_data_packet(mmsh, len); - default: - av_log(NULL, AV_LOG_ERROR, "Recv other type packet %d\n", chunk_type); - return AVERROR_INVALIDDATA; - } - return 0; -} - -static int mmsh_read(URLContext *h, uint8_t *buf, int size) -{ - int res = 0; - MMSHContext *mmsh = h->priv_data; - MMSContext *mms = &mmsh->mms; - do { - if (mms->asf_header_read_size < mms->asf_header_size) { - // copy asf header into buffer - res = ff_mms_read_header(mms, buf, size); - } else { - if (!mms->remaining_in_len && (res = handle_chunk_type(mmsh))) - return res; - res = ff_mms_read_data(mms, buf, size); - } - } while (!res); - return res; -} - -static int64_t mmsh_read_seek(URLContext *h, int stream_index, - int64_t timestamp, int flags) -{ - MMSHContext *mmsh = h->priv_data; - MMSContext *mms = &mmsh->mms; - int ret; - - ret= mmsh_open_internal(h, mmsh->location, 0, FFMAX(timestamp, 0), 0); - - if(ret>=0){ - if (mms->mms_hd) - ffurl_close(mms->mms_hd); - av_freep(&mms->streams); - av_freep(&mms->asf_header); - av_free(mmsh); - mmsh = h->priv_data; - mms = &mmsh->mms; - mms->asf_header_read_size= mms->asf_header_size; - }else - h->priv_data= mmsh; - return ret; -} - -static int64_t mmsh_seek(URLContext *h, int64_t pos, int whence) -{ - MMSHContext *mmsh = h->priv_data; - MMSContext *mms = &mmsh->mms; - - if(pos == 0 && whence == SEEK_CUR) - return mms->asf_header_read_size + mms->remaining_in_len + mmsh->chunk_seq * (int64_t)mms->asf_packet_len; - return AVERROR(ENOSYS); -} - -URLProtocol ff_mmsh_protocol = { - .name = "mmsh", - .url_open = mmsh_open, - .url_read = mmsh_read, - .url_seek = mmsh_seek, - .url_close = mmsh_close, - .url_read_seek = mmsh_read_seek, - .priv_data_size = sizeof(MMSHContext), - .flags = URL_PROTOCOL_FLAG_NETWORK, -}; diff --git a/ffmpeg1/libavformat/mmst.c b/ffmpeg1/libavformat/mmst.c deleted file mode 100644 index c3d2ebb..0000000 --- a/ffmpeg1/libavformat/mmst.c +++ /dev/null @@ -1,629 +0,0 @@ -/* - * MMS protocol over TCP - * Copyright (c) 2006,2007 Ryan Martell - * Copyright (c) 2007 Björn Axelsson - * Copyright (c) 2010 Zhentan Feng - * - * 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 - */ - -/* References - * MMS protocol specification: - * [1]http://msdn.microsoft.com/en-us/library/cc234711(PROT.10).aspx - * ASF specification. Revision 01.20.03. - * [2]http://msdn.microsoft.com/en-us/library/bb643323.aspx - */ - -#include "avformat.h" -#include "mms.h" -#include "internal.h" -#include "avio_internal.h" -#include "libavutil/intreadwrite.h" -#include "libavcodec/bytestream.h" -#include "network.h" -#include "url.h" - -#define LOCAL_ADDRESS 0xc0a80081 // FIXME get and use correct local ip address. -#define LOCAL_PORT 1037 // as above. -/** Client to server packet types. */ -typedef enum { - CS_PKT_INITIAL = 0x01, - CS_PKT_PROTOCOL_SELECT = 0x02, - CS_PKT_MEDIA_FILE_REQUEST = 0x05, - CS_PKT_START_FROM_PKT_ID = 0x07, - CS_PKT_STREAM_PAUSE = 0x09, - CS_PKT_STREAM_CLOSE = 0x0d, - CS_PKT_MEDIA_HEADER_REQUEST = 0x15, - CS_PKT_TIMING_DATA_REQUEST = 0x18, - CS_PKT_USER_PASSWORD = 0x1a, - CS_PKT_KEEPALIVE = 0x1b, - CS_PKT_STREAM_ID_REQUEST = 0x33, -} MMSCSPacketType; - -/** Server to client packet types. */ -typedef enum { - /** Control packets. */ - /*@{*/ - SC_PKT_CLIENT_ACCEPTED = 0x01, - SC_PKT_PROTOCOL_ACCEPTED = 0x02, - SC_PKT_PROTOCOL_FAILED = 0x03, - SC_PKT_MEDIA_PKT_FOLLOWS = 0x05, - SC_PKT_MEDIA_FILE_DETAILS = 0x06, - SC_PKT_HEADER_REQUEST_ACCEPTED = 0x11, - SC_PKT_TIMING_TEST_REPLY = 0x15, - SC_PKT_PASSWORD_REQUIRED = 0x1a, - SC_PKT_KEEPALIVE = 0x1b, - SC_PKT_STREAM_STOPPED = 0x1e, - SC_PKT_STREAM_CHANGING = 0x20, - SC_PKT_STREAM_ID_ACCEPTED = 0x21, - /*@}*/ - - /** Pseudo packets. */ - /*@{*/ - SC_PKT_CANCEL = -1, - SC_PKT_NO_DATA = -2, - /*@}*/ - - /** Data packets. */ - /*@{*/ - SC_PKT_ASF_HEADER = 0x010000,// make it bigger than 0xFF in case of - SC_PKT_ASF_MEDIA = 0x010001,// receiving false data packets. - /*@}*/ -} MMSSCPacketType; - -typedef struct { - MMSContext mms; - int outgoing_packet_seq; ///< Outgoing packet sequence number. - char path[256]; ///< Path of the resource being asked for. - char host[128]; ///< Host of the resources. - int incoming_packet_seq; ///< Incoming packet sequence number. - int incoming_flags; ///< Incoming packet flags. - int packet_id; ///< Identifier for packets in the current stream. - unsigned int header_packet_id; ///< default is 2. -} MMSTContext; - -/** Create MMST command packet header */ -static void start_command_packet(MMSTContext *mmst, MMSCSPacketType packet_type) -{ - MMSContext *mms = &mmst->mms; - mms->write_out_ptr = mms->out_buffer; - - bytestream_put_le32(&mms->write_out_ptr, 1); // start sequence - bytestream_put_le32(&mms->write_out_ptr, 0xb00bface); - bytestream_put_le32(&mms->write_out_ptr, 0); // Length starts from after the protocol type bytes - bytestream_put_le32(&mms->write_out_ptr, MKTAG('M','M','S',' ')); - bytestream_put_le32(&mms->write_out_ptr, 0); - bytestream_put_le32(&mms->write_out_ptr, mmst->outgoing_packet_seq++); - bytestream_put_le64(&mms->write_out_ptr, 0); // timestamp - bytestream_put_le32(&mms->write_out_ptr, 0); - bytestream_put_le16(&mms->write_out_ptr, packet_type); - bytestream_put_le16(&mms->write_out_ptr, 3); // direction to server -} - -/** Add prefixes to MMST command packet. */ -static void insert_command_prefixes(MMSContext *mms, - uint32_t prefix1, uint32_t prefix2) -{ - bytestream_put_le32(&mms->write_out_ptr, prefix1); // first prefix - bytestream_put_le32(&mms->write_out_ptr, prefix2); // second prefix -} - -/** Send a prepared MMST command packet. */ -static int send_command_packet(MMSTContext *mmst) -{ - MMSContext *mms = &mmst->mms; - int len= mms->write_out_ptr - mms->out_buffer; - int exact_length = FFALIGN(len, 8); - int first_length= exact_length - 16; - int len8= first_length/8; - int write_result; - - // update packet length fields. - AV_WL32(mms->out_buffer + 8, first_length); - AV_WL32(mms->out_buffer + 16, len8); - AV_WL32(mms->out_buffer + 32, len8-2); - memset(mms->write_out_ptr, 0, exact_length - len); - - // write it out. - write_result= ffurl_write(mms->mms_hd, mms->out_buffer, exact_length); - if(write_result != exact_length) { - av_log(NULL, AV_LOG_ERROR, - "Failed to write data of length %d: %d (%s)\n", - exact_length, write_result, - write_result < 0 ? strerror(AVUNERROR(write_result)) : - "The server closed the connection"); - return AVERROR(EIO); - } - - return 0; -} - -static void mms_put_utf16(MMSContext *mms, const uint8_t *src) -{ - AVIOContext bic; - int size = mms->write_out_ptr - mms->out_buffer; - int len; - ffio_init_context(&bic, mms->write_out_ptr, - sizeof(mms->out_buffer) - size, 1, NULL, NULL, NULL, NULL); - - len = avio_put_str16le(&bic, src); - mms->write_out_ptr += len; -} - -static int send_time_test_data(MMSTContext *mmst) -{ - start_command_packet(mmst, CS_PKT_TIMING_DATA_REQUEST); - insert_command_prefixes(&mmst->mms, 0x00f0f0f0, 0x0004000b); - return send_command_packet(mmst); -} - -static int send_protocol_select(MMSTContext *mmst) -{ - char data_string[256]; - MMSContext *mms = &mmst->mms; - - start_command_packet(mmst, CS_PKT_PROTOCOL_SELECT); - insert_command_prefixes(mms, 0, 0xffffffff); - bytestream_put_le32(&mms->write_out_ptr, 0); // maxFunnelBytes - bytestream_put_le32(&mms->write_out_ptr, 0x00989680); // maxbitRate - bytestream_put_le32(&mms->write_out_ptr, 2); // funnelMode - snprintf(data_string, sizeof(data_string), "\\\\%d.%d.%d.%d\\%s\\%d", - (LOCAL_ADDRESS>>24)&0xff, - (LOCAL_ADDRESS>>16)&0xff, - (LOCAL_ADDRESS>>8)&0xff, - LOCAL_ADDRESS&0xff, - "TCP", // or UDP - LOCAL_PORT); - - mms_put_utf16(mms, data_string); - return send_command_packet(mmst); -} - -static int send_media_file_request(MMSTContext *mmst) -{ - MMSContext *mms = &mmst->mms; - start_command_packet(mmst, CS_PKT_MEDIA_FILE_REQUEST); - insert_command_prefixes(mms, 1, 0xffffffff); - bytestream_put_le32(&mms->write_out_ptr, 0); - bytestream_put_le32(&mms->write_out_ptr, 0); - mms_put_utf16(mms, mmst->path + 1); // +1 for skip "/" - - return send_command_packet(mmst); -} - -static void handle_packet_stream_changing_type(MMSTContext *mmst) -{ - MMSContext *mms = &mmst->mms; - av_dlog(NULL, "Stream changing!\n"); - - // 40 is the packet header size, 7 is the prefix size. - mmst->header_packet_id= AV_RL32(mms->in_buffer + 40 + 7); - av_dlog(NULL, "Changed header prefix to 0x%x", mmst->header_packet_id); -} - -static int send_keepalive_packet(MMSTContext *mmst) -{ - // respond to a keepalive with a keepalive... - start_command_packet(mmst, CS_PKT_KEEPALIVE); - insert_command_prefixes(&mmst->mms, 1, 0x100FFFF); - return send_command_packet(mmst); -} - -/** Pad media packets smaller than max_packet_size and/or adjust read position - * after a seek. */ -static void pad_media_packet(MMSContext *mms) -{ - if(mms->remaining_in_lenasf_packet_len) { - int padding_size = mms->asf_packet_len - mms->remaining_in_len; - memset(mms->in_buffer + mms->remaining_in_len, 0, padding_size); - mms->remaining_in_len += padding_size; - } -} - -/** Read incoming MMST media, header or command packet. */ -static MMSSCPacketType get_tcp_server_response(MMSTContext *mmst) -{ - int read_result; - MMSSCPacketType packet_type= -1; - MMSContext *mms = &mmst->mms; - for(;;) { - read_result = ffurl_read_complete(mms->mms_hd, mms->in_buffer, 8); - if (read_result != 8) { - if(read_result < 0) { - av_log(NULL, AV_LOG_ERROR, - "Error reading packet header: %d (%s)\n", - read_result, strerror(AVUNERROR(read_result))); - packet_type = SC_PKT_CANCEL; - } else { - av_log(NULL, AV_LOG_ERROR, - "The server closed the connection\n"); - packet_type = SC_PKT_NO_DATA; - } - return packet_type; - } - - // handle command packet. - if(AV_RL32(mms->in_buffer + 4)==0xb00bface) { - int length_remaining, hr; - - mmst->incoming_flags= mms->in_buffer[3]; - read_result= ffurl_read_complete(mms->mms_hd, mms->in_buffer+8, 4); - if(read_result != 4) { - av_log(NULL, AV_LOG_ERROR, - "Reading command packet length failed: %d (%s)\n", - read_result, - read_result < 0 ? strerror(AVUNERROR(read_result)) : - "The server closed the connection"); - return read_result < 0 ? read_result : AVERROR(EIO); - } - - length_remaining= AV_RL32(mms->in_buffer+8) + 4; - av_dlog(NULL, "Length remaining is %d\n", length_remaining); - // read the rest of the packet. - if (length_remaining < 0 - || length_remaining > sizeof(mms->in_buffer) - 12) { - av_log(NULL, AV_LOG_ERROR, - "Incoming packet length %d exceeds bufsize %zu\n", - length_remaining, sizeof(mms->in_buffer) - 12); - return AVERROR_INVALIDDATA; - } - read_result = ffurl_read_complete(mms->mms_hd, mms->in_buffer + 12, - length_remaining) ; - if (read_result != length_remaining) { - av_log(NULL, AV_LOG_ERROR, - "Reading pkt data (length=%d) failed: %d (%s)\n", - length_remaining, read_result, - read_result < 0 ? strerror(AVUNERROR(read_result)) : - "The server closed the connection"); - return read_result < 0 ? read_result : AVERROR(EIO); - } - packet_type= AV_RL16(mms->in_buffer+36); - if (read_result >= 44 && (hr = AV_RL32(mms->in_buffer + 40))) { - av_log(NULL, AV_LOG_ERROR, - "Server sent a message with packet type 0x%x and error status code 0x%08x\n", packet_type, hr); - return AVERROR(EINVAL); - } - } else { - int length_remaining; - int packet_id_type; - int tmp; - - // note we cache the first 8 bytes, - // then fill up the buffer with the others - tmp = AV_RL16(mms->in_buffer + 6); - length_remaining = (tmp - 8) & 0xffff; - mmst->incoming_packet_seq = AV_RL32(mms->in_buffer); - packet_id_type = mms->in_buffer[4]; - mmst->incoming_flags = mms->in_buffer[5]; - - if (length_remaining < 0 - || length_remaining > sizeof(mms->in_buffer) - 8) { - av_log(NULL, AV_LOG_ERROR, - "Data length %d is invalid or too large (max=%zu)\n", - length_remaining, sizeof(mms->in_buffer)); - return AVERROR_INVALIDDATA; - } - mms->remaining_in_len = length_remaining; - mms->read_in_ptr = mms->in_buffer; - read_result= ffurl_read_complete(mms->mms_hd, mms->in_buffer, length_remaining); - if(read_result != length_remaining) { - av_log(NULL, AV_LOG_ERROR, - "Failed to read packet data of size %d: %d (%s)\n", - length_remaining, read_result, - read_result < 0 ? strerror(AVUNERROR(read_result)) : - "The server closed the connection"); - return read_result < 0 ? read_result : AVERROR(EIO); - } - - // if we successfully read everything. - if(packet_id_type == mmst->header_packet_id) { - packet_type = SC_PKT_ASF_HEADER; - // Store the asf header - if(!mms->header_parsed) { - void *p = av_realloc(mms->asf_header, - mms->asf_header_size + mms->remaining_in_len); - if (!p) { - av_freep(&mms->asf_header); - return AVERROR(ENOMEM); - } - mms->asf_header = p; - memcpy(mms->asf_header + mms->asf_header_size, - mms->read_in_ptr, mms->remaining_in_len); - mms->asf_header_size += mms->remaining_in_len; - } - // 0x04 means asf header is sent in multiple packets. - if (mmst->incoming_flags == 0x04) - continue; - } else if(packet_id_type == mmst->packet_id) { - packet_type = SC_PKT_ASF_MEDIA; - } else { - av_dlog(NULL, "packet id type %d is old.", packet_id_type); - continue; - } - } - - // preprocess some packet type - if(packet_type == SC_PKT_KEEPALIVE) { - send_keepalive_packet(mmst); - continue; - } else if(packet_type == SC_PKT_STREAM_CHANGING) { - handle_packet_stream_changing_type(mmst); - } else if(packet_type == SC_PKT_ASF_MEDIA) { - pad_media_packet(mms); - } - return packet_type; - } -} - -static int mms_safe_send_recv(MMSTContext *mmst, - int (*send_fun)(MMSTContext *mmst), - const MMSSCPacketType expect_type) -{ - MMSSCPacketType type; - if(send_fun) { - int ret = send_fun(mmst); - if (ret < 0) { - av_dlog(NULL, "Send Packet error before expecting recv packet %d\n", expect_type); - return ret; - } - } - - if ((type = get_tcp_server_response(mmst)) != expect_type) { - av_log(NULL, AV_LOG_ERROR, - "Corrupt stream (unexpected packet type 0x%x, expected 0x%x)\n", - type, expect_type); - return AVERROR_INVALIDDATA; - } else { - return 0; - } -} - -static int send_media_header_request(MMSTContext *mmst) -{ - MMSContext *mms = &mmst->mms; - start_command_packet(mmst, CS_PKT_MEDIA_HEADER_REQUEST); - insert_command_prefixes(mms, 1, 0); - bytestream_put_le32(&mms->write_out_ptr, 0); - bytestream_put_le32(&mms->write_out_ptr, 0x00800000); - bytestream_put_le32(&mms->write_out_ptr, 0xffffffff); - bytestream_put_le32(&mms->write_out_ptr, 0); - bytestream_put_le32(&mms->write_out_ptr, 0); - bytestream_put_le32(&mms->write_out_ptr, 0); - - // the media preroll value in milliseconds? - bytestream_put_le32(&mms->write_out_ptr, 0); - bytestream_put_le32(&mms->write_out_ptr, 0x40AC2000); - bytestream_put_le32(&mms->write_out_ptr, 2); - bytestream_put_le32(&mms->write_out_ptr, 0); - - return send_command_packet(mmst); -} - -/** Send the initial handshake. */ -static int send_startup_packet(MMSTContext *mmst) -{ - char data_string[256]; - MMSContext *mms = &mmst->mms; - // SubscriberName is defined in MS specification linked below. - // The guid value can be any valid value. - // http://download.microsoft.com/ - // download/9/5/E/95EF66AF-9026-4BB0-A41D-A4F81802D92C/%5BMS-WMSP%5D.pdf - snprintf(data_string, sizeof(data_string), - "NSPlayer/7.0.0.1956; {%s}; Host: %s", - "7E667F5D-A661-495E-A512-F55686DDA178", mmst->host); - - start_command_packet(mmst, CS_PKT_INITIAL); - insert_command_prefixes(mms, 0, 0x0004000b); - bytestream_put_le32(&mms->write_out_ptr, 0x0003001c); - mms_put_utf16(mms, data_string); - return send_command_packet(mmst); -} - -/** Send MMST stream selection command based on the AVStream->discard values. */ -static int send_stream_selection_request(MMSTContext *mmst) -{ - int i; - MMSContext *mms = &mmst->mms; - // send the streams we want back... - start_command_packet(mmst, CS_PKT_STREAM_ID_REQUEST); - bytestream_put_le32(&mms->write_out_ptr, mms->stream_num); // stream nums - for(i= 0; istream_num; i++) { - bytestream_put_le16(&mms->write_out_ptr, 0xffff); // flags - bytestream_put_le16(&mms->write_out_ptr, mms->streams[i].id); // stream id - bytestream_put_le16(&mms->write_out_ptr, 0); // selection - } - return send_command_packet(mmst); -} - -static int send_close_packet(MMSTContext *mmst) -{ - start_command_packet(mmst, CS_PKT_STREAM_CLOSE); - insert_command_prefixes(&mmst->mms, 1, 1); - - return send_command_packet(mmst); -} - -/** Close the MMSH/MMST connection */ -static int mms_close(URLContext *h) -{ - MMSTContext *mmst = (MMSTContext *)h->priv_data; - MMSContext *mms = &mmst->mms; - if(mms->mms_hd) { - send_close_packet(mmst); - ffurl_close(mms->mms_hd); - } - - /* free all separately allocated pointers in mms */ - av_free(mms->streams); - av_free(mms->asf_header); - - return 0; -} - -static int send_media_packet_request(MMSTContext *mmst) -{ - MMSContext *mms = &mmst->mms; - start_command_packet(mmst, CS_PKT_START_FROM_PKT_ID); - insert_command_prefixes(mms, 1, 0x0001FFFF); - bytestream_put_le64(&mms->write_out_ptr, 0); // seek timestamp - bytestream_put_le32(&mms->write_out_ptr, 0xffffffff); // unknown - bytestream_put_le32(&mms->write_out_ptr, 0xffffffff); // packet offset - bytestream_put_byte(&mms->write_out_ptr, 0xff); // max stream time limit - bytestream_put_byte(&mms->write_out_ptr, 0xff); // max stream time limit - bytestream_put_byte(&mms->write_out_ptr, 0xff); // max stream time limit - bytestream_put_byte(&mms->write_out_ptr, 0x00); // stream time limit flag - - mmst->packet_id++; // new packet_id - bytestream_put_le32(&mms->write_out_ptr, mmst->packet_id); - return send_command_packet(mmst); -} - - -static void clear_stream_buffers(MMSContext *mms) -{ - mms->remaining_in_len = 0; - mms->read_in_ptr = mms->in_buffer; -} - -static int mms_open(URLContext *h, const char *uri, int flags) -{ - MMSTContext *mmst = h->priv_data; - MMSContext *mms; - int port, err; - char tcpname[256]; - - h->is_streamed = 1; - mms = &mmst->mms; - - // only for MMS over TCP, so set proto = NULL - av_url_split(NULL, 0, NULL, 0, - mmst->host, sizeof(mmst->host), &port, mmst->path, - sizeof(mmst->path), uri); - - if(port<0) - port = 1755; // defaut mms protocol port - - // establish tcp connection. - ff_url_join(tcpname, sizeof(tcpname), "tcp", NULL, mmst->host, port, NULL); - err = ffurl_open(&mms->mms_hd, tcpname, AVIO_FLAG_READ_WRITE, - &h->interrupt_callback, NULL); - if (err) - goto fail; - - mmst->packet_id = 3; // default, initial value. - mmst->header_packet_id = 2; // default, initial value. - err = mms_safe_send_recv(mmst, send_startup_packet, SC_PKT_CLIENT_ACCEPTED); - if (err) - goto fail; - err = mms_safe_send_recv(mmst, send_time_test_data, SC_PKT_TIMING_TEST_REPLY); - if (err) - goto fail; - err = mms_safe_send_recv(mmst, send_protocol_select, SC_PKT_PROTOCOL_ACCEPTED); - if (err) - goto fail; - err = mms_safe_send_recv(mmst, send_media_file_request, SC_PKT_MEDIA_FILE_DETAILS); - if (err) - goto fail; - err = mms_safe_send_recv(mmst, send_media_header_request, SC_PKT_HEADER_REQUEST_ACCEPTED); - if (err) - goto fail; - err = mms_safe_send_recv(mmst, NULL, SC_PKT_ASF_HEADER); - if (err) - goto fail; - if((mmst->incoming_flags != 0X08) && (mmst->incoming_flags != 0X0C)) { - av_log(NULL, AV_LOG_ERROR, - "The server does not support MMST (try MMSH or RTSP)\n"); - err = AVERROR(EINVAL); - goto fail; - } - err = ff_mms_asf_header_parser(mms); - if (err) { - av_dlog(NULL, "asf header parsed failed!\n"); - goto fail; - } - mms->header_parsed = 1; - - if (!mms->asf_packet_len || !mms->stream_num) - goto fail; - - clear_stream_buffers(mms); - err = mms_safe_send_recv(mmst, send_stream_selection_request, SC_PKT_STREAM_ID_ACCEPTED); - if (err) - goto fail; - // send media packet request - err = mms_safe_send_recv(mmst, send_media_packet_request, SC_PKT_MEDIA_PKT_FOLLOWS); - if (err) { - goto fail; - } - av_dlog(NULL, "Leaving open (success)\n"); - return 0; -fail: - mms_close(h); - av_dlog(NULL, "Leaving open (failure: %d)\n", err); - return err; -} - -/** Read ASF data through the protocol. */ -static int mms_read(URLContext *h, uint8_t *buf, int size) -{ - /* TODO: see tcp.c:tcp_read() about a possible timeout scheme */ - MMSTContext *mmst = h->priv_data; - MMSContext *mms = &mmst->mms; - int result = 0; - - do { - if(mms->asf_header_read_size < mms->asf_header_size) { - /* Read from ASF header buffer */ - result = ff_mms_read_header(mms, buf, size); - } else if(mms->remaining_in_len) { - /* Read remaining packet data to buffer. - * the result can not be zero because remaining_in_len is positive.*/ - result = ff_mms_read_data(mms, buf, size); - } else { - /* Read from network */ - int err = mms_safe_send_recv(mmst, NULL, SC_PKT_ASF_MEDIA); - if (err == 0) { - if(mms->remaining_in_len>mms->asf_packet_len) { - av_log(NULL, AV_LOG_ERROR, - "Incoming pktlen %d is larger than ASF pktsize %d\n", - mms->remaining_in_len, mms->asf_packet_len); - result= AVERROR(EIO); - } else { - // copy the data to the packet buffer. - result = ff_mms_read_data(mms, buf, size); - if (result == 0) { - av_dlog(NULL, "Read ASF media packet size is zero!\n"); - break; - } - } - } else { - av_dlog(NULL, "read packet error!\n"); - break; - } - } - } while(!result); // only return one packet. - return result; -} - -URLProtocol ff_mmst_protocol = { - .name = "mmst", - .url_open = mms_open, - .url_read = mms_read, - .url_close = mms_close, - .priv_data_size = sizeof(MMSTContext), - .flags = URL_PROTOCOL_FLAG_NETWORK, -}; diff --git a/ffmpeg1/libavformat/mov.c b/ffmpeg1/libavformat/mov.c deleted file mode 100644 index 577c0e9..0000000 --- a/ffmpeg1/libavformat/mov.c +++ /dev/null @@ -1,3408 +0,0 @@ -/* - * MOV demuxer - * Copyright (c) 2001 Fabrice Bellard - * Copyright (c) 2009 Baptiste Coudurier - * - * 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 - -//#define DEBUG -//#define MOV_EXPORT_ALL_METADATA - -#include "libavutil/attributes.h" -#include "libavutil/channel_layout.h" -#include "libavutil/intreadwrite.h" -#include "libavutil/intfloat.h" -#include "libavutil/mathematics.h" -#include "libavutil/avstring.h" -#include "libavutil/dict.h" -#include "libavutil/opt.h" -#include "libavutil/timecode.h" -#include "libavcodec/ac3tab.h" -#include "avformat.h" -#include "internal.h" -#include "avio_internal.h" -#include "riff.h" -#include "isom.h" -#include "libavcodec/get_bits.h" -#include "id3v1.h" -#include "mov_chan.h" - -#if CONFIG_ZLIB -#include -#endif - -/* - * First version by Francois Revol revol@free.fr - * Seek function by Gael Chardon gael.dev@4now.net - */ - -#include "qtpalette.h" - - -#undef NDEBUG -#include - -/* those functions parse an atom */ -/* links atom IDs to parse functions */ -typedef struct MOVParseTableEntry { - uint32_t type; - int (*parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom); -} MOVParseTableEntry; - -static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom); - -static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb, - unsigned len, const char *key) -{ - char buf[16]; - - short current, total = 0; - avio_rb16(pb); // unknown - current = avio_rb16(pb); - if (len >= 6) - total = avio_rb16(pb); - if (!total) - snprintf(buf, sizeof(buf), "%d", current); - else - snprintf(buf, sizeof(buf), "%d/%d", current, total); - av_dict_set(&c->fc->metadata, key, buf, 0); - - return 0; -} - -static int mov_metadata_int8_bypass_padding(MOVContext *c, AVIOContext *pb, - unsigned len, const char *key) -{ - char buf[16]; - - /* bypass padding bytes */ - avio_r8(pb); - avio_r8(pb); - avio_r8(pb); - - snprintf(buf, sizeof(buf), "%d", avio_r8(pb)); - av_dict_set(&c->fc->metadata, key, buf, 0); - - return 0; -} - -static int mov_metadata_int8_no_padding(MOVContext *c, AVIOContext *pb, - unsigned len, const char *key) -{ - char buf[16]; - - snprintf(buf, sizeof(buf), "%d", avio_r8(pb)); - av_dict_set(&c->fc->metadata, key, buf, 0); - - return 0; -} - -static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb, - unsigned len, const char *key) -{ - short genre; - char buf[20]; - - avio_r8(pb); // unknown - - genre = avio_r8(pb); - if (genre < 1 || genre > ID3v1_GENRE_MAX) - return 0; - snprintf(buf, sizeof(buf), "%s", ff_id3v1_genre_str[genre-1]); - av_dict_set(&c->fc->metadata, key, buf, 0); - - return 0; -} - -static int mov_read_custom_metadata(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - char key[1024]={0}, data[1024]={0}; - int i; - AVStream *st; - MOVStreamContext *sc; - - if (c->fc->nb_streams < 1) - return 0; - st = c->fc->streams[c->fc->nb_streams-1]; - sc = st->priv_data; - - if (atom.size <= 8) return 0; - - for (i = 0; i < 3; i++) { // Parse up to three sub-atoms looking for name and data. - int data_size = avio_rb32(pb); - int tag = avio_rl32(pb); - int str_size = 0, skip_size = 0; - char *target = NULL; - - switch (tag) { - case MKTAG('n','a','m','e'): - avio_rb32(pb); // version/flags - str_size = skip_size = data_size - 12; - atom.size -= 12; - target = key; - break; - case MKTAG('d','a','t','a'): - avio_rb32(pb); // version/flags - avio_rb32(pb); // reserved (zero) - str_size = skip_size = data_size - 16; - atom.size -= 16; - target = data; - break; - default: - skip_size = data_size - 8; - str_size = 0; - break; - } - - if (target) { - str_size = FFMIN3(sizeof(data)-1, str_size, atom.size); - avio_read(pb, target, str_size); - target[str_size] = 0; - } - atom.size -= skip_size; - - // If we didn't read the full data chunk for the sub-atom, skip to the end of it. - if (skip_size > str_size) avio_skip(pb, skip_size - str_size); - } - - if (*key && *data) { - if (strcmp(key, "iTunSMPB") == 0) { - int priming, remainder, samples; - if(sscanf(data, "%*X %X %X %X", &priming, &remainder, &samples) == 3){ - if(priming>0 && priming<16384) - sc->start_pad = priming; - return 1; - } - } - if (strcmp(key, "cdec") == 0) { -// av_dict_set(&st->metadata, key, data, 0); - return 1; - } - } - return 0; -} - -static const uint32_t mac_to_unicode[128] = { - 0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1, - 0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8, - 0x00EA,0x00EB,0x00ED,0x00EC,0x00EE,0x00EF,0x00F1,0x00F3, - 0x00F2,0x00F4,0x00F6,0x00F5,0x00FA,0x00F9,0x00FB,0x00FC, - 0x2020,0x00B0,0x00A2,0x00A3,0x00A7,0x2022,0x00B6,0x00DF, - 0x00AE,0x00A9,0x2122,0x00B4,0x00A8,0x2260,0x00C6,0x00D8, - 0x221E,0x00B1,0x2264,0x2265,0x00A5,0x00B5,0x2202,0x2211, - 0x220F,0x03C0,0x222B,0x00AA,0x00BA,0x03A9,0x00E6,0x00F8, - 0x00BF,0x00A1,0x00AC,0x221A,0x0192,0x2248,0x2206,0x00AB, - 0x00BB,0x2026,0x00A0,0x00C0,0x00C3,0x00D5,0x0152,0x0153, - 0x2013,0x2014,0x201C,0x201D,0x2018,0x2019,0x00F7,0x25CA, - 0x00FF,0x0178,0x2044,0x20AC,0x2039,0x203A,0xFB01,0xFB02, - 0x2021,0x00B7,0x201A,0x201E,0x2030,0x00C2,0x00CA,0x00C1, - 0x00CB,0x00C8,0x00CD,0x00CE,0x00CF,0x00CC,0x00D3,0x00D4, - 0xF8FF,0x00D2,0x00DA,0x00DB,0x00D9,0x0131,0x02C6,0x02DC, - 0x00AF,0x02D8,0x02D9,0x02DA,0x00B8,0x02DD,0x02DB,0x02C7, -}; - -static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len, - char *dst, int dstlen) -{ - char *p = dst; - char *end = dst+dstlen-1; - int i; - - for (i = 0; i < len; i++) { - uint8_t t, c = avio_r8(pb); - if (c < 0x80 && p < end) - *p++ = c; - else if (p < end) - PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;); - } - *p = 0; - return p - dst; -} - -static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len) -{ - AVPacket pkt; - AVStream *st; - MOVStreamContext *sc; - enum AVCodecID id; - int ret; - - switch (type) { - case 0xd: id = AV_CODEC_ID_MJPEG; break; - case 0xe: id = AV_CODEC_ID_PNG; break; - case 0x1b: id = AV_CODEC_ID_BMP; break; - default: - av_log(c->fc, AV_LOG_WARNING, "Unknown cover type: 0x%x.\n", type); - avio_skip(pb, len); - return 0; - } - - st = avformat_new_stream(c->fc, NULL); - if (!st) - return AVERROR(ENOMEM); - sc = av_mallocz(sizeof(*sc)); - if (!sc) - return AVERROR(ENOMEM); - st->priv_data = sc; - - ret = av_get_packet(pb, &pkt, len); - if (ret < 0) - return ret; - - st->disposition |= AV_DISPOSITION_ATTACHED_PIC; - - st->attached_pic = pkt; - st->attached_pic.stream_index = st->index; - st->attached_pic.flags |= AV_PKT_FLAG_KEY; - - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = id; - - return 0; -} - -static int mov_metadata_raw(MOVContext *c, AVIOContext *pb, - unsigned len, const char *key) -{ - char *value = av_malloc(len + 1); - if (!value) - return AVERROR(ENOMEM); - avio_read(pb, value, len); - value[len] = 0; - return av_dict_set(&c->fc->metadata, key, value, AV_DICT_DONT_STRDUP_VAL); -} - -static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ -#ifdef MOV_EXPORT_ALL_METADATA - char tmp_key[5]; -#endif - char str[1024], key2[16], language[4] = {0}; - const char *key = NULL; - uint16_t langcode = 0; - uint32_t data_type = 0, str_size; - int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL; - - if (c->itunes_metadata && atom.type == MKTAG('-','-','-','-')) - return mov_read_custom_metadata(c, pb, atom); - - switch (atom.type) { - case MKTAG(0xa9,'n','a','m'): key = "title"; break; - case MKTAG(0xa9,'a','u','t'): - case MKTAG(0xa9,'A','R','T'): key = "artist"; break; - case MKTAG( 'a','A','R','T'): key = "album_artist"; break; - case MKTAG(0xa9,'w','r','t'): key = "composer"; break; - case MKTAG( 'c','p','r','t'): - case MKTAG(0xa9,'c','p','y'): key = "copyright"; break; - case MKTAG(0xa9,'g','r','p'): key = "grouping"; break; - case MKTAG(0xa9,'l','y','r'): key = "lyrics"; break; - case MKTAG(0xa9,'c','m','t'): - case MKTAG(0xa9,'i','n','f'): key = "comment"; break; - case MKTAG(0xa9,'a','l','b'): key = "album"; break; - case MKTAG(0xa9,'d','a','y'): key = "date"; break; - case MKTAG(0xa9,'g','e','n'): key = "genre"; break; - case MKTAG( 'g','n','r','e'): key = "genre"; - parse = mov_metadata_gnre; break; - case MKTAG(0xa9,'t','o','o'): - case MKTAG(0xa9,'s','w','r'): key = "encoder"; break; - case MKTAG(0xa9,'e','n','c'): key = "encoder"; break; - case MKTAG(0xa9,'m','a','k'): key = "make"; break; - case MKTAG(0xa9,'m','o','d'): key = "model"; break; - case MKTAG(0xa9,'x','y','z'): key = "location"; break; - case MKTAG( 'd','e','s','c'): key = "description";break; - case MKTAG( 'l','d','e','s'): key = "synopsis"; break; - case MKTAG( 't','v','s','h'): key = "show"; break; - case MKTAG( 't','v','e','n'): key = "episode_id";break; - case MKTAG( 't','v','n','n'): key = "network"; break; - case MKTAG( 't','r','k','n'): key = "track"; - parse = mov_metadata_track_or_disc_number; break; - case MKTAG( 'd','i','s','k'): key = "disc"; - parse = mov_metadata_track_or_disc_number; break; - case MKTAG( 't','v','e','s'): key = "episode_sort"; - parse = mov_metadata_int8_bypass_padding; break; - case MKTAG( 't','v','s','n'): key = "season_number"; - parse = mov_metadata_int8_bypass_padding; break; - case MKTAG( 's','t','i','k'): key = "media_type"; - parse = mov_metadata_int8_no_padding; break; - case MKTAG( 'h','d','v','d'): key = "hd_video"; - parse = mov_metadata_int8_no_padding; break; - case MKTAG( 'p','g','a','p'): key = "gapless_playback"; - parse = mov_metadata_int8_no_padding; break; - case MKTAG( '@','P','R','M'): - return mov_metadata_raw(c, pb, atom.size, "premiere_version"); - case MKTAG( '@','P','R','Q'): - return mov_metadata_raw(c, pb, atom.size, "quicktime_version"); - } - - if (c->itunes_metadata && atom.size > 8) { - int data_size = avio_rb32(pb); - int tag = avio_rl32(pb); - if (tag == MKTAG('d','a','t','a')) { - data_type = avio_rb32(pb); // type - avio_rb32(pb); // unknown - str_size = data_size - 16; - atom.size -= 16; - - if (atom.type == MKTAG('c', 'o', 'v', 'r')) { - int ret = mov_read_covr(c, pb, data_type, str_size); - if (ret < 0) { - av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n"); - return ret; - } - } - } else return 0; - } else if (atom.size > 4 && key && !c->itunes_metadata) { - str_size = avio_rb16(pb); // string length - langcode = avio_rb16(pb); - ff_mov_lang_to_iso639(langcode, language); - atom.size -= 4; - } else - str_size = atom.size; - -#ifdef MOV_EXPORT_ALL_METADATA - if (!key) { - snprintf(tmp_key, 5, "%.4s", (char*)&atom.type); - key = tmp_key; - } -#endif - - if (!key) - return 0; - if (atom.size < 0) - return AVERROR_INVALIDDATA; - - str_size = FFMIN3(sizeof(str)-1, str_size, atom.size); - - if (parse) - parse(c, pb, str_size, key); - else { - if (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff))) { // MAC Encoded - mov_read_mac_string(c, pb, str_size, str, sizeof(str)); - } else { - avio_read(pb, str, str_size); - str[str_size] = 0; - } - av_dict_set(&c->fc->metadata, key, str, 0); - if (*language && strcmp(language, "und")) { - snprintf(key2, sizeof(key2), "%s-%s", key, language); - av_dict_set(&c->fc->metadata, key2, str, 0); - } - } - av_dlog(c->fc, "lang \"%3s\" ", language); - av_dlog(c->fc, "tag \"%s\" value \"%s\" atom \"%.4s\" %d %"PRId64"\n", - key, str, (char*)&atom.type, str_size, atom.size); - - return 0; -} - -static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - int64_t start; - int i, nb_chapters, str_len, version; - char str[256+1]; - - if ((atom.size -= 5) < 0) - return 0; - - version = avio_r8(pb); - avio_rb24(pb); - if (version) - avio_rb32(pb); // ??? - nb_chapters = avio_r8(pb); - - for (i = 0; i < nb_chapters; i++) { - if (atom.size < 9) - return 0; - - start = avio_rb64(pb); - str_len = avio_r8(pb); - - if ((atom.size -= 9+str_len) < 0) - return 0; - - avio_read(pb, str, str_len); - str[str_len] = 0; - avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str); - } - return 0; -} - -#define MIN_DATA_ENTRY_BOX_SIZE 12 -static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - AVStream *st; - MOVStreamContext *sc; - int entries, i, j; - - if (c->fc->nb_streams < 1) - return 0; - st = c->fc->streams[c->fc->nb_streams-1]; - sc = st->priv_data; - - avio_rb32(pb); // version + flags - entries = avio_rb32(pb); - if (entries > (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 || - entries >= UINT_MAX / sizeof(*sc->drefs)) - return AVERROR_INVALIDDATA; - av_free(sc->drefs); - sc->drefs_count = 0; - sc->drefs = av_mallocz(entries * sizeof(*sc->drefs)); - if (!sc->drefs) - return AVERROR(ENOMEM); - sc->drefs_count = entries; - - for (i = 0; i < sc->drefs_count; i++) { - MOVDref *dref = &sc->drefs[i]; - uint32_t size = avio_rb32(pb); - int64_t next = avio_tell(pb) + size - 4; - - if (size < 12) - return AVERROR_INVALIDDATA; - - dref->type = avio_rl32(pb); - avio_rb32(pb); // version + flags - av_dlog(c->fc, "type %.4s size %d\n", (char*)&dref->type, size); - - if (dref->type == MKTAG('a','l','i','s') && size > 150) { - /* macintosh alias record */ - uint16_t volume_len, len; - int16_t type; - - avio_skip(pb, 10); - - volume_len = avio_r8(pb); - volume_len = FFMIN(volume_len, 27); - avio_read(pb, dref->volume, 27); - dref->volume[volume_len] = 0; - av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len); - - avio_skip(pb, 12); - - len = avio_r8(pb); - len = FFMIN(len, 63); - avio_read(pb, dref->filename, 63); - dref->filename[len] = 0; - av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len); - - avio_skip(pb, 16); - - /* read next level up_from_alias/down_to_target */ - dref->nlvl_from = avio_rb16(pb); - dref->nlvl_to = avio_rb16(pb); - av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n", - dref->nlvl_from, dref->nlvl_to); - - avio_skip(pb, 16); - - for (type = 0; type != -1 && avio_tell(pb) < next; ) { - if(url_feof(pb)) - return AVERROR_EOF; - type = avio_rb16(pb); - len = avio_rb16(pb); - av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len); - if (len&1) - len += 1; - if (type == 2) { // absolute path - av_free(dref->path); - dref->path = av_mallocz(len+1); - if (!dref->path) - return AVERROR(ENOMEM); - avio_read(pb, dref->path, len); - if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) { - len -= volume_len; - memmove(dref->path, dref->path+volume_len, len); - dref->path[len] = 0; - } - for (j = 0; j < len; j++) - if (dref->path[j] == ':') - dref->path[j] = '/'; - av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path); - } else if (type == 0) { // directory name - av_free(dref->dir); - dref->dir = av_malloc(len+1); - if (!dref->dir) - return AVERROR(ENOMEM); - avio_read(pb, dref->dir, len); - dref->dir[len] = 0; - for (j = 0; j < len; j++) - if (dref->dir[j] == ':') - dref->dir[j] = '/'; - av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir); - } else - avio_skip(pb, len); - } - } - avio_seek(pb, next, SEEK_SET); - } - return 0; -} - -static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - AVStream *st; - uint32_t type; - uint32_t av_unused ctype; - int title_size; - char *title_str; - - if (c->fc->nb_streams < 1) // meta before first trak - return 0; - - st = c->fc->streams[c->fc->nb_streams-1]; - - avio_r8(pb); /* version */ - avio_rb24(pb); /* flags */ - - /* component type */ - ctype = avio_rl32(pb); - type = avio_rl32(pb); /* component subtype */ - - av_dlog(c->fc, "ctype= %.4s (0x%08x)\n", (char*)&ctype, ctype); - av_dlog(c->fc, "stype= %.4s\n", (char*)&type); - - if (type == MKTAG('v','i','d','e')) - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - else if (type == MKTAG('s','o','u','n')) - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - else if (type == MKTAG('m','1','a',' ')) - st->codec->codec_id = AV_CODEC_ID_MP2; - else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p'))) - st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE; - - avio_rb32(pb); /* component manufacture */ - avio_rb32(pb); /* component flags */ - avio_rb32(pb); /* component flags mask */ - - title_size = atom.size - 24; - if (title_size > 0) { - title_str = av_malloc(title_size + 1); /* Add null terminator */ - if (!title_str) - return AVERROR(ENOMEM); - avio_read(pb, title_str, title_size); - title_str[title_size] = 0; - if (title_str[0]) - av_dict_set(&st->metadata, "handler_name", title_str + - (!c->isom && title_str[0] == title_size - 1), 0); - av_freep(&title_str); - } - - return 0; -} - -int ff_mov_read_esds(AVFormatContext *fc, AVIOContext *pb, MOVAtom atom) -{ - AVStream *st; - int tag; - - if (fc->nb_streams < 1) - return 0; - st = fc->streams[fc->nb_streams-1]; - - avio_rb32(pb); /* version + flags */ - ff_mp4_read_descr(fc, pb, &tag); - if (tag == MP4ESDescrTag) { - ff_mp4_parse_es_descr(pb, NULL); - } else - avio_rb16(pb); /* ID */ - - ff_mp4_read_descr(fc, pb, &tag); - if (tag == MP4DecConfigDescrTag) - ff_mp4_read_dec_config_descr(fc, st, pb); - return 0; -} - -static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - return ff_mov_read_esds(c->fc, pb, atom); -} - -static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - AVStream *st; - int ac3info, acmod, lfeon, bsmod; - - if (c->fc->nb_streams < 1) - return 0; - st = c->fc->streams[c->fc->nb_streams-1]; - - ac3info = avio_rb24(pb); - bsmod = (ac3info >> 14) & 0x7; - acmod = (ac3info >> 11) & 0x7; - lfeon = (ac3info >> 10) & 0x1; - st->codec->channels = ((int[]){2,1,2,3,3,4,4,5})[acmod] + lfeon; - st->codec->channel_layout = avpriv_ac3_channel_layout_tab[acmod]; - if (lfeon) - st->codec->channel_layout |= AV_CH_LOW_FREQUENCY; - st->codec->audio_service_type = bsmod; - if (st->codec->channels > 1 && bsmod == 0x7) - st->codec->audio_service_type = AV_AUDIO_SERVICE_TYPE_KARAOKE; - - return 0; -} - -static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - AVStream *st; - int eac3info, acmod, lfeon, bsmod; - - if (c->fc->nb_streams < 1) - return 0; - st = c->fc->streams[c->fc->nb_streams-1]; - - /* No need to parse fields for additional independent substreams and its - * associated dependent substreams since libavcodec's E-AC-3 decoder - * does not support them yet. */ - avio_rb16(pb); /* data_rate and num_ind_sub */ - eac3info = avio_rb24(pb); - bsmod = (eac3info >> 12) & 0x1f; - acmod = (eac3info >> 9) & 0x7; - lfeon = (eac3info >> 8) & 0x1; - st->codec->channel_layout = avpriv_ac3_channel_layout_tab[acmod]; - if (lfeon) - st->codec->channel_layout |= AV_CH_LOW_FREQUENCY; - st->codec->channels = av_get_channel_layout_nb_channels(st->codec->channel_layout); - st->codec->audio_service_type = bsmod; - if (st->codec->channels > 1 && bsmod == 0x7) - st->codec->audio_service_type = AV_AUDIO_SERVICE_TYPE_KARAOKE; - - return 0; -} - -static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - AVStream *st; - - if (c->fc->nb_streams < 1) - return 0; - st = c->fc->streams[c->fc->nb_streams-1]; - - if (atom.size < 16) - return 0; - - /* skip version and flags */ - avio_skip(pb, 4); - - ff_mov_read_chan(c->fc, pb, st, atom.size - 4); - - return 0; -} - -static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - AVStream *st; - - if (c->fc->nb_streams < 1) - return 0; - st = c->fc->streams[c->fc->nb_streams-1]; - - if (ff_get_wav_header(pb, st->codec, atom.size) < 0) { - av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n"); - } - - return 0; -} - -static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - const int num = avio_rb32(pb); - const int den = avio_rb32(pb); - AVStream *st; - - if (c->fc->nb_streams < 1) - return 0; - st = c->fc->streams[c->fc->nb_streams-1]; - - if ((st->sample_aspect_ratio.den != 1 || st->sample_aspect_ratio.num) && // default - (den != st->sample_aspect_ratio.den || num != st->sample_aspect_ratio.num)) { - av_log(c->fc, AV_LOG_WARNING, - "sample aspect ratio already set to %d:%d, ignoring 'pasp' atom (%d:%d)\n", - st->sample_aspect_ratio.num, st->sample_aspect_ratio.den, - num, den); - } else if (den != 0) { - st->sample_aspect_ratio.num = num; - st->sample_aspect_ratio.den = den; - } - return 0; -} - -/* this atom contains actual media data */ -static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - if (atom.size == 0) /* wrong one (MP4) */ - return 0; - c->found_mdat=1; - return 0; /* now go for moov */ -} - -/* read major brand, minor version and compatible brands and store them as metadata */ -static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - uint32_t minor_ver; - int comp_brand_size; - char minor_ver_str[11]; /* 32 bit integer -> 10 digits + null */ - char* comp_brands_str; - uint8_t type[5] = {0}; - - avio_read(pb, type, 4); - if (strcmp(type, "qt ")) - c->isom = 1; - av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type); - av_dict_set(&c->fc->metadata, "major_brand", type, 0); - minor_ver = avio_rb32(pb); /* minor version */ - snprintf(minor_ver_str, sizeof(minor_ver_str), "%d", minor_ver); - av_dict_set(&c->fc->metadata, "minor_version", minor_ver_str, 0); - - comp_brand_size = atom.size - 8; - if (comp_brand_size < 0) - return AVERROR_INVALIDDATA; - comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */ - if (!comp_brands_str) - return AVERROR(ENOMEM); - avio_read(pb, comp_brands_str, comp_brand_size); - comp_brands_str[comp_brand_size] = 0; - av_dict_set(&c->fc->metadata, "compatible_brands", comp_brands_str, 0); - av_freep(&comp_brands_str); - - return 0; -} - -/* this atom should contain all header atoms */ -static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - int ret; - - if ((ret = mov_read_default(c, pb, atom)) < 0) - return ret; - /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */ - /* so we don't parse the whole file if over a network */ - c->found_moov=1; - return 0; /* now go for mdat */ -} - -static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - c->fragment.moof_offset = avio_tell(pb) - 8; - av_dlog(c->fc, "moof offset %"PRIx64"\n", c->fragment.moof_offset); - return mov_read_default(c, pb, atom); -} - -static void mov_metadata_creation_time(AVDictionary **metadata, int64_t time) -{ - char buffer[32]; - if (time) { - struct tm *ptm; - time_t timet; - if(time >= 2082844800) - time -= 2082844800; /* seconds between 1904-01-01 and Epoch */ - timet = time; - ptm = gmtime(&timet); - if (!ptm) return; - strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", ptm); - av_dict_set(metadata, "creation_time", buffer, 0); - } -} - -static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - AVStream *st; - MOVStreamContext *sc; - int version; - char language[4] = {0}; - unsigned lang; - int64_t creation_time; - - if (c->fc->nb_streams < 1) - return 0; - st = c->fc->streams[c->fc->nb_streams-1]; - sc = st->priv_data; - - version = avio_r8(pb); - if (version > 1) { - avpriv_request_sample(c->fc, "Version %d", version); - return AVERROR_PATCHWELCOME; - } - avio_rb24(pb); /* flags */ - if (version == 1) { - creation_time = avio_rb64(pb); - avio_rb64(pb); - } else { - creation_time = avio_rb32(pb); - avio_rb32(pb); /* modification time */ - } - mov_metadata_creation_time(&st->metadata, creation_time); - - sc->time_scale = avio_rb32(pb); - st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */ - - lang = avio_rb16(pb); /* language */ - if (ff_mov_lang_to_iso639(lang, language)) - av_dict_set(&st->metadata, "language", language, 0); - avio_rb16(pb); /* quality */ - - return 0; -} - -static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - int64_t creation_time; - int version = avio_r8(pb); /* version */ - avio_rb24(pb); /* flags */ - - if (version == 1) { - creation_time = avio_rb64(pb); - avio_rb64(pb); - } else { - creation_time = avio_rb32(pb); - avio_rb32(pb); /* modification time */ - } - mov_metadata_creation_time(&c->fc->metadata, creation_time); - c->time_scale = avio_rb32(pb); /* time scale */ - - av_dlog(c->fc, "time scale = %i\n", c->time_scale); - - c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */ - // set the AVCodecContext duration because the duration of individual tracks - // may be inaccurate - if (c->time_scale > 0) - c->fc->duration = av_rescale(c->duration, AV_TIME_BASE, c->time_scale); - avio_rb32(pb); /* preferred scale */ - - avio_rb16(pb); /* preferred volume */ - - avio_skip(pb, 10); /* reserved */ - - avio_skip(pb, 36); /* display matrix */ - - avio_rb32(pb); /* preview time */ - avio_rb32(pb); /* preview duration */ - avio_rb32(pb); /* poster time */ - avio_rb32(pb); /* selection time */ - avio_rb32(pb); /* selection duration */ - avio_rb32(pb); /* current time */ - avio_rb32(pb); /* next track ID */ - return 0; -} - -static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - AVStream *st; - int little_endian; - - if (c->fc->nb_streams < 1) - return 0; - st = c->fc->streams[c->fc->nb_streams-1]; - - little_endian = avio_rb16(pb) & 0xFF; - av_dlog(c->fc, "enda %d\n", little_endian); - if (little_endian == 1) { - switch (st->codec->codec_id) { - case AV_CODEC_ID_PCM_S24BE: - st->codec->codec_id = AV_CODEC_ID_PCM_S24LE; - break; - case AV_CODEC_ID_PCM_S32BE: - st->codec->codec_id = AV_CODEC_ID_PCM_S32LE; - break; - case AV_CODEC_ID_PCM_F32BE: - st->codec->codec_id = AV_CODEC_ID_PCM_F32LE; - break; - case AV_CODEC_ID_PCM_F64BE: - st->codec->codec_id = AV_CODEC_ID_PCM_F64LE; - break; - default: - break; - } - } - return 0; -} - -static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - AVStream *st; - unsigned mov_field_order; - enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN; - - if (c->fc->nb_streams < 1) // will happen with jp2 files - return 0; - st = c->fc->streams[c->fc->nb_streams-1]; - if (atom.size < 2) - return AVERROR_INVALIDDATA; - mov_field_order = avio_rb16(pb); - if ((mov_field_order & 0xFF00) == 0x0100) - decoded_field_order = AV_FIELD_PROGRESSIVE; - else if ((mov_field_order & 0xFF00) == 0x0200) { - switch (mov_field_order & 0xFF) { - case 0x01: decoded_field_order = AV_FIELD_TT; - break; - case 0x06: decoded_field_order = AV_FIELD_BB; - break; - case 0x09: decoded_field_order = AV_FIELD_TB; - break; - case 0x0E: decoded_field_order = AV_FIELD_BT; - break; - } - } - if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) { - av_log(NULL, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order); - } - st->codec->field_order = decoded_field_order; - - return 0; -} - -/* FIXME modify qdm2/svq3/h264 decoders to take full atom as extradata */ -static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom, - enum AVCodecID codec_id) -{ - AVStream *st; - uint64_t size; - uint8_t *buf; - - if (c->fc->nb_streams < 1) // will happen with jp2 files - return 0; - st= c->fc->streams[c->fc->nb_streams-1]; - - if (st->codec->codec_id != codec_id) - return 0; /* unexpected codec_id - don't mess with extradata */ - - size= (uint64_t)st->codec->extradata_size + atom.size + 8 + FF_INPUT_BUFFER_PADDING_SIZE; - if (size > INT_MAX || (uint64_t)atom.size > INT_MAX) - return AVERROR_INVALIDDATA; - buf= av_realloc(st->codec->extradata, size); - if (!buf) - return AVERROR(ENOMEM); - st->codec->extradata= buf; - buf+= st->codec->extradata_size; - st->codec->extradata_size= size - FF_INPUT_BUFFER_PADDING_SIZE; - AV_WB32( buf , atom.size + 8); - AV_WL32( buf + 4, atom.type); - avio_read(pb, buf + 8, atom.size); - return 0; -} - -/* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */ -static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC); -} - -static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - return mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVS); -} - -static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000); -} - -static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - return mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI); -} - -static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3); -} - -static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - AVStream *st; - - if (c->fc->nb_streams < 1) - return 0; - st = c->fc->streams[c->fc->nb_streams-1]; - - if ((uint64_t)atom.size > (1<<30)) - return AVERROR_INVALIDDATA; - - if (st->codec->codec_id == AV_CODEC_ID_QDM2 || st->codec->codec_id == AV_CODEC_ID_QDMC) { - // pass all frma atom to codec, needed at least for QDMC and QDM2 - av_free(st->codec->extradata); - st->codec->extradata_size = 0; - st->codec->extradata = av_mallocz(atom.size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!st->codec->extradata) - return AVERROR(ENOMEM); - st->codec->extradata_size = atom.size; - avio_read(pb, st->codec->extradata, atom.size); - } else if (atom.size > 8) { /* to read frma, esds atoms */ - int ret; - if ((ret = mov_read_default(c, pb, atom)) < 0) - return ret; - } else - avio_skip(pb, atom.size); - return 0; -} - -/** - * This function reads atom content and puts data in extradata without tag - * nor size unlike mov_read_extradata. - */ -static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - AVStream *st; - - if (c->fc->nb_streams < 1) - return 0; - st = c->fc->streams[c->fc->nb_streams-1]; - - if ((uint64_t)atom.size > (1<<30)) - return AVERROR_INVALIDDATA; - - if (atom.size >= 10) { - // Broken files created by legacy versions of libavformat will - // wrap a whole fiel atom inside of a glbl atom. - unsigned size = avio_rb32(pb); - unsigned type = avio_rl32(pb); - avio_seek(pb, -8, SEEK_CUR); - if (type == MKTAG('f','i','e','l') && size == atom.size) - return mov_read_default(c, pb, atom); - } - av_free(st->codec->extradata); - st->codec->extradata_size = 0; - st->codec->extradata = av_mallocz(atom.size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!st->codec->extradata) - return AVERROR(ENOMEM); - st->codec->extradata_size = atom.size; - avio_read(pb, st->codec->extradata, atom.size); - return 0; -} - -static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - AVStream *st; - uint8_t profile_level; - - if (c->fc->nb_streams < 1) - return 0; - st = c->fc->streams[c->fc->nb_streams-1]; - - if (atom.size >= (1<<28) || atom.size < 7) - return AVERROR_INVALIDDATA; - - profile_level = avio_r8(pb); - if ((profile_level & 0xf0) != 0xc0) - return 0; - - av_free(st->codec->extradata); - st->codec->extradata_size = 0; - st->codec->extradata = av_mallocz(atom.size - 7 + FF_INPUT_BUFFER_PADDING_SIZE); - if (!st->codec->extradata) - return AVERROR(ENOMEM); - st->codec->extradata_size = atom.size - 7; - avio_seek(pb, 6, SEEK_CUR); - avio_read(pb, st->codec->extradata, st->codec->extradata_size); - return 0; -} - -/** - * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself, - * but can have extradata appended at the end after the 40 bytes belonging - * to the struct. - */ -static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - AVStream *st; - - if (c->fc->nb_streams < 1) - return 0; - if (atom.size <= 40) - return 0; - st = c->fc->streams[c->fc->nb_streams-1]; - - if ((uint64_t)atom.size > (1<<30)) - return AVERROR_INVALIDDATA; - - av_free(st->codec->extradata); - st->codec->extradata_size = 0; - st->codec->extradata = av_mallocz(atom.size - 40 + FF_INPUT_BUFFER_PADDING_SIZE); - if (!st->codec->extradata) - return AVERROR(ENOMEM); - st->codec->extradata_size = atom.size - 40; - avio_skip(pb, 40); - avio_read(pb, st->codec->extradata, atom.size - 40); - return 0; -} - -static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - AVStream *st; - MOVStreamContext *sc; - unsigned int i, entries; - - if (c->fc->nb_streams < 1) - return 0; - st = c->fc->streams[c->fc->nb_streams-1]; - sc = st->priv_data; - - avio_r8(pb); /* version */ - avio_rb24(pb); /* flags */ - - entries = avio_rb32(pb); - - if (!entries) - return 0; - if (entries >= UINT_MAX/sizeof(int64_t)) - return AVERROR_INVALIDDATA; - - sc->chunk_offsets = av_malloc(entries * sizeof(int64_t)); - if (!sc->chunk_offsets) - return AVERROR(ENOMEM); - sc->chunk_count = entries; - - if (atom.type == MKTAG('s','t','c','o')) - for (i = 0; i < entries && !pb->eof_reached; i++) - sc->chunk_offsets[i] = avio_rb32(pb); - else if (atom.type == MKTAG('c','o','6','4')) - for (i = 0; i < entries && !pb->eof_reached; i++) - sc->chunk_offsets[i] = avio_rb64(pb); - else - return AVERROR_INVALIDDATA; - - sc->chunk_count = i; - - if (pb->eof_reached) - return AVERROR_EOF; - - return 0; -} - -/** - * Compute codec id for 'lpcm' tag. - * See CoreAudioTypes and AudioStreamBasicDescription at Apple. - */ -enum AVCodecID ff_mov_get_lpcm_codec_id(int bps, int flags) -{ - /* lpcm flags: - * 0x1 = float - * 0x2 = big-endian - * 0x4 = signed - */ - return ff_get_pcm_codec_id(bps, flags & 1, flags & 2, flags & 4 ? -1 : 0); -} - -int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries) -{ - AVStream *st; - MOVStreamContext *sc; - int j, pseudo_stream_id; - - if (c->fc->nb_streams < 1) - return 0; - st = c->fc->streams[c->fc->nb_streams-1]; - sc = st->priv_data; - - for (pseudo_stream_id = 0; - pseudo_stream_id < entries && !pb->eof_reached; - pseudo_stream_id++) { - //Parsing Sample description table - enum AVCodecID id; - int dref_id = 1; - MOVAtom a = { AV_RL32("stsd") }; - int64_t start_pos = avio_tell(pb); - int64_t size = avio_rb32(pb); /* size */ - uint32_t format = avio_rl32(pb); /* data format */ - - if (size >= 16) { - avio_rb32(pb); /* reserved */ - avio_rb16(pb); /* reserved */ - dref_id = avio_rb16(pb); - }else if (size <= 7){ - av_log(c->fc, AV_LOG_ERROR, "invalid size %"PRId64" in stsd\n", size); - return AVERROR_INVALIDDATA; - } - - if (st->codec->codec_tag && - st->codec->codec_tag != format && - (c->fc->video_codec_id ? ff_codec_get_id(ff_codec_movvideo_tags, format) != c->fc->video_codec_id - : st->codec->codec_tag != MKTAG('j','p','e','g')) - ){ - /* Multiple fourcc, we skip JPEG. This is not correct, we should - * export it as a separate AVStream but this needs a few changes - * in the MOV demuxer, patch welcome. */ - av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n"); - avio_skip(pb, size - (avio_tell(pb) - start_pos)); - continue; - } - /* we cannot demux concatenated h264 streams because of different extradata */ - if (st->codec->codec_tag && st->codec->codec_tag == AV_RL32("avc1")) - av_log(c->fc, AV_LOG_WARNING, "Concatenated H.264 might not play corrently.\n"); - sc->pseudo_stream_id = st->codec->codec_tag ? -1 : pseudo_stream_id; - sc->dref_id= dref_id; - - st->codec->codec_tag = format; - id = ff_codec_get_id(ff_codec_movaudio_tags, format); - if (id<=0 && ((format&0xFFFF) == 'm'+('s'<<8) || (format&0xFFFF) == 'T'+('S'<<8))) - id = ff_codec_get_id(ff_codec_wav_tags, av_bswap32(format)&0xFFFF); - - if (st->codec->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) { - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - } else if (st->codec->codec_type != AVMEDIA_TYPE_AUDIO && /* do not overwrite codec type */ - format && format != MKTAG('m','p','4','s')) { /* skip old asf mpeg4 tag */ - id = ff_codec_get_id(ff_codec_movvideo_tags, format); - if (id <= 0) - id = ff_codec_get_id(ff_codec_bmp_tags, format); - if (id > 0) - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - else if (st->codec->codec_type == AVMEDIA_TYPE_DATA || - (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE && - st->codec->codec_id == AV_CODEC_ID_NONE)){ - id = ff_codec_get_id(ff_codec_movsubtitle_tags, format); - if (id > 0) - st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE; - } - } - - av_dlog(c->fc, "size=%"PRId64" 4CC= %c%c%c%c codec_type=%d\n", size, - (format >> 0) & 0xff, (format >> 8) & 0xff, (format >> 16) & 0xff, - (format >> 24) & 0xff, st->codec->codec_type); - - if (st->codec->codec_type==AVMEDIA_TYPE_VIDEO) { - unsigned int color_depth, len; - int color_greyscale; - int color_table_id; - - st->codec->codec_id = id; - avio_rb16(pb); /* version */ - avio_rb16(pb); /* revision level */ - avio_rb32(pb); /* vendor */ - avio_rb32(pb); /* temporal quality */ - avio_rb32(pb); /* spatial quality */ - - st->codec->width = avio_rb16(pb); /* width */ - st->codec->height = avio_rb16(pb); /* height */ - - avio_rb32(pb); /* horiz resolution */ - avio_rb32(pb); /* vert resolution */ - avio_rb32(pb); /* data size, always 0 */ - avio_rb16(pb); /* frames per samples */ - - len = avio_r8(pb); /* codec name, pascal string */ - if (len > 31) - len = 31; - mov_read_mac_string(c, pb, len, st->codec->codec_name, 32); - if (len < 31) - avio_skip(pb, 31 - len); - /* codec_tag YV12 triggers an UV swap in rawdec.c */ - if (!memcmp(st->codec->codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)){ - st->codec->codec_tag=MKTAG('I', '4', '2', '0'); - st->codec->width &= ~1; - st->codec->height &= ~1; - } - /* Flash Media Server uses tag H263 with Sorenson Spark */ - if (format == MKTAG('H','2','6','3') && - !memcmp(st->codec->codec_name, "Sorenson H263", 13)) - st->codec->codec_id = AV_CODEC_ID_FLV1; - - st->codec->bits_per_coded_sample = avio_rb16(pb); /* depth */ - color_table_id = avio_rb16(pb); /* colortable id */ - av_dlog(c->fc, "depth %d, ctab id %d\n", - st->codec->bits_per_coded_sample, color_table_id); - /* figure out the palette situation */ - color_depth = st->codec->bits_per_coded_sample & 0x1F; - color_greyscale = st->codec->bits_per_coded_sample & 0x20; - - /* if the depth is 2, 4, or 8 bpp, file is palettized */ - if ((color_depth == 2) || (color_depth == 4) || - (color_depth == 8)) { - /* for palette traversal */ - unsigned int color_start, color_count, color_end; - unsigned char a, r, g, b; - - if (color_greyscale) { - int color_index, color_dec; - /* compute the greyscale palette */ - st->codec->bits_per_coded_sample = color_depth; - color_count = 1 << color_depth; - color_index = 255; - color_dec = 256 / (color_count - 1); - for (j = 0; j < color_count; j++) { - if (id == AV_CODEC_ID_CINEPAK){ - r = g = b = color_count - 1 - color_index; - }else - r = g = b = color_index; - sc->palette[j] = - (0xFFU << 24) | (r << 16) | (g << 8) | (b); - color_index -= color_dec; - if (color_index < 0) - color_index = 0; - } - } else if (color_table_id) { - const uint8_t *color_table; - /* if flag bit 3 is set, use the default palette */ - color_count = 1 << color_depth; - if (color_depth == 2) - color_table = ff_qt_default_palette_4; - else if (color_depth == 4) - color_table = ff_qt_default_palette_16; - else - color_table = ff_qt_default_palette_256; - - for (j = 0; j < color_count; j++) { - r = color_table[j * 3 + 0]; - g = color_table[j * 3 + 1]; - b = color_table[j * 3 + 2]; - sc->palette[j] = - (0xFFU << 24) | (r << 16) | (g << 8) | (b); - } - } else { - /* load the palette from the file */ - color_start = avio_rb32(pb); - color_count = avio_rb16(pb); - color_end = avio_rb16(pb); - if ((color_start <= 255) && - (color_end <= 255)) { - for (j = color_start; j <= color_end; j++) { - /* each A, R, G, or B component is 16 bits; - * only use the top 8 bits */ - a = avio_r8(pb); - avio_r8(pb); - r = avio_r8(pb); - avio_r8(pb); - g = avio_r8(pb); - avio_r8(pb); - b = avio_r8(pb); - avio_r8(pb); - sc->palette[j] = - (a << 24 ) | (r << 16) | (g << 8) | (b); - } - } - } - sc->has_palette = 1; - } - } else if (st->codec->codec_type==AVMEDIA_TYPE_AUDIO) { - int bits_per_sample, flags; - uint16_t version = avio_rb16(pb); - AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE); - - st->codec->codec_id = id; - avio_rb16(pb); /* revision level */ - avio_rb32(pb); /* vendor */ - - st->codec->channels = avio_rb16(pb); /* channel count */ - av_dlog(c->fc, "audio channels %d\n", st->codec->channels); - st->codec->bits_per_coded_sample = avio_rb16(pb); /* sample size */ - - sc->audio_cid = avio_rb16(pb); - avio_rb16(pb); /* packet size = 0 */ - - st->codec->sample_rate = ((avio_rb32(pb) >> 16)); - - //Read QT version 1 fields. In version 0 these do not exist. - av_dlog(c->fc, "version =%d, isom =%d\n",version,c->isom); - if (!c->isom || - (compatible_brands && strstr(compatible_brands->value, "qt "))) { - if (version==1) { - sc->samples_per_frame = avio_rb32(pb); - avio_rb32(pb); /* bytes per packet */ - sc->bytes_per_frame = avio_rb32(pb); - avio_rb32(pb); /* bytes per sample */ - } else if (version==2) { - avio_rb32(pb); /* sizeof struct only */ - st->codec->sample_rate = av_int2double(avio_rb64(pb)); /* float 64 */ - st->codec->channels = avio_rb32(pb); - avio_rb32(pb); /* always 0x7F000000 */ - st->codec->bits_per_coded_sample = avio_rb32(pb); /* bits per channel if sound is uncompressed */ - flags = avio_rb32(pb); /* lpcm format specific flag */ - sc->bytes_per_frame = avio_rb32(pb); /* bytes per audio packet if constant */ - sc->samples_per_frame = avio_rb32(pb); /* lpcm frames per audio packet if constant */ - if (format == MKTAG('l','p','c','m')) - st->codec->codec_id = ff_mov_get_lpcm_codec_id(st->codec->bits_per_coded_sample, flags); - } - } - - switch (st->codec->codec_id) { - case AV_CODEC_ID_PCM_S8: - case AV_CODEC_ID_PCM_U8: - if (st->codec->bits_per_coded_sample == 16) - st->codec->codec_id = AV_CODEC_ID_PCM_S16BE; - break; - case AV_CODEC_ID_PCM_S16LE: - case AV_CODEC_ID_PCM_S16BE: - if (st->codec->bits_per_coded_sample == 8) - st->codec->codec_id = AV_CODEC_ID_PCM_S8; - else if (st->codec->bits_per_coded_sample == 24) - st->codec->codec_id = - st->codec->codec_id == AV_CODEC_ID_PCM_S16BE ? - AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE; - break; - /* set values for old format before stsd version 1 appeared */ - case AV_CODEC_ID_MACE3: - sc->samples_per_frame = 6; - sc->bytes_per_frame = 2*st->codec->channels; - break; - case AV_CODEC_ID_MACE6: - sc->samples_per_frame = 6; - sc->bytes_per_frame = 1*st->codec->channels; - break; - case AV_CODEC_ID_ADPCM_IMA_QT: - sc->samples_per_frame = 64; - sc->bytes_per_frame = 34*st->codec->channels; - break; - case AV_CODEC_ID_GSM: - sc->samples_per_frame = 160; - sc->bytes_per_frame = 33; - break; - default: - break; - } - - bits_per_sample = av_get_bits_per_sample(st->codec->codec_id); - if (bits_per_sample) { - st->codec->bits_per_coded_sample = bits_per_sample; - sc->sample_size = (bits_per_sample >> 3) * st->codec->channels; - } - } else if (st->codec->codec_type==AVMEDIA_TYPE_SUBTITLE){ - // ttxt stsd contains display flags, justification, background - // color, fonts, and default styles, so fake an atom to read it - MOVAtom fake_atom = { .size = size - (avio_tell(pb) - start_pos) }; - if (format != AV_RL32("mp4s")) // mp4s contains a regular esds atom - mov_read_glbl(c, pb, fake_atom); - st->codec->codec_id= id; - st->codec->width = sc->width; - st->codec->height = sc->height; - } else { - if (st->codec->codec_tag == MKTAG('t','m','c','d')) { - MOVStreamContext *tmcd_ctx = st->priv_data; - int val; - avio_rb32(pb); /* reserved */ - val = avio_rb32(pb); /* flags */ - tmcd_ctx->tmcd_flags = val; - if (val & 1) - st->codec->flags2 |= CODEC_FLAG2_DROP_FRAME_TIMECODE; - avio_rb32(pb); /* time scale */ - avio_rb32(pb); /* frame duration */ - st->codec->time_base.den = avio_r8(pb); /* number of frame */ - st->codec->time_base.num = 1; - } - /* other codec type, just skip (rtp, mp4s, ...) */ - avio_skip(pb, size - (avio_tell(pb) - start_pos)); - } - /* this will read extra atoms at the end (wave, alac, damr, avcC, SMI ...) */ - a.size = size - (avio_tell(pb) - start_pos); - if (a.size > 8) { - int ret; - if ((ret = mov_read_default(c, pb, a)) < 0) - return ret; - } else if (a.size > 0) - avio_skip(pb, a.size); - } - - if (pb->eof_reached) - return AVERROR_EOF; - - if (st->codec->codec_type==AVMEDIA_TYPE_AUDIO && st->codec->sample_rate==0 && sc->time_scale>1) - st->codec->sample_rate= sc->time_scale; - - /* special codec parameters handling */ - switch (st->codec->codec_id) { -#if CONFIG_DV_DEMUXER - case AV_CODEC_ID_DVAUDIO: - c->dv_fctx = avformat_alloc_context(); - c->dv_demux = avpriv_dv_init_demux(c->dv_fctx); - if (!c->dv_demux) { - av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n"); - return AVERROR(ENOMEM); - } - sc->dv_audio_container = 1; - st->codec->codec_id = AV_CODEC_ID_PCM_S16LE; - break; -#endif - /* no ifdef since parameters are always those */ - case AV_CODEC_ID_QCELP: - // force sample rate for qcelp when not stored in mov - if (st->codec->codec_tag != MKTAG('Q','c','l','p')) - st->codec->sample_rate = 8000; - st->codec->channels= 1; /* really needed */ - break; - case AV_CODEC_ID_AMR_NB: - st->codec->channels= 1; /* really needed */ - /* force sample rate for amr, stsd in 3gp does not store sample rate */ - st->codec->sample_rate = 8000; - break; - case AV_CODEC_ID_AMR_WB: - st->codec->channels = 1; - st->codec->sample_rate = 16000; - break; - case AV_CODEC_ID_MP2: - case AV_CODEC_ID_MP3: - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; /* force type after stsd for m1a hdlr */ - st->need_parsing = AVSTREAM_PARSE_FULL; - break; - case AV_CODEC_ID_GSM: - case AV_CODEC_ID_ADPCM_MS: - case AV_CODEC_ID_ADPCM_IMA_WAV: - case AV_CODEC_ID_ILBC: - st->codec->block_align = sc->bytes_per_frame; - break; - case AV_CODEC_ID_ALAC: - if (st->codec->extradata_size == 36) { - st->codec->channels = AV_RB8 (st->codec->extradata+21); - st->codec->sample_rate = AV_RB32(st->codec->extradata+32); - } - break; - case AV_CODEC_ID_AC3: - st->need_parsing = AVSTREAM_PARSE_FULL; - break; - case AV_CODEC_ID_MPEG1VIDEO: - st->need_parsing = AVSTREAM_PARSE_FULL; - break; - case AV_CODEC_ID_VC1: - st->need_parsing = AVSTREAM_PARSE_FULL; - break; - default: - break; - } - - return 0; -} - -static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - int entries; - - avio_r8(pb); /* version */ - avio_rb24(pb); /* flags */ - entries = avio_rb32(pb); - - return ff_mov_read_stsd_entries(c, pb, entries); -} - -static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - AVStream *st; - MOVStreamContext *sc; - unsigned int i, entries; - - if (c->fc->nb_streams < 1) - return 0; - st = c->fc->streams[c->fc->nb_streams-1]; - sc = st->priv_data; - - avio_r8(pb); /* version */ - avio_rb24(pb); /* flags */ - - entries = avio_rb32(pb); - - av_dlog(c->fc, "track[%i].stsc.entries = %i\n", c->fc->nb_streams-1, entries); - - if (!entries) - return 0; - if (entries >= UINT_MAX / sizeof(*sc->stsc_data)) - return AVERROR_INVALIDDATA; - sc->stsc_data = av_malloc(entries * sizeof(*sc->stsc_data)); - if (!sc->stsc_data) - return AVERROR(ENOMEM); - - for (i = 0; i < entries && !pb->eof_reached; i++) { - sc->stsc_data[i].first = avio_rb32(pb); - sc->stsc_data[i].count = avio_rb32(pb); - sc->stsc_data[i].id = avio_rb32(pb); - } - - sc->stsc_count = i; - - if (pb->eof_reached) - return AVERROR_EOF; - - return 0; -} - -static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - AVStream *st; - MOVStreamContext *sc; - unsigned i, entries; - - if (c->fc->nb_streams < 1) - return 0; - st = c->fc->streams[c->fc->nb_streams-1]; - sc = st->priv_data; - - avio_rb32(pb); // version + flags - - entries = avio_rb32(pb); - if (entries >= UINT_MAX / sizeof(*sc->stps_data)) - return AVERROR_INVALIDDATA; - sc->stps_data = av_malloc(entries * sizeof(*sc->stps_data)); - if (!sc->stps_data) - return AVERROR(ENOMEM); - - for (i = 0; i < entries && !pb->eof_reached; i++) { - sc->stps_data[i] = avio_rb32(pb); - //av_dlog(c->fc, "stps %d\n", sc->stps_data[i]); - } - - sc->stps_count = i; - - if (pb->eof_reached) - return AVERROR_EOF; - - return 0; -} - -static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - AVStream *st; - MOVStreamContext *sc; - unsigned int i, entries; - - if (c->fc->nb_streams < 1) - return 0; - st = c->fc->streams[c->fc->nb_streams-1]; - sc = st->priv_data; - - avio_r8(pb); /* version */ - avio_rb24(pb); /* flags */ - - entries = avio_rb32(pb); - - av_dlog(c->fc, "keyframe_count = %d\n", entries); - - if (!entries) - { - sc->keyframe_absent = 1; - return 0; - } - if (entries >= UINT_MAX / sizeof(int)) - return AVERROR_INVALIDDATA; - sc->keyframes = av_malloc(entries * sizeof(int)); - if (!sc->keyframes) - return AVERROR(ENOMEM); - - for (i = 0; i < entries && !pb->eof_reached; i++) { - sc->keyframes[i] = avio_rb32(pb); - //av_dlog(c->fc, "keyframes[]=%d\n", sc->keyframes[i]); - } - - sc->keyframe_count = i; - - if (pb->eof_reached) - return AVERROR_EOF; - - return 0; -} - -static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - AVStream *st; - MOVStreamContext *sc; - unsigned int i, entries, sample_size, field_size, num_bytes; - GetBitContext gb; - unsigned char* buf; - - if (c->fc->nb_streams < 1) - return 0; - st = c->fc->streams[c->fc->nb_streams-1]; - sc = st->priv_data; - - avio_r8(pb); /* version */ - avio_rb24(pb); /* flags */ - - if (atom.type == MKTAG('s','t','s','z')) { - sample_size = avio_rb32(pb); - if (!sc->sample_size) /* do not overwrite value computed in stsd */ - sc->sample_size = sample_size; - sc->alt_sample_size = sample_size; - field_size = 32; - } else { - sample_size = 0; - avio_rb24(pb); /* reserved */ - field_size = avio_r8(pb); - } - entries = avio_rb32(pb); - - av_dlog(c->fc, "sample_size = %d sample_count = %d\n", sc->sample_size, entries); - - sc->sample_count = entries; - if (sample_size) - return 0; - - if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) { - av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %d\n", field_size); - return AVERROR_INVALIDDATA; - } - - if (!entries) - return 0; - if (entries >= UINT_MAX / sizeof(int) || entries >= (UINT_MAX - 4) / field_size) - return AVERROR_INVALIDDATA; - sc->sample_sizes = av_malloc(entries * sizeof(int)); - if (!sc->sample_sizes) - return AVERROR(ENOMEM); - - num_bytes = (entries*field_size+4)>>3; - - buf = av_malloc(num_bytes+FF_INPUT_BUFFER_PADDING_SIZE); - if (!buf) { - av_freep(&sc->sample_sizes); - return AVERROR(ENOMEM); - } - - if (avio_read(pb, buf, num_bytes) < num_bytes) { - av_freep(&sc->sample_sizes); - av_free(buf); - return AVERROR_INVALIDDATA; - } - - init_get_bits(&gb, buf, 8*num_bytes); - - for (i = 0; i < entries && !pb->eof_reached; i++) { - sc->sample_sizes[i] = get_bits_long(&gb, field_size); - sc->data_size += sc->sample_sizes[i]; - } - - sc->sample_count = i; - - if (pb->eof_reached) - return AVERROR_EOF; - - av_free(buf); - return 0; -} - -static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - AVStream *st; - MOVStreamContext *sc; - unsigned int i, entries; - int64_t duration=0; - int64_t total_sample_count=0; - - if (c->fc->nb_streams < 1) - return 0; - st = c->fc->streams[c->fc->nb_streams-1]; - sc = st->priv_data; - - avio_r8(pb); /* version */ - avio_rb24(pb); /* flags */ - entries = avio_rb32(pb); - - av_dlog(c->fc, "track[%i].stts.entries = %i\n", - c->fc->nb_streams-1, entries); - - if (entries >= UINT_MAX / sizeof(*sc->stts_data)) - return -1; - - sc->stts_data = av_malloc(entries * sizeof(*sc->stts_data)); - if (!sc->stts_data) - return AVERROR(ENOMEM); - - for (i = 0; i < entries && !pb->eof_reached; i++) { - int sample_duration; - int sample_count; - - sample_count=avio_rb32(pb); - sample_duration = avio_rb32(pb); - /* sample_duration < 0 is invalid based on the spec */ - if (sample_duration < 0) { - av_log(c->fc, AV_LOG_ERROR, "Invalid SampleDelta in STTS %d\n", sample_duration); - sample_duration = 1; - } - sc->stts_data[i].count= sample_count; - sc->stts_data[i].duration= sample_duration; - - av_dlog(c->fc, "sample_count=%d, sample_duration=%d\n", - sample_count, sample_duration); - - duration+=(int64_t)sample_duration*sample_count; - total_sample_count+=sample_count; - } - - sc->stts_count = i; - - if (pb->eof_reached) - return AVERROR_EOF; - - st->nb_frames= total_sample_count; - if (duration) - st->duration= duration; - sc->track_end = duration; - return 0; -} - -static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - AVStream *st; - MOVStreamContext *sc; - unsigned int i, entries; - - if (c->fc->nb_streams < 1) - return 0; - st = c->fc->streams[c->fc->nb_streams-1]; - sc = st->priv_data; - - avio_r8(pb); /* version */ - avio_rb24(pb); /* flags */ - entries = avio_rb32(pb); - - av_dlog(c->fc, "track[%i].ctts.entries = %i\n", c->fc->nb_streams-1, entries); - - if (!entries) - return 0; - if (entries >= UINT_MAX / sizeof(*sc->ctts_data)) - return AVERROR_INVALIDDATA; - sc->ctts_data = av_malloc(entries * sizeof(*sc->ctts_data)); - if (!sc->ctts_data) - return AVERROR(ENOMEM); - - for (i = 0; i < entries && !pb->eof_reached; i++) { - int count =avio_rb32(pb); - int duration =avio_rb32(pb); - - sc->ctts_data[i].count = count; - sc->ctts_data[i].duration= duration; - - av_dlog(c->fc, "count=%d, duration=%d\n", - count, duration); - - if (FFABS(duration) > (1<<28) && i+2fc, AV_LOG_WARNING, "CTTS invalid\n"); - av_freep(&sc->ctts_data); - sc->ctts_count = 0; - return 0; - } - - if (duration < 0 && i+2dts_shift = FFMAX(sc->dts_shift, -duration); - } - - sc->ctts_count = i; - - if (pb->eof_reached) - return AVERROR_EOF; - - av_dlog(c->fc, "dts shift %d\n", sc->dts_shift); - - return 0; -} - -static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - AVStream *st; - MOVStreamContext *sc; - unsigned int i, entries; - uint8_t version; - uint32_t grouping_type; - - if (c->fc->nb_streams < 1) - return 0; - st = c->fc->streams[c->fc->nb_streams-1]; - sc = st->priv_data; - - version = avio_r8(pb); /* version */ - avio_rb24(pb); /* flags */ - grouping_type = avio_rl32(pb); - if (grouping_type != MKTAG( 'r','a','p',' ')) - return 0; /* only support 'rap ' grouping */ - if (version == 1) - avio_rb32(pb); /* grouping_type_parameter */ - - entries = avio_rb32(pb); - if (!entries) - return 0; - if (entries >= UINT_MAX / sizeof(*sc->rap_group)) - return AVERROR_INVALIDDATA; - sc->rap_group = av_malloc(entries * sizeof(*sc->rap_group)); - if (!sc->rap_group) - return AVERROR(ENOMEM); - - for (i = 0; i < entries && !pb->eof_reached; i++) { - sc->rap_group[i].count = avio_rb32(pb); /* sample_count */ - sc->rap_group[i].index = avio_rb32(pb); /* group_description_index */ - } - - sc->rap_group_count = i; - - return pb->eof_reached ? AVERROR_EOF : 0; -} - -static void mov_build_index(MOVContext *mov, AVStream *st) -{ - MOVStreamContext *sc = st->priv_data; - int64_t current_offset; - int64_t current_dts = 0; - unsigned int stts_index = 0; - unsigned int stsc_index = 0; - unsigned int stss_index = 0; - unsigned int stps_index = 0; - unsigned int i, j; - uint64_t stream_size = 0; - AVIndexEntry *mem; - - /* adjust first dts according to edit list */ - if ((sc->empty_duration || sc->start_time) && mov->time_scale > 0) { - if (sc->empty_duration) - sc->empty_duration = av_rescale(sc->empty_duration, sc->time_scale, mov->time_scale); - sc->time_offset = sc->start_time - sc->empty_duration; - current_dts = -sc->time_offset; - if (sc->ctts_count>0 && sc->stts_count>0 && - sc->ctts_data[0].duration / FFMAX(sc->stts_data[0].duration, 1) > 16) { - /* more than 16 frames delay, dts are likely wrong - this happens with files created by iMovie */ - sc->wrong_dts = 1; - st->codec->has_b_frames = 1; - } - } - - /* only use old uncompressed audio chunk demuxing when stts specifies it */ - if (!(st->codec->codec_type == AVMEDIA_TYPE_AUDIO && - sc->stts_count == 1 && sc->stts_data[0].duration == 1)) { - unsigned int current_sample = 0; - unsigned int stts_sample = 0; - unsigned int sample_size; - unsigned int distance = 0; - unsigned int rap_group_index = 0; - unsigned int rap_group_sample = 0; - int rap_group_present = sc->rap_group_count && sc->rap_group; - int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0); - - current_dts -= sc->dts_shift; - - if (!sc->sample_count || st->nb_index_entries) - return; - if (sc->sample_count >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries) - return; - mem = av_realloc(st->index_entries, (st->nb_index_entries + sc->sample_count) * sizeof(*st->index_entries)); - if (!mem) - return; - st->index_entries = mem; - st->index_entries_allocated_size = (st->nb_index_entries + sc->sample_count) * sizeof(*st->index_entries); - - for (i = 0; i < sc->chunk_count; i++) { - current_offset = sc->chunk_offsets[i]; - while (stsc_index + 1 < sc->stsc_count && - i + 1 == sc->stsc_data[stsc_index + 1].first) - stsc_index++; - for (j = 0; j < sc->stsc_data[stsc_index].count; j++) { - int keyframe = 0; - if (current_sample >= sc->sample_count) { - av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n"); - return; - } - - if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) { - keyframe = 1; - if (stss_index + 1 < sc->keyframe_count) - stss_index++; - } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) { - keyframe = 1; - if (stps_index + 1 < sc->stps_count) - stps_index++; - } - if (rap_group_present && rap_group_index < sc->rap_group_count) { - if (sc->rap_group[rap_group_index].index > 0) - keyframe = 1; - if (++rap_group_sample == sc->rap_group[rap_group_index].count) { - rap_group_sample = 0; - rap_group_index++; - } - } - if (keyframe) - distance = 0; - sample_size = sc->alt_sample_size > 0 ? sc->alt_sample_size : sc->sample_sizes[current_sample]; - if (sc->pseudo_stream_id == -1 || - sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) { - AVIndexEntry *e = &st->index_entries[st->nb_index_entries++]; - e->pos = current_offset; - e->timestamp = current_dts; - e->size = sample_size; - e->min_distance = distance; - e->flags = keyframe ? AVINDEX_KEYFRAME : 0; - av_dlog(mov->fc, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", " - "size %d, distance %d, keyframe %d\n", st->index, current_sample, - current_offset, current_dts, sample_size, distance, keyframe); - } - - current_offset += sample_size; - stream_size += sample_size; - current_dts += sc->stts_data[stts_index].duration; - distance++; - stts_sample++; - current_sample++; - if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) { - stts_sample = 0; - stts_index++; - } - } - } - if (st->duration > 0) - st->codec->bit_rate = stream_size*8*sc->time_scale/st->duration; - } else { - unsigned chunk_samples, total = 0; - - // compute total chunk count - for (i = 0; i < sc->stsc_count; i++) { - unsigned count, chunk_count; - - chunk_samples = sc->stsc_data[i].count; - if (i != sc->stsc_count - 1 && - sc->samples_per_frame && chunk_samples % sc->samples_per_frame) { - av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n"); - return; - } - - if (sc->samples_per_frame >= 160) { // gsm - count = chunk_samples / sc->samples_per_frame; - } else if (sc->samples_per_frame > 1) { - unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame; - count = (chunk_samples+samples-1) / samples; - } else { - count = (chunk_samples+1023) / 1024; - } - - if (i < sc->stsc_count - 1) - chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first; - else - chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1); - total += chunk_count * count; - } - - av_dlog(mov->fc, "chunk count %d\n", total); - if (total >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries) - return; - mem = av_realloc(st->index_entries, (st->nb_index_entries + total) * sizeof(*st->index_entries)); - if (!mem) - return; - st->index_entries = mem; - st->index_entries_allocated_size = (st->nb_index_entries + total) * sizeof(*st->index_entries); - - // populate index - for (i = 0; i < sc->chunk_count; i++) { - current_offset = sc->chunk_offsets[i]; - if (stsc_index + 1 < sc->stsc_count && - i + 1 == sc->stsc_data[stsc_index + 1].first) - stsc_index++; - chunk_samples = sc->stsc_data[stsc_index].count; - - while (chunk_samples > 0) { - AVIndexEntry *e; - unsigned size, samples; - - if (sc->samples_per_frame >= 160) { // gsm - samples = sc->samples_per_frame; - size = sc->bytes_per_frame; - } else { - if (sc->samples_per_frame > 1) { - samples = FFMIN((1024 / sc->samples_per_frame)* - sc->samples_per_frame, chunk_samples); - size = (samples / sc->samples_per_frame) * sc->bytes_per_frame; - } else { - samples = FFMIN(1024, chunk_samples); - size = samples * sc->sample_size; - } - } - - if (st->nb_index_entries >= total) { - av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %d\n", total); - return; - } - e = &st->index_entries[st->nb_index_entries++]; - e->pos = current_offset; - e->timestamp = current_dts; - e->size = size; - e->min_distance = 0; - e->flags = AVINDEX_KEYFRAME; - av_dlog(mov->fc, "AVIndex stream %d, chunk %d, offset %"PRIx64", dts %"PRId64", " - "size %d, duration %d\n", st->index, i, current_offset, current_dts, - size, samples); - - current_offset += size; - current_dts += samples; - chunk_samples -= samples; - } - } - } -} - -static int mov_open_dref(AVIOContext **pb, const char *src, MOVDref *ref, - AVIOInterruptCB *int_cb, int use_absolute_path, AVFormatContext *fc) -{ - /* try relative path, we do not try the absolute because it can leak information about our - system to an attacker */ - if (ref->nlvl_to > 0 && ref->nlvl_from > 0) { - char filename[1024]; - const char *src_path; - int i, l; - - /* find a source dir */ - src_path = strrchr(src, '/'); - if (src_path) - src_path++; - else - src_path = src; - - /* find a next level down to target */ - for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--) - if (ref->path[l] == '/') { - if (i == ref->nlvl_to - 1) - break; - else - i++; - } - - /* compose filename if next level down to target was found */ - if (i == ref->nlvl_to - 1 && src_path - src < sizeof(filename)) { - memcpy(filename, src, src_path - src); - filename[src_path - src] = 0; - - for (i = 1; i < ref->nlvl_from; i++) - av_strlcat(filename, "../", 1024); - - av_strlcat(filename, ref->path + l + 1, 1024); - - if (!avio_open2(pb, filename, AVIO_FLAG_READ, int_cb, NULL)) - return 0; - } - } else if (use_absolute_path) { - av_log(fc, AV_LOG_WARNING, "Using absolute path on user request, " - "this is a possible security issue\n"); - if (!avio_open2(pb, ref->path, AVIO_FLAG_READ, int_cb, NULL)) - return 0; - } - - return AVERROR(ENOENT); -} - -static void fix_timescale(MOVContext *c, MOVStreamContext *sc) -{ - if (sc->time_scale <= 0) { - av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex); - sc->time_scale = c->time_scale; - if (sc->time_scale <= 0) - sc->time_scale = 1; - } -} - -static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - AVStream *st; - MOVStreamContext *sc; - int ret; - - st = avformat_new_stream(c->fc, NULL); - if (!st) return AVERROR(ENOMEM); - st->id = c->fc->nb_streams; - sc = av_mallocz(sizeof(MOVStreamContext)); - if (!sc) return AVERROR(ENOMEM); - - st->priv_data = sc; - st->codec->codec_type = AVMEDIA_TYPE_DATA; - sc->ffindex = st->index; - - if ((ret = mov_read_default(c, pb, atom)) < 0) - return ret; - - /* sanity checks */ - if (sc->chunk_count && (!sc->stts_count || !sc->stsc_count || - (!sc->sample_size && !sc->sample_count))) { - av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n", - st->index); - return 0; - } - - fix_timescale(c, sc); - - avpriv_set_pts_info(st, 64, 1, sc->time_scale); - - mov_build_index(c, st); - - if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) { - MOVDref *dref = &sc->drefs[sc->dref_id - 1]; - if (mov_open_dref(&sc->pb, c->fc->filename, dref, &c->fc->interrupt_callback, - c->use_absolute_path, c->fc) < 0) - av_log(c->fc, AV_LOG_ERROR, - "stream %d, error opening alias: path='%s', dir='%s', " - "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n", - st->index, dref->path, dref->dir, dref->filename, - dref->volume, dref->nlvl_from, dref->nlvl_to); - } else { - sc->pb = c->fc->pb; - sc->pb_is_copied = 1; - } - - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { - if (!st->sample_aspect_ratio.num && - (st->codec->width != sc->width || st->codec->height != sc->height)) { - st->sample_aspect_ratio = av_d2q(((double)st->codec->height * sc->width) / - ((double)st->codec->width * sc->height), INT_MAX); - } - - if (st->duration > 0) - av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den, - sc->time_scale*st->nb_frames, st->duration, INT_MAX); - -#if FF_API_R_FRAME_RATE - if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1)) - av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den, - sc->time_scale, sc->stts_data[0].duration, INT_MAX); -#endif - } - - // done for ai5q, ai52, ai55, ai1q, ai12 and ai15. - if (!st->codec->extradata_size && st->codec->codec_id == AV_CODEC_ID_H264 && - st->codec->codec_tag != MKTAG('a', 'v', 'c', '1')) { - ff_generate_avci_extradata(st); - } - - switch (st->codec->codec_id) { -#if CONFIG_H261_DECODER - case AV_CODEC_ID_H261: -#endif -#if CONFIG_H263_DECODER - case AV_CODEC_ID_H263: -#endif -#if CONFIG_MPEG4_DECODER - case AV_CODEC_ID_MPEG4: -#endif - st->codec->width = 0; /* let decoder init width/height */ - st->codec->height= 0; - break; - } - - /* Do not need those anymore. */ - av_freep(&sc->chunk_offsets); - av_freep(&sc->stsc_data); - av_freep(&sc->sample_sizes); - av_freep(&sc->keyframes); - av_freep(&sc->stts_data); - av_freep(&sc->stps_data); - av_freep(&sc->rap_group); - - return 0; -} - -static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - int ret; - c->itunes_metadata = 1; - ret = mov_read_default(c, pb, atom); - c->itunes_metadata = 0; - return ret; -} - -static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - while (atom.size > 8) { - uint32_t tag = avio_rl32(pb); - atom.size -= 4; - if (tag == MKTAG('h','d','l','r')) { - avio_seek(pb, -8, SEEK_CUR); - atom.size += 8; - return mov_read_default(c, pb, atom); - } - } - return 0; -} - -static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - int i; - int width; - int height; - int64_t disp_transform[2]; - int display_matrix[3][2]; - AVStream *st; - MOVStreamContext *sc; - int version; - - if (c->fc->nb_streams < 1) - return 0; - st = c->fc->streams[c->fc->nb_streams-1]; - sc = st->priv_data; - - version = avio_r8(pb); - avio_rb24(pb); /* flags */ - /* - MOV_TRACK_ENABLED 0x0001 - MOV_TRACK_IN_MOVIE 0x0002 - MOV_TRACK_IN_PREVIEW 0x0004 - MOV_TRACK_IN_POSTER 0x0008 - */ - - if (version == 1) { - avio_rb64(pb); - avio_rb64(pb); - } else { - avio_rb32(pb); /* creation time */ - avio_rb32(pb); /* modification time */ - } - st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/ - avio_rb32(pb); /* reserved */ - - /* highlevel (considering edits) duration in movie timebase */ - (version == 1) ? avio_rb64(pb) : avio_rb32(pb); - avio_rb32(pb); /* reserved */ - avio_rb32(pb); /* reserved */ - - avio_rb16(pb); /* layer */ - avio_rb16(pb); /* alternate group */ - avio_rb16(pb); /* volume */ - avio_rb16(pb); /* reserved */ - - //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2) - // they're kept in fixed point format through all calculations - // ignore u,v,z b/c we don't need the scale factor to calc aspect ratio - for (i = 0; i < 3; i++) { - display_matrix[i][0] = avio_rb32(pb); // 16.16 fixed point - display_matrix[i][1] = avio_rb32(pb); // 16.16 fixed point - avio_rb32(pb); // 2.30 fixed point (not used) - } - - width = avio_rb32(pb); // 16.16 fixed point track width - height = avio_rb32(pb); // 16.16 fixed point track height - sc->width = width >> 16; - sc->height = height >> 16; - - //Assign clockwise rotate values based on transform matrix so that - //we can compensate for iPhone orientation during capture. - - if (display_matrix[1][0] == -65536 && display_matrix[0][1] == 65536) { - av_dict_set(&st->metadata, "rotate", "90", 0); - } - - if (display_matrix[0][0] == -65536 && display_matrix[1][1] == -65536) { - av_dict_set(&st->metadata, "rotate", "180", 0); - } - - if (display_matrix[1][0] == 65536 && display_matrix[0][1] == -65536) { - av_dict_set(&st->metadata, "rotate", "270", 0); - } - - // transform the display width/height according to the matrix - // skip this if the display matrix is the default identity matrix - // or if it is rotating the picture, ex iPhone 3GS - // to keep the same scale, use [width height 1<<16] - if (width && height && - ((display_matrix[0][0] != 65536 || - display_matrix[1][1] != 65536) && - !display_matrix[0][1] && - !display_matrix[1][0] && - !display_matrix[2][0] && !display_matrix[2][1])) { - for (i = 0; i < 2; i++) - disp_transform[i] = - (int64_t) width * display_matrix[0][i] + - (int64_t) height * display_matrix[1][i] + - ((int64_t) display_matrix[2][i] << 16); - - //sample aspect ratio is new width/height divided by old width/height - st->sample_aspect_ratio = av_d2q( - ((double) disp_transform[0] * height) / - ((double) disp_transform[1] * width), INT_MAX); - } - return 0; -} - -static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - MOVFragment *frag = &c->fragment; - MOVTrackExt *trex = NULL; - int flags, track_id, i; - - avio_r8(pb); /* version */ - flags = avio_rb24(pb); - - track_id = avio_rb32(pb); - if (!track_id) - return AVERROR_INVALIDDATA; - frag->track_id = track_id; - for (i = 0; i < c->trex_count; i++) - if (c->trex_data[i].track_id == frag->track_id) { - trex = &c->trex_data[i]; - break; - } - if (!trex) { - av_log(c->fc, AV_LOG_ERROR, "could not find corresponding trex\n"); - return AVERROR_INVALIDDATA; - } - - 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 & 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; -} - -static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - c->chapter_track = avio_rb32(pb); - return 0; -} - -static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - MOVTrackExt *trex; - - if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data)) - return AVERROR_INVALIDDATA; - trex = av_realloc(c->trex_data, (c->trex_count+1)*sizeof(*c->trex_data)); - if (!trex) - return AVERROR(ENOMEM); - - c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used. - - c->trex_data = trex; - trex = &c->trex_data[c->trex_count++]; - avio_r8(pb); /* version */ - avio_rb24(pb); /* flags */ - trex->track_id = avio_rb32(pb); - trex->stsd_id = avio_rb32(pb); - trex->duration = avio_rb32(pb); - trex->size = avio_rb32(pb); - trex->flags = avio_rb32(pb); - return 0; -} - -static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - MOVFragment *frag = &c->fragment; - AVStream *st = NULL; - MOVStreamContext *sc; - MOVStts *ctts_data; - uint64_t offset; - int64_t dts; - int data_offset = 0; - unsigned entries, first_sample_flags = frag->flags; - int flags, distance, i, found_keyframe = 0; - - for (i = 0; i < c->fc->nb_streams; i++) { - if (c->fc->streams[i]->id == frag->track_id) { - st = c->fc->streams[i]; - break; - } - } - if (!st) { - av_log(c->fc, AV_LOG_ERROR, "could not find corresponding track id %d\n", frag->track_id); - return AVERROR_INVALIDDATA; - } - sc = st->priv_data; - if (sc->pseudo_stream_id+1 != frag->stsd_id) - return 0; - avio_r8(pb); /* version */ - flags = avio_rb24(pb); - entries = avio_rb32(pb); - av_dlog(c->fc, "flags 0x%x entries %d\n", flags, entries); - - /* Always assume the presence of composition time offsets. - * Without this assumption, for instance, we cannot deal with a track in fragmented movies that meet the following. - * 1) in the initial movie, there are no samples. - * 2) in the first movie fragment, there is only one sample without composition time offset. - * 3) in the subsequent movie fragments, there are samples with composition time offset. */ - if (!sc->ctts_count && sc->sample_count) - { - /* Complement ctts table if moov atom doesn't have ctts atom. */ - ctts_data = av_malloc(sizeof(*sc->ctts_data)); - if (!ctts_data) - return AVERROR(ENOMEM); - sc->ctts_data = ctts_data; - sc->ctts_data[sc->ctts_count].count = sc->sample_count; - sc->ctts_data[sc->ctts_count].duration = 0; - sc->ctts_count++; - } - if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data)) - return AVERROR_INVALIDDATA; - ctts_data = av_realloc(sc->ctts_data, - (entries+sc->ctts_count)*sizeof(*sc->ctts_data)); - if (!ctts_data) - return AVERROR(ENOMEM); - sc->ctts_data = ctts_data; - - 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; - av_dlog(c->fc, "first sample flags 0x%x\n", first_sample_flags); - for (i = 0; i < entries && !pb->eof_reached; i++) { - unsigned sample_size = frag->size; - int sample_flags = i ? frag->flags : first_sample_flags; - unsigned sample_duration = frag->duration; - int keyframe = 0; - - 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 & MOV_TRUN_SAMPLE_CTS) ? - avio_rb32(pb) : 0; - sc->ctts_count++; - if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) - keyframe = 1; - else if (!found_keyframe) - keyframe = found_keyframe = - !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC | - MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES)); - if (keyframe) - distance = 0; - av_add_index_entry(st, offset, dts, sample_size, distance, - keyframe ? AVINDEX_KEYFRAME : 0); - av_dlog(c->fc, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", " - "size %d, distance %d, keyframe %d\n", st->index, sc->sample_count+i, - offset, dts, sample_size, distance, keyframe); - distance++; - dts += sample_duration; - offset += sample_size; - sc->data_size += sample_size; - } - - if (pb->eof_reached) - return AVERROR_EOF; - - frag->moof_offset = offset; - st->duration = sc->track_end = dts + sc->time_offset; - return 0; -} - -/* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */ -/* like the files created with Adobe Premiere 5.0, for samples see */ -/* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */ -static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - int err; - - if (atom.size < 8) - return 0; /* continue */ - if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */ - avio_skip(pb, atom.size - 4); - return 0; - } - atom.type = avio_rl32(pb); - atom.size -= 8; - if (atom.type != MKTAG('m','d','a','t')) { - avio_skip(pb, atom.size); - return 0; - } - err = mov_read_mdat(c, pb, atom); - return err; -} - -static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ -#if CONFIG_ZLIB - AVIOContext ctx; - uint8_t *cmov_data; - uint8_t *moov_data; /* uncompressed data */ - long cmov_len, moov_len; - int ret = -1; - - avio_rb32(pb); /* dcom atom */ - if (avio_rl32(pb) != MKTAG('d','c','o','m')) - return AVERROR_INVALIDDATA; - if (avio_rl32(pb) != MKTAG('z','l','i','b')) { - av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n"); - return AVERROR_INVALIDDATA; - } - avio_rb32(pb); /* cmvd atom */ - if (avio_rl32(pb) != MKTAG('c','m','v','d')) - return AVERROR_INVALIDDATA; - moov_len = avio_rb32(pb); /* uncompressed size */ - cmov_len = atom.size - 6 * 4; - - cmov_data = av_malloc(cmov_len); - if (!cmov_data) - return AVERROR(ENOMEM); - moov_data = av_malloc(moov_len); - if (!moov_data) { - av_free(cmov_data); - return AVERROR(ENOMEM); - } - avio_read(pb, cmov_data, cmov_len); - if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK) - goto free_and_return; - if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0) - goto free_and_return; - atom.type = MKTAG('m','o','o','v'); - atom.size = moov_len; - ret = mov_read_default(c, &ctx, atom); -free_and_return: - av_free(moov_data); - av_free(cmov_data); - return ret; -#else - av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n"); - return AVERROR(ENOSYS); -#endif -} - -/* edit list atom */ -static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - MOVStreamContext *sc; - int i, edit_count, version, edit_start_index = 0; - int unsupported = 0; - - if (c->fc->nb_streams < 1 || c->ignore_editlist) - return 0; - sc = c->fc->streams[c->fc->nb_streams-1]->priv_data; - - version = avio_r8(pb); /* version */ - avio_rb24(pb); /* flags */ - edit_count = avio_rb32(pb); /* entries */ - - if ((uint64_t)edit_count*12+8 > atom.size) - return AVERROR_INVALIDDATA; - - av_dlog(c->fc, "track[%i].edit_count = %i\n", c->fc->nb_streams-1, edit_count); - for (i=0; iempty_duration = duration; - edit_start_index = 1; - } else if (i == edit_start_index && time >= 0) - sc->start_time = time; - else - unsupported = 1; - - av_dlog(c->fc, "duration=%"PRId64" time=%"PRId64" rate=%f\n", - duration, time, rate / 65536.0); - } - - if (unsupported) - av_log(c->fc, AV_LOG_WARNING, "multiple edit list entries, " - "a/v desync might occur, patch welcome\n"); - - return 0; -} - -static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - MOVStreamContext *sc; - - if (c->fc->nb_streams < 1) - return AVERROR_INVALIDDATA; - sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data; - sc->timecode_track = avio_rb32(pb); - return 0; -} - -static const MOVParseTableEntry mov_default_parse_table[] = { -{ MKTAG('A','C','L','R'), mov_read_avid }, -{ MKTAG('A','P','R','G'), mov_read_avid }, -{ MKTAG('A','A','L','P'), mov_read_avid }, -{ MKTAG('A','R','E','S'), mov_read_avid }, -{ MKTAG('a','v','s','s'), mov_read_avss }, -{ MKTAG('c','h','p','l'), mov_read_chpl }, -{ MKTAG('c','o','6','4'), mov_read_stco }, -{ MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */ -{ MKTAG('d','i','n','f'), mov_read_default }, -{ MKTAG('d','r','e','f'), mov_read_dref }, -{ MKTAG('e','d','t','s'), mov_read_default }, -{ MKTAG('e','l','s','t'), mov_read_elst }, -{ MKTAG('e','n','d','a'), mov_read_enda }, -{ MKTAG('f','i','e','l'), mov_read_fiel }, -{ MKTAG('f','t','y','p'), mov_read_ftyp }, -{ MKTAG('g','l','b','l'), mov_read_glbl }, -{ MKTAG('h','d','l','r'), mov_read_hdlr }, -{ MKTAG('i','l','s','t'), mov_read_ilst }, -{ MKTAG('j','p','2','h'), mov_read_jp2h }, -{ MKTAG('m','d','a','t'), mov_read_mdat }, -{ MKTAG('m','d','h','d'), mov_read_mdhd }, -{ MKTAG('m','d','i','a'), mov_read_default }, -{ MKTAG('m','e','t','a'), mov_read_meta }, -{ MKTAG('m','i','n','f'), mov_read_default }, -{ MKTAG('m','o','o','f'), mov_read_moof }, -{ MKTAG('m','o','o','v'), mov_read_moov }, -{ MKTAG('m','v','e','x'), mov_read_default }, -{ MKTAG('m','v','h','d'), mov_read_mvhd }, -{ MKTAG('S','M','I',' '), mov_read_svq3 }, -{ MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */ -{ MKTAG('a','v','c','C'), mov_read_glbl }, -{ MKTAG('p','a','s','p'), mov_read_pasp }, -{ MKTAG('s','t','b','l'), mov_read_default }, -{ MKTAG('s','t','c','o'), mov_read_stco }, -{ MKTAG('s','t','p','s'), mov_read_stps }, -{ MKTAG('s','t','r','f'), mov_read_strf }, -{ MKTAG('s','t','s','c'), mov_read_stsc }, -{ MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */ -{ MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */ -{ MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */ -{ MKTAG('s','t','t','s'), mov_read_stts }, -{ MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */ -{ MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */ -{ MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */ -{ MKTAG('t','r','a','k'), mov_read_trak }, -{ MKTAG('t','r','a','f'), mov_read_default }, -{ MKTAG('t','r','e','f'), mov_read_default }, -{ MKTAG('t','m','c','d'), mov_read_tmcd }, -{ MKTAG('c','h','a','p'), mov_read_chap }, -{ MKTAG('t','r','e','x'), mov_read_trex }, -{ MKTAG('t','r','u','n'), mov_read_trun }, -{ MKTAG('u','d','t','a'), mov_read_default }, -{ MKTAG('w','a','v','e'), mov_read_wave }, -{ MKTAG('e','s','d','s'), mov_read_esds }, -{ MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */ -{ MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */ -{ MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */ -{ MKTAG('w','f','e','x'), mov_read_wfex }, -{ MKTAG('c','m','o','v'), mov_read_cmov }, -{ MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */ -{ MKTAG('d','v','c','1'), mov_read_dvc1 }, -{ MKTAG('s','b','g','p'), mov_read_sbgp }, -{ 0, NULL } -}; - -static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom) -{ - int64_t total_size = 0; - MOVAtom a; - int i; - - if (atom.size < 0) - atom.size = INT64_MAX; - while (total_size + 8 <= atom.size && !url_feof(pb)) { - int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL; - a.size = atom.size; - a.type=0; - if (atom.size >= 8) { - a.size = avio_rb32(pb); - a.type = avio_rl32(pb); - if (atom.type != MKTAG('r','o','o','t') && - atom.type != MKTAG('m','o','o','v')) - { - if (a.type == MKTAG('t','r','a','k') || a.type == MKTAG('m','d','a','t')) - { - av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n"); - avio_skip(pb, -8); - return 0; - } - } - total_size += 8; - if (a.size == 1) { /* 64 bit extended size */ - a.size = avio_rb64(pb) - 8; - total_size += 8; - } - } - av_dlog(c->fc, "type: %08x '%.4s' parent:'%.4s' sz: %"PRId64" %"PRId64" %"PRId64"\n", - a.type, (char*)&a.type, (char*)&atom.type, a.size, total_size, atom.size); - if (a.size == 0) { - a.size = atom.size - total_size + 8; - } - a.size -= 8; - if (a.size < 0) - break; - a.size = FFMIN(a.size, atom.size - total_size); - - for (i = 0; mov_default_parse_table[i].type; i++) - if (mov_default_parse_table[i].type == a.type) { - parse = mov_default_parse_table[i].parse; - break; - } - - // container is user data - if (!parse && (atom.type == MKTAG('u','d','t','a') || - atom.type == MKTAG('i','l','s','t'))) - parse = mov_read_udta_string; - - if (!parse) { /* skip leaf atoms data */ - avio_skip(pb, a.size); - } else { - int64_t start_pos = avio_tell(pb); - int64_t left; - int err = parse(c, pb, a); - if (err < 0) - return err; - if (c->found_moov && c->found_mdat && - ((!pb->seekable || c->fc->flags & AVFMT_FLAG_IGNIDX) || - start_pos + a.size == avio_size(pb))) { - if (!pb->seekable || c->fc->flags & AVFMT_FLAG_IGNIDX) - c->next_root_atom = start_pos + a.size; - return 0; - } - left = a.size - avio_tell(pb) + start_pos; - if (left > 0) /* skip garbage at atom end */ - avio_skip(pb, left); - else if(left < 0) { - av_log(c->fc, AV_LOG_DEBUG, "undoing overread of %"PRId64" in '%.4s'\n", -left, (char*)&a.type); - avio_seek(pb, left, SEEK_CUR); - } - } - - total_size += a.size; - } - - if (total_size < atom.size && atom.size < 0x7ffff) - avio_skip(pb, atom.size - total_size); - - return 0; -} - -static int mov_probe(AVProbeData *p) -{ - int64_t offset; - uint32_t tag; - int score = 0; - int moov_offset = -1; - - /* check file header */ - offset = 0; - for (;;) { - /* ignore invalid offset */ - if ((offset + 8) > (unsigned int)p->buf_size) - break; - tag = AV_RL32(p->buf + offset + 4); - switch(tag) { - /* check for obvious tags */ - case MKTAG('m','o','o','v'): - moov_offset = offset + 4; - case MKTAG('j','P',' ',' '): /* jpeg 2000 signature */ - case MKTAG('m','d','a','t'): - case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */ - case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */ - case MKTAG('f','t','y','p'): - if (AV_RB32(p->buf+offset) < 8 && - (AV_RB32(p->buf+offset) != 1 || - offset + 12 > (unsigned int)p->buf_size || - AV_RB64(p->buf+offset + 8) == 0)) { - score = FFMAX(score, AVPROBE_SCORE_MAX - 50); - } else { - score = AVPROBE_SCORE_MAX; - } - offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset; - break; - /* those are more common words, so rate then a bit less */ - case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */ - case MKTAG('w','i','d','e'): - case MKTAG('f','r','e','e'): - case MKTAG('j','u','n','k'): - case MKTAG('p','i','c','t'): - score = FFMAX(score, AVPROBE_SCORE_MAX - 5); - offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset; - break; - case MKTAG(0x82,0x82,0x7f,0x7d): - case MKTAG('s','k','i','p'): - case MKTAG('u','u','i','d'): - case MKTAG('p','r','f','l'): - /* if we only find those cause probedata is too small at least rate them */ - score = FFMAX(score, AVPROBE_SCORE_MAX - 50); - offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset; - break; - default: - offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset; - } - } - if(score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) { - /* moov atom in the header - we should make sure that this is not a - * MOV-packed MPEG-PS */ - offset = moov_offset; - - while(offset < (p->buf_size - 16)){ /* Sufficient space */ - /* We found an actual hdlr atom */ - if(AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') && - AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') && - AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')){ - av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n"); - /* We found a media handler reference atom describing an - * MPEG-PS-in-MOV, return a - * low score to force expanding the probe window until - * mpegps_probe finds what it needs */ - return 5; - }else - /* Keep looking */ - offset+=2; - } - } - - return score; -} - -// must be done after parsing all trak because there's no order requirement -static void mov_read_chapters(AVFormatContext *s) -{ - MOVContext *mov = s->priv_data; - AVStream *st = NULL; - MOVStreamContext *sc; - int64_t cur_pos; - int i; - - for (i = 0; i < s->nb_streams; i++) - if (s->streams[i]->id == mov->chapter_track) { - st = s->streams[i]; - break; - } - if (!st) { - av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n"); - return; - } - - st->discard = AVDISCARD_ALL; - sc = st->priv_data; - cur_pos = avio_tell(sc->pb); - - for (i = 0; i < st->nb_index_entries; i++) { - AVIndexEntry *sample = &st->index_entries[i]; - int64_t end = i+1 < st->nb_index_entries ? st->index_entries[i+1].timestamp : st->duration; - uint8_t *title; - uint16_t ch; - int len, title_len; - - if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) { - av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i); - goto finish; - } - - // the first two bytes are the length of the title - len = avio_rb16(sc->pb); - if (len > sample->size-2) - continue; - title_len = 2*len + 1; - if (!(title = av_mallocz(title_len))) - goto finish; - - // The samples could theoretically be in any encoding if there's an encd - // atom following, but in practice are only utf-8 or utf-16, distinguished - // instead by the presence of a BOM - if (!len) { - title[0] = 0; - } else { - ch = avio_rb16(sc->pb); - if (ch == 0xfeff) - avio_get_str16be(sc->pb, len, title, title_len); - else if (ch == 0xfffe) - avio_get_str16le(sc->pb, len, title, title_len); - else { - AV_WB16(title, ch); - if (len == 1 || len == 2) - title[len] = 0; - else - avio_get_str(sc->pb, INT_MAX, title + 2, len - 1); - } - } - - avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title); - av_freep(&title); - } -finish: - avio_seek(sc->pb, cur_pos, SEEK_SET); -} - -static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st, - uint32_t value, int flags) -{ - AVTimecode tc; - char buf[AV_TIMECODE_STR_SIZE]; - AVRational rate = {st->codec->time_base.den, - st->codec->time_base.num}; - int ret = av_timecode_init(&tc, rate, flags, 0, s); - if (ret < 0) - return ret; - av_dict_set(&st->metadata, "timecode", - av_timecode_make_string(&tc, buf, value), 0); - return 0; -} - -static int mov_read_timecode_track(AVFormatContext *s, AVStream *st) -{ - MOVStreamContext *sc = st->priv_data; - int flags = 0; - int64_t cur_pos = avio_tell(sc->pb); - uint32_t value; - - if (!st->nb_index_entries) - return -1; - - avio_seek(sc->pb, st->index_entries->pos, SEEK_SET); - value = avio_rb32(s->pb); - - if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME; - if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX; - if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE; - - /* Assume Counter flag is set to 1 in tmcd track (even though it is likely - * not the case) and thus assume "frame number format" instead of QT one. - * No sample with tmcd track can be found with a QT timecode at the moment, - * despite what the tmcd track "suggests" (Counter flag set to 0 means QT - * format). */ - parse_timecode_in_framenum_format(s, st, value, flags); - - avio_seek(sc->pb, cur_pos, SEEK_SET); - return 0; -} - -static int mov_read_close(AVFormatContext *s) -{ - MOVContext *mov = s->priv_data; - int i, j; - - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - MOVStreamContext *sc = st->priv_data; - - av_freep(&sc->ctts_data); - for (j = 0; j < sc->drefs_count; j++) { - av_freep(&sc->drefs[j].path); - av_freep(&sc->drefs[j].dir); - } - av_freep(&sc->drefs); - if (!sc->pb_is_copied) - avio_close(sc->pb); - sc->pb = NULL; - av_freep(&sc->chunk_offsets); - av_freep(&sc->keyframes); - av_freep(&sc->sample_sizes); - av_freep(&sc->stps_data); - av_freep(&sc->stsc_data); - av_freep(&sc->stts_data); - } - - if (mov->dv_demux) { - for (i = 0; i < mov->dv_fctx->nb_streams; i++) { - av_freep(&mov->dv_fctx->streams[i]->codec); - av_freep(&mov->dv_fctx->streams[i]); - } - av_freep(&mov->dv_fctx); - av_freep(&mov->dv_demux); - } - - av_freep(&mov->trex_data); - - return 0; -} - -static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id) -{ - int i; - - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - MOVStreamContext *sc = st->priv_data; - - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && - sc->timecode_track == tmcd_id) - return 1; - } - return 0; -} - -/* look for a tmcd track not referenced by any video track, and export it globally */ -static void export_orphan_timecode(AVFormatContext *s) -{ - int i; - - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - - if (st->codec->codec_tag == MKTAG('t','m','c','d') && - !tmcd_is_referenced(s, i + 1)) { - AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0); - if (tcr) { - av_dict_set(&s->metadata, "timecode", tcr->value, 0); - break; - } - } - } -} - -static int mov_read_header(AVFormatContext *s) -{ - MOVContext *mov = s->priv_data; - AVIOContext *pb = s->pb; - int i, j, err; - MOVAtom atom = { AV_RL32("root") }; - - mov->fc = s; - /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */ - if (pb->seekable) - atom.size = avio_size(pb); - else - atom.size = INT64_MAX; - - /* check MOV header */ - if ((err = mov_read_default(mov, pb, atom)) < 0) { - av_log(s, AV_LOG_ERROR, "error reading header: %d\n", err); - mov_read_close(s); - return err; - } - if (!mov->found_moov) { - av_log(s, AV_LOG_ERROR, "moov atom not found\n"); - mov_read_close(s); - return AVERROR_INVALIDDATA; - } - av_dlog(mov->fc, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb)); - - if (pb->seekable) { - if (mov->chapter_track > 0) - mov_read_chapters(s); - for (i = 0; i < s->nb_streams; i++) - if (s->streams[i]->codec->codec_tag == AV_RL32("tmcd")) - mov_read_timecode_track(s, s->streams[i]); - } - - /* copy timecode metadata from tmcd tracks to the related video streams */ - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - MOVStreamContext *sc = st->priv_data; - if (sc->timecode_track > 0) { - AVDictionaryEntry *tcr; - int tmcd_st_id = -1; - - for (j = 0; j < s->nb_streams; j++) - if (s->streams[j]->id == sc->timecode_track) - tmcd_st_id = j; - - if (tmcd_st_id < 0 || tmcd_st_id == i) - continue; - tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0); - if (tcr) - av_dict_set(&st->metadata, "timecode", tcr->value, 0); - } - } - export_orphan_timecode(s); - - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - MOVStreamContext *sc = st->priv_data; - fix_timescale(mov, sc); - if(st->codec->codec_type == AVMEDIA_TYPE_AUDIO && st->codec->codec_id == AV_CODEC_ID_AAC) { - st->skip_samples = sc->start_pad; - } - } - - if (mov->trex_data) { - 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; -} - -static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st) -{ - AVIndexEntry *sample = NULL; - int64_t best_dts = INT64_MAX; - int i; - for (i = 0; i < s->nb_streams; i++) { - AVStream *avst = s->streams[i]; - MOVStreamContext *msc = avst->priv_data; - if (msc->pb && msc->current_sample < avst->nb_index_entries) { - AVIndexEntry *current_sample = &avst->index_entries[msc->current_sample]; - int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale); - av_dlog(s, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts); - if (!sample || (!s->pb->seekable && current_sample->pos < sample->pos) || - (s->pb->seekable && - ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && - ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) || - (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) { - sample = current_sample; - best_dts = dts; - *st = avst; - } - } - } - return sample; -} - -static int mov_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - MOVContext *mov = s->priv_data; - MOVStreamContext *sc; - AVIndexEntry *sample; - AVStream *st = NULL; - int ret; - mov->fc = s; - retry: - sample = mov_find_next_sample(s, &st); - if (!sample) { - mov->found_mdat = 0; - if (!mov->next_root_atom) - return AVERROR_EOF; - avio_seek(s->pb, mov->next_root_atom, SEEK_SET); - mov->next_root_atom = 0; - if (mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX }) < 0 || - url_feof(s->pb)) - return AVERROR_EOF; - av_dlog(s, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb)); - goto retry; - } - sc = st->priv_data; - /* must be done just before reading, to avoid infinite loop on sample */ - sc->current_sample++; - - if (st->discard != AVDISCARD_ALL) { - if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) { - av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n", - sc->ffindex, sample->pos); - return AVERROR_INVALIDDATA; - } - ret = av_get_packet(sc->pb, pkt, sample->size); - if (ret < 0) - return ret; - if (sc->has_palette) { - uint8_t *pal; - - pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE); - if (!pal) { - av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n"); - } else { - memcpy(pal, sc->palette, AVPALETTE_SIZE); - sc->has_palette = 0; - } - } -#if CONFIG_DV_DEMUXER - if (mov->dv_demux && sc->dv_audio_container) { - avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos); - av_free(pkt->data); - pkt->size = 0; - ret = avpriv_dv_get_packet(mov->dv_demux, pkt); - if (ret < 0) - return ret; - } -#endif - } - - pkt->stream_index = sc->ffindex; - pkt->dts = sample->timestamp; - if (sc->ctts_data && sc->ctts_index < sc->ctts_count) { - pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration; - /* update ctts context */ - sc->ctts_sample++; - if (sc->ctts_index < sc->ctts_count && - sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) { - sc->ctts_index++; - sc->ctts_sample = 0; - } - if (sc->wrong_dts) - pkt->dts = AV_NOPTS_VALUE; - } else { - int64_t next_dts = (sc->current_sample < st->nb_index_entries) ? - st->index_entries[sc->current_sample].timestamp : st->duration; - pkt->duration = next_dts - pkt->dts; - pkt->pts = pkt->dts; - } - if (st->discard == AVDISCARD_ALL) - goto retry; - pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0; - pkt->pos = sample->pos; - av_dlog(s, "stream %d, pts %"PRId64", dts %"PRId64", pos 0x%"PRIx64", duration %d\n", - pkt->stream_index, pkt->pts, pkt->dts, pkt->pos, pkt->duration); - return 0; -} - -static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags) -{ - MOVStreamContext *sc = st->priv_data; - int sample, time_sample; - int i; - - sample = av_index_search_timestamp(st, timestamp, flags); - av_dlog(s, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample); - if (sample < 0 && st->nb_index_entries && timestamp < st->index_entries[0].timestamp) - sample = 0; - if (sample < 0) /* not sure what to do */ - return AVERROR_INVALIDDATA; - sc->current_sample = sample; - av_dlog(s, "stream %d, found sample %d\n", st->index, sc->current_sample); - /* adjust ctts index */ - if (sc->ctts_data) { - time_sample = 0; - for (i = 0; i < sc->ctts_count; i++) { - int next = time_sample + sc->ctts_data[i].count; - if (next > sc->current_sample) { - sc->ctts_index = i; - sc->ctts_sample = sc->current_sample - time_sample; - break; - } - time_sample = next; - } - } - return sample; -} - -static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags) -{ - AVStream *st; - int64_t seek_timestamp, timestamp; - int sample; - int i; - - if (stream_index >= s->nb_streams) - return AVERROR_INVALIDDATA; - - st = s->streams[stream_index]; - sample = mov_seek_stream(s, st, sample_time, flags); - if (sample < 0) - return sample; - - /* adjust seek timestamp to found sample timestamp */ - seek_timestamp = st->index_entries[sample].timestamp; - - for (i = 0; i < s->nb_streams; i++) { - MOVStreamContext *sc = s->streams[i]->priv_data; - st = s->streams[i]; - st->skip_samples = (sample_time <= 0) ? sc->start_pad : 0; - - if (stream_index == i) - continue; - - timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base); - mov_seek_stream(s, st, timestamp, flags); - } - return 0; -} - -static const AVOption options[] = { - {"use_absolute_path", - "allow using absolute path when opening alias, this is a possible security issue", - offsetof(MOVContext, use_absolute_path), FF_OPT_TYPE_INT, {.i64 = 0}, - 0, 1, AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_DECODING_PARAM}, - {"ignore_editlist", "", offsetof(MOVContext, ignore_editlist), FF_OPT_TYPE_INT, {.i64 = 0}, - 0, 1, AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_DECODING_PARAM}, - {NULL} -}; - -static const AVClass class = { - .class_name = "mov,mp4,m4a,3gp,3g2,mj2", - .item_name = av_default_item_name, - .option = options, - .version = LIBAVUTIL_VERSION_INT, -}; - -AVInputFormat ff_mov_demuxer = { - .name = "mov,mp4,m4a,3gp,3g2,mj2", - .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"), - .priv_data_size = sizeof(MOVContext), - .read_probe = mov_probe, - .read_header = mov_read_header, - .read_packet = mov_read_packet, - .read_close = mov_read_close, - .read_seek = mov_read_seek, - .priv_class = &class, - .flags = AVFMT_NO_BYTE_SEEK, -}; diff --git a/ffmpeg1/libavformat/mov_chan.c b/ffmpeg1/libavformat/mov_chan.c deleted file mode 100644 index 7078b4a..0000000 --- a/ffmpeg1/libavformat/mov_chan.c +++ /dev/null @@ -1,592 +0,0 @@ -/* - * Copyright (c) 2011 Justin Ruggles - * - * 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 - */ - -/** - * mov 'chan' tag reading/writing. - * @author Justin Ruggles - */ - -#include - -#include "libavutil/channel_layout.h" -#include "libavcodec/avcodec.h" -#include "mov_chan.h" - -/** - * Channel Layout Tag - * This tells which channels are present in the audio stream and the order in - * which they appear. - * - * @note We're using the channel layout tag to indicate channel order - * when the value is greater than 0x10000. The Apple documentation has - * some contradictions as to how this is actually supposed to be handled. - * - * Core Audio File Format Spec: - * "The high 16 bits indicates a specific ordering of the channels." - * Core Audio Data Types Reference: - * "These identifiers specify the channels included in a layout but - * do not specify a particular ordering of those channels." - */ -enum MovChannelLayoutTag { - MOV_CH_LAYOUT_UNKNOWN = 0xFFFF0000, - MOV_CH_LAYOUT_USE_DESCRIPTIONS = ( 0 << 16) | 0, - MOV_CH_LAYOUT_USE_BITMAP = ( 1 << 16) | 0, - MOV_CH_LAYOUT_DISCRETEINORDER = (147 << 16) | 0, - MOV_CH_LAYOUT_MONO = (100 << 16) | 1, - MOV_CH_LAYOUT_STEREO = (101 << 16) | 2, - MOV_CH_LAYOUT_STEREOHEADPHONES = (102 << 16) | 2, - MOV_CH_LAYOUT_MATRIXSTEREO = (103 << 16) | 2, - MOV_CH_LAYOUT_MIDSIDE = (104 << 16) | 2, - MOV_CH_LAYOUT_XY = (105 << 16) | 2, - MOV_CH_LAYOUT_BINAURAL = (106 << 16) | 2, - MOV_CH_LAYOUT_AMBISONIC_B_FORMAT = (107 << 16) | 4, - MOV_CH_LAYOUT_QUADRAPHONIC = (108 << 16) | 4, - MOV_CH_LAYOUT_PENTAGONAL = (109 << 16) | 5, - MOV_CH_LAYOUT_HEXAGONAL = (110 << 16) | 6, - MOV_CH_LAYOUT_OCTAGONAL = (111 << 16) | 8, - MOV_CH_LAYOUT_CUBE = (112 << 16) | 8, - MOV_CH_LAYOUT_MPEG_3_0_A = (113 << 16) | 3, - MOV_CH_LAYOUT_MPEG_3_0_B = (114 << 16) | 3, - MOV_CH_LAYOUT_MPEG_4_0_A = (115 << 16) | 4, - MOV_CH_LAYOUT_MPEG_4_0_B = (116 << 16) | 4, - MOV_CH_LAYOUT_MPEG_5_0_A = (117 << 16) | 5, - MOV_CH_LAYOUT_MPEG_5_0_B = (118 << 16) | 5, - MOV_CH_LAYOUT_MPEG_5_0_C = (119 << 16) | 5, - MOV_CH_LAYOUT_MPEG_5_0_D = (120 << 16) | 5, - MOV_CH_LAYOUT_MPEG_5_1_A = (121 << 16) | 6, - MOV_CH_LAYOUT_MPEG_5_1_B = (122 << 16) | 6, - MOV_CH_LAYOUT_MPEG_5_1_C = (123 << 16) | 6, - MOV_CH_LAYOUT_MPEG_5_1_D = (124 << 16) | 6, - MOV_CH_LAYOUT_MPEG_6_1_A = (125 << 16) | 7, - MOV_CH_LAYOUT_MPEG_7_1_A = (126 << 16) | 8, - MOV_CH_LAYOUT_MPEG_7_1_B = (127 << 16) | 8, - MOV_CH_LAYOUT_MPEG_7_1_C = (128 << 16) | 8, - MOV_CH_LAYOUT_EMAGIC_DEFAULT_7_1 = (129 << 16) | 8, - MOV_CH_LAYOUT_SMPTE_DTV = (130 << 16) | 8, - MOV_CH_LAYOUT_ITU_2_1 = (131 << 16) | 3, - MOV_CH_LAYOUT_ITU_2_2 = (132 << 16) | 4, - MOV_CH_LAYOUT_DVD_4 = (133 << 16) | 3, - MOV_CH_LAYOUT_DVD_5 = (134 << 16) | 4, - MOV_CH_LAYOUT_DVD_6 = (135 << 16) | 5, - MOV_CH_LAYOUT_DVD_10 = (136 << 16) | 4, - MOV_CH_LAYOUT_DVD_11 = (137 << 16) | 5, - MOV_CH_LAYOUT_DVD_18 = (138 << 16) | 5, - MOV_CH_LAYOUT_AUDIOUNIT_6_0 = (139 << 16) | 6, - MOV_CH_LAYOUT_AUDIOUNIT_7_0 = (140 << 16) | 7, - MOV_CH_LAYOUT_AUDIOUNIT_7_0_FRONT = (148 << 16) | 7, - MOV_CH_LAYOUT_AAC_6_0 = (141 << 16) | 6, - MOV_CH_LAYOUT_AAC_6_1 = (142 << 16) | 7, - MOV_CH_LAYOUT_AAC_7_0 = (143 << 16) | 7, - MOV_CH_LAYOUT_AAC_OCTAGONAL = (144 << 16) | 8, - MOV_CH_LAYOUT_TMH_10_2_STD = (145 << 16) | 16, - MOV_CH_LAYOUT_TMH_10_2_FULL = (146 << 16) | 21, - MOV_CH_LAYOUT_AC3_1_0_1 = (149 << 16) | 2, - MOV_CH_LAYOUT_AC3_3_0 = (150 << 16) | 3, - MOV_CH_LAYOUT_AC3_3_1 = (151 << 16) | 4, - MOV_CH_LAYOUT_AC3_3_0_1 = (152 << 16) | 4, - MOV_CH_LAYOUT_AC3_2_1_1 = (153 << 16) | 4, - MOV_CH_LAYOUT_AC3_3_1_1 = (154 << 16) | 5, - MOV_CH_LAYOUT_EAC3_6_0_A = (155 << 16) | 6, - MOV_CH_LAYOUT_EAC3_7_0_A = (156 << 16) | 7, - MOV_CH_LAYOUT_EAC3_6_1_A = (157 << 16) | 7, - MOV_CH_LAYOUT_EAC3_6_1_B = (158 << 16) | 7, - MOV_CH_LAYOUT_EAC3_6_1_C = (159 << 16) | 7, - MOV_CH_LAYOUT_EAC3_7_1_A = (160 << 16) | 8, - MOV_CH_LAYOUT_EAC3_7_1_B = (161 << 16) | 8, - MOV_CH_LAYOUT_EAC3_7_1_C = (162 << 16) | 8, - MOV_CH_LAYOUT_EAC3_7_1_D = (163 << 16) | 8, - MOV_CH_LAYOUT_EAC3_7_1_E = (164 << 16) | 8, - MOV_CH_LAYOUT_EAC3_7_1_F = (165 << 16) | 8, - MOV_CH_LAYOUT_EAC3_7_1_G = (166 << 16) | 8, - MOV_CH_LAYOUT_EAC3_7_1_H = (167 << 16) | 8, - MOV_CH_LAYOUT_DTS_3_1 = (168 << 16) | 4, - MOV_CH_LAYOUT_DTS_4_1 = (169 << 16) | 5, - MOV_CH_LAYOUT_DTS_6_0_A = (170 << 16) | 6, - MOV_CH_LAYOUT_DTS_6_0_B = (171 << 16) | 6, - MOV_CH_LAYOUT_DTS_6_0_C = (172 << 16) | 6, - MOV_CH_LAYOUT_DTS_6_1_A = (173 << 16) | 7, - MOV_CH_LAYOUT_DTS_6_1_B = (174 << 16) | 7, - MOV_CH_LAYOUT_DTS_6_1_C = (175 << 16) | 7, - MOV_CH_LAYOUT_DTS_6_1_D = (182 << 16) | 7, - MOV_CH_LAYOUT_DTS_7_0 = (176 << 16) | 7, - MOV_CH_LAYOUT_DTS_7_1 = (177 << 16) | 8, - MOV_CH_LAYOUT_DTS_8_0_A = (178 << 16) | 8, - MOV_CH_LAYOUT_DTS_8_0_B = (179 << 16) | 8, - MOV_CH_LAYOUT_DTS_8_1_A = (180 << 16) | 9, - MOV_CH_LAYOUT_DTS_8_1_B = (181 << 16) | 9, -}; - -struct MovChannelLayoutMap { - uint32_t tag; - uint64_t layout; -}; - -static const struct MovChannelLayoutMap mov_ch_layout_map_misc[] = { - { MOV_CH_LAYOUT_USE_DESCRIPTIONS, 0 }, - { MOV_CH_LAYOUT_USE_BITMAP, 0 }, - { MOV_CH_LAYOUT_DISCRETEINORDER, 0 }, - { MOV_CH_LAYOUT_UNKNOWN, 0 }, - { MOV_CH_LAYOUT_TMH_10_2_STD, 0 }, // L, R, C, Vhc, Lsd, Rsd, - // Ls, Rs, Vhl, Vhr, Lw, Rw, - // Csd, Cs, LFE1, LFE2 - { MOV_CH_LAYOUT_TMH_10_2_FULL, 0 }, // L, R, C, Vhc, Lsd, Rsd, - // Ls, Rs, Vhl, Vhr, Lw, Rw, - // Csd, Cs, LFE1, LFE2, Lc, Rc, - // HI, VI, Haptic - { 0, 0 }, -}; - -static const struct MovChannelLayoutMap mov_ch_layout_map_1ch[] = { - { MOV_CH_LAYOUT_MONO, AV_CH_LAYOUT_MONO }, // C - { 0, 0 }, -}; - -static const struct MovChannelLayoutMap mov_ch_layout_map_2ch[] = { - { MOV_CH_LAYOUT_STEREO, AV_CH_LAYOUT_STEREO }, // L, R - { MOV_CH_LAYOUT_STEREOHEADPHONES, AV_CH_LAYOUT_STEREO }, // L, R - { MOV_CH_LAYOUT_BINAURAL, AV_CH_LAYOUT_STEREO }, // L, R - { MOV_CH_LAYOUT_MIDSIDE, AV_CH_LAYOUT_STEREO }, // C, sides - { MOV_CH_LAYOUT_XY, AV_CH_LAYOUT_STEREO }, // X (left), Y (right) - - { MOV_CH_LAYOUT_MATRIXSTEREO, AV_CH_LAYOUT_STEREO_DOWNMIX }, // Lt, Rt - - { MOV_CH_LAYOUT_AC3_1_0_1, AV_CH_LAYOUT_MONO | // C, LFE - AV_CH_LOW_FREQUENCY }, - { 0, 0 }, -}; - -static const struct MovChannelLayoutMap mov_ch_layout_map_3ch[] = { - { MOV_CH_LAYOUT_MPEG_3_0_A, AV_CH_LAYOUT_SURROUND }, // L, R, C - { MOV_CH_LAYOUT_MPEG_3_0_B, AV_CH_LAYOUT_SURROUND }, // C, L, R - { MOV_CH_LAYOUT_AC3_3_0, AV_CH_LAYOUT_SURROUND }, // L, C, R - - { MOV_CH_LAYOUT_ITU_2_1, AV_CH_LAYOUT_2_1 }, // L, R, Cs - - { MOV_CH_LAYOUT_DVD_4, AV_CH_LAYOUT_2POINT1 }, // L, R, LFE - { 0, 0 }, -}; - -static const struct MovChannelLayoutMap mov_ch_layout_map_4ch[] = { - { MOV_CH_LAYOUT_AMBISONIC_B_FORMAT, 0 }, // W, X, Y, Z - - { MOV_CH_LAYOUT_QUADRAPHONIC, AV_CH_LAYOUT_QUAD }, // L, R, Rls, Rrs - - { MOV_CH_LAYOUT_MPEG_4_0_A, AV_CH_LAYOUT_4POINT0 }, // L, R, C, Cs - { MOV_CH_LAYOUT_MPEG_4_0_B, AV_CH_LAYOUT_4POINT0 }, // C, L, R, Cs - { MOV_CH_LAYOUT_AC3_3_1, AV_CH_LAYOUT_4POINT0 }, // L, C, R, Cs - - { MOV_CH_LAYOUT_ITU_2_2, AV_CH_LAYOUT_2_2 }, // L, R, Ls, Rs - - { MOV_CH_LAYOUT_DVD_5, AV_CH_LAYOUT_2_1 | // L, R, LFE, Cs - AV_CH_LOW_FREQUENCY }, - { MOV_CH_LAYOUT_AC3_2_1_1, AV_CH_LAYOUT_2_1 | // L, R, Cs, LFE - AV_CH_LOW_FREQUENCY }, - - { MOV_CH_LAYOUT_DVD_10, AV_CH_LAYOUT_3POINT1 }, // L, R, C, LFE - { MOV_CH_LAYOUT_AC3_3_0_1, AV_CH_LAYOUT_3POINT1 }, // L, C, R, LFE - { MOV_CH_LAYOUT_DTS_3_1, AV_CH_LAYOUT_3POINT1 }, // C, L, R, LFE - { 0, 0 }, -}; - -static const struct MovChannelLayoutMap mov_ch_layout_map_5ch[] = { - { MOV_CH_LAYOUT_PENTAGONAL, AV_CH_LAYOUT_5POINT0_BACK }, // L, R, Rls, Rrs, C - - { MOV_CH_LAYOUT_MPEG_5_0_A, AV_CH_LAYOUT_5POINT0 }, // L, R, C, Ls, Rs - { MOV_CH_LAYOUT_MPEG_5_0_B, AV_CH_LAYOUT_5POINT0 }, // L, R, Ls, Rs, C - { MOV_CH_LAYOUT_MPEG_5_0_C, AV_CH_LAYOUT_5POINT0 }, // L, C, R, Ls, Rs - { MOV_CH_LAYOUT_MPEG_5_0_D, AV_CH_LAYOUT_5POINT0 }, // C, L, R, Ls, Rs - - { MOV_CH_LAYOUT_DVD_6, AV_CH_LAYOUT_2_2 | // L, R, LFE, Ls, Rs - AV_CH_LOW_FREQUENCY }, - { MOV_CH_LAYOUT_DVD_18, AV_CH_LAYOUT_2_2 | // L, R, Ls, Rs, LFE - AV_CH_LOW_FREQUENCY }, - - { MOV_CH_LAYOUT_DVD_11, AV_CH_LAYOUT_4POINT1 }, // L, R, C, LFE, Cs - { MOV_CH_LAYOUT_AC3_3_1_1, AV_CH_LAYOUT_4POINT1 }, // L, C, R, Cs, LFE - { MOV_CH_LAYOUT_DTS_4_1, AV_CH_LAYOUT_4POINT1 }, // C, L, R, Cs, LFE - { 0, 0 }, -}; - -static const struct MovChannelLayoutMap mov_ch_layout_map_6ch[] = { - { MOV_CH_LAYOUT_HEXAGONAL, AV_CH_LAYOUT_HEXAGONAL }, // L, R, Rls, Rrs, C, Cs - { MOV_CH_LAYOUT_DTS_6_0_C, AV_CH_LAYOUT_HEXAGONAL }, // C, Cs, L, R, Rls, Rrs - - { MOV_CH_LAYOUT_MPEG_5_1_A, AV_CH_LAYOUT_5POINT1 }, // L, R, C, LFE, Ls, Rs - { MOV_CH_LAYOUT_MPEG_5_1_B, AV_CH_LAYOUT_5POINT1 }, // L, R, Ls, Rs, C, LFE - { MOV_CH_LAYOUT_MPEG_5_1_C, AV_CH_LAYOUT_5POINT1 }, // L, C, R, Ls, Rs, LFE - { MOV_CH_LAYOUT_MPEG_5_1_D, AV_CH_LAYOUT_5POINT1 }, // C, L, R, Ls, Rs, LFE - - { MOV_CH_LAYOUT_AUDIOUNIT_6_0, AV_CH_LAYOUT_6POINT0 }, // L, R, Ls, Rs, C, Cs - { MOV_CH_LAYOUT_AAC_6_0, AV_CH_LAYOUT_6POINT0 }, // C, L, R, Ls, Rs, Cs - { MOV_CH_LAYOUT_EAC3_6_0_A, AV_CH_LAYOUT_6POINT0 }, // L, C, R, Ls, Rs, Cs - - { MOV_CH_LAYOUT_DTS_6_0_A, AV_CH_LAYOUT_6POINT0_FRONT }, // Lc, Rc, L, R, Ls, Rs - - { MOV_CH_LAYOUT_DTS_6_0_B, AV_CH_LAYOUT_5POINT0_BACK | // C, L, R, Rls, Rrs, Ts - AV_CH_TOP_CENTER }, - { 0, 0 }, -}; - -static const struct MovChannelLayoutMap mov_ch_layout_map_7ch[] = { - { MOV_CH_LAYOUT_MPEG_6_1_A, AV_CH_LAYOUT_6POINT1 }, // L, R, C, LFE, Ls, Rs, Cs - { MOV_CH_LAYOUT_AAC_6_1, AV_CH_LAYOUT_6POINT1 }, // C, L, R, Ls, Rs, Cs, LFE - { MOV_CH_LAYOUT_EAC3_6_1_A, AV_CH_LAYOUT_6POINT1 }, // L, C, R, Ls, Rs, LFE, Cs - { MOV_CH_LAYOUT_DTS_6_1_D, AV_CH_LAYOUT_6POINT1 }, // C, L, R, Ls, Rs, LFE, Cs - - { MOV_CH_LAYOUT_AUDIOUNIT_7_0, AV_CH_LAYOUT_7POINT0 }, // L, R, Ls, Rs, C, Rls, Rrs - { MOV_CH_LAYOUT_AAC_7_0, AV_CH_LAYOUT_7POINT0 }, // C, L, R, Ls, Rs, Rls, Rrs - { MOV_CH_LAYOUT_EAC3_7_0_A, AV_CH_LAYOUT_7POINT0 }, // L, C, R, Ls, Rs, Rls, Rrs - - { MOV_CH_LAYOUT_AUDIOUNIT_7_0_FRONT, AV_CH_LAYOUT_7POINT0_FRONT }, // L, R, Ls, Rs, C, Lc, Rc - { MOV_CH_LAYOUT_DTS_7_0, AV_CH_LAYOUT_7POINT0_FRONT }, // Lc, C, Rc, L, R, Ls, Rs - - { MOV_CH_LAYOUT_EAC3_6_1_B, AV_CH_LAYOUT_5POINT1 | // L, C, R, Ls, Rs, LFE, Ts - AV_CH_TOP_CENTER }, - - { MOV_CH_LAYOUT_EAC3_6_1_C, AV_CH_LAYOUT_5POINT1 | // L, C, R, Ls, Rs, LFE, Vhc - AV_CH_TOP_FRONT_CENTER }, - - { MOV_CH_LAYOUT_DTS_6_1_A, AV_CH_LAYOUT_6POINT1_FRONT }, // Lc, Rc, L, R, Ls, Rs, LFE - - { MOV_CH_LAYOUT_DTS_6_1_B, AV_CH_LAYOUT_5POINT1_BACK | // C, L, R, Rls, Rrs, Ts, LFE - AV_CH_TOP_CENTER }, - - { MOV_CH_LAYOUT_DTS_6_1_C, AV_CH_LAYOUT_6POINT1_BACK }, // C, Cs, L, R, Rls, Rrs, LFE - { 0, 0 }, -}; - -static const struct MovChannelLayoutMap mov_ch_layout_map_8ch[] = { - { MOV_CH_LAYOUT_OCTAGONAL, AV_CH_LAYOUT_OCTAGONAL }, // L, R, Rls, Rrs, C, Cs, Ls, Rs - { MOV_CH_LAYOUT_AAC_OCTAGONAL, AV_CH_LAYOUT_OCTAGONAL }, // C, L, R, Ls, Rs, Rls, Rrs, Cs - - { MOV_CH_LAYOUT_CUBE, AV_CH_LAYOUT_QUAD | // L, R, Rls, Rrs, Vhl, Vhr, Rlt, Rrt - AV_CH_TOP_FRONT_LEFT | - AV_CH_TOP_FRONT_RIGHT | - AV_CH_TOP_BACK_LEFT | - AV_CH_TOP_BACK_RIGHT }, - - { MOV_CH_LAYOUT_MPEG_7_1_A, AV_CH_LAYOUT_7POINT1_WIDE }, // L, R, C, LFE, Ls, Rs, Lc, Rc - { MOV_CH_LAYOUT_MPEG_7_1_B, AV_CH_LAYOUT_7POINT1_WIDE }, // C, Lc, Rc, L, R, Ls, Rs, LFE - { MOV_CH_LAYOUT_EMAGIC_DEFAULT_7_1, AV_CH_LAYOUT_7POINT1_WIDE }, // L, R, Ls, Rs, C, LFE, Lc, Rc - { MOV_CH_LAYOUT_EAC3_7_1_B, AV_CH_LAYOUT_7POINT1_WIDE }, // L, C, R, Ls, Rs, LFE, Lc, Rc - { MOV_CH_LAYOUT_DTS_7_1, AV_CH_LAYOUT_7POINT1_WIDE }, // Lc, C, Rc, L, R, Ls, Rs, LFE - - { MOV_CH_LAYOUT_MPEG_7_1_C, AV_CH_LAYOUT_7POINT1 }, // L, R, C, LFE, Ls, Rs, Rls, Rrs - { MOV_CH_LAYOUT_EAC3_7_1_A, AV_CH_LAYOUT_7POINT1 }, // L, C, R, Ls, Rs, LFE, Rls, Rrs - - { MOV_CH_LAYOUT_SMPTE_DTV, AV_CH_LAYOUT_5POINT1 | // L, R, C, LFE, Ls, Rs, Lt, Rt - AV_CH_LAYOUT_STEREO_DOWNMIX }, - - { MOV_CH_LAYOUT_EAC3_7_1_C, AV_CH_LAYOUT_5POINT1 | // L, C, R, Ls, Rs, LFE, Lsd, Rsd - AV_CH_SURROUND_DIRECT_LEFT | - AV_CH_SURROUND_DIRECT_RIGHT }, - - { MOV_CH_LAYOUT_EAC3_7_1_D, AV_CH_LAYOUT_5POINT1 | // L, C, R, Ls, Rs, LFE, Lw, Rw - AV_CH_WIDE_LEFT | - AV_CH_WIDE_RIGHT }, - - { MOV_CH_LAYOUT_EAC3_7_1_E, AV_CH_LAYOUT_5POINT1 | // L, C, R, Ls, Rs, LFE, Vhl, Vhr - AV_CH_TOP_FRONT_LEFT | - AV_CH_TOP_FRONT_RIGHT }, - - { MOV_CH_LAYOUT_EAC3_7_1_F, AV_CH_LAYOUT_5POINT1 | // L, C, R, Ls, Rs, LFE, Cs, Ts - AV_CH_BACK_CENTER | - AV_CH_TOP_CENTER }, - - { MOV_CH_LAYOUT_EAC3_7_1_G, AV_CH_LAYOUT_5POINT1 | // L, C, R, Ls, Rs, LFE, Cs, Vhc - AV_CH_BACK_CENTER | - AV_CH_TOP_FRONT_CENTER }, - - { MOV_CH_LAYOUT_EAC3_7_1_H, AV_CH_LAYOUT_5POINT1 | // L, C, R, Ls, Rs, LFE, Ts, Vhc - AV_CH_TOP_CENTER | - AV_CH_TOP_FRONT_CENTER }, - - { MOV_CH_LAYOUT_DTS_8_0_A, AV_CH_LAYOUT_2_2 | // Lc, Rc, L, R, Ls, Rs, Rls, Rrs - AV_CH_BACK_LEFT | - AV_CH_BACK_RIGHT | - AV_CH_FRONT_LEFT_OF_CENTER | - AV_CH_FRONT_RIGHT_OF_CENTER }, - - { MOV_CH_LAYOUT_DTS_8_0_B, AV_CH_LAYOUT_5POINT0 | // Lc, C, Rc, L, R, Ls, Cs, Rs - AV_CH_FRONT_LEFT_OF_CENTER | - AV_CH_FRONT_RIGHT_OF_CENTER | - AV_CH_BACK_CENTER }, - { 0, 0 }, -}; - -static const struct MovChannelLayoutMap mov_ch_layout_map_9ch[] = { - { MOV_CH_LAYOUT_DTS_8_1_A, AV_CH_LAYOUT_2_2 | // Lc, Rc, L, R, Ls, Rs, Rls, Rrs, LFE - AV_CH_BACK_LEFT | - AV_CH_BACK_RIGHT | - AV_CH_FRONT_LEFT_OF_CENTER | - AV_CH_FRONT_RIGHT_OF_CENTER | - AV_CH_LOW_FREQUENCY }, - - { MOV_CH_LAYOUT_DTS_8_1_B, AV_CH_LAYOUT_7POINT1_WIDE | // Lc, C, Rc, L, R, Ls, Cs, Rs, LFE - AV_CH_BACK_CENTER }, - { 0, 0 }, -}; - -static const struct MovChannelLayoutMap *mov_ch_layout_map[] = { - mov_ch_layout_map_misc, - mov_ch_layout_map_1ch, - mov_ch_layout_map_2ch, - mov_ch_layout_map_3ch, - mov_ch_layout_map_4ch, - mov_ch_layout_map_5ch, - mov_ch_layout_map_6ch, - mov_ch_layout_map_7ch, - mov_ch_layout_map_8ch, - mov_ch_layout_map_9ch, -}; - -static const enum MovChannelLayoutTag mov_ch_layouts_aac[] = { - MOV_CH_LAYOUT_MONO, - MOV_CH_LAYOUT_STEREO, - MOV_CH_LAYOUT_AC3_1_0_1, - MOV_CH_LAYOUT_MPEG_3_0_B, - MOV_CH_LAYOUT_ITU_2_1, - MOV_CH_LAYOUT_DVD_4, - MOV_CH_LAYOUT_QUADRAPHONIC, - MOV_CH_LAYOUT_MPEG_4_0_B, - MOV_CH_LAYOUT_ITU_2_2, - MOV_CH_LAYOUT_AC3_2_1_1, - MOV_CH_LAYOUT_DTS_3_1, - MOV_CH_LAYOUT_MPEG_5_0_D, - MOV_CH_LAYOUT_DVD_18, - MOV_CH_LAYOUT_DTS_4_1, - MOV_CH_LAYOUT_MPEG_5_1_D, - MOV_CH_LAYOUT_AAC_6_0, - MOV_CH_LAYOUT_DTS_6_0_A, - MOV_CH_LAYOUT_AAC_6_1, - MOV_CH_LAYOUT_AAC_7_0, - MOV_CH_LAYOUT_DTS_6_1_A, - MOV_CH_LAYOUT_AAC_OCTAGONAL, - MOV_CH_LAYOUT_MPEG_7_1_B, - MOV_CH_LAYOUT_DTS_8_0_A, - 0, -}; - -static const enum MovChannelLayoutTag mov_ch_layouts_ac3[] = { - MOV_CH_LAYOUT_MONO, - MOV_CH_LAYOUT_STEREO, - MOV_CH_LAYOUT_AC3_1_0_1, - MOV_CH_LAYOUT_AC3_3_0, - MOV_CH_LAYOUT_ITU_2_1, - MOV_CH_LAYOUT_DVD_4, - MOV_CH_LAYOUT_AC3_3_1, - MOV_CH_LAYOUT_ITU_2_2, - MOV_CH_LAYOUT_AC3_2_1_1, - MOV_CH_LAYOUT_AC3_3_0_1, - MOV_CH_LAYOUT_MPEG_5_0_C, - MOV_CH_LAYOUT_DVD_18, - MOV_CH_LAYOUT_AC3_3_1_1, - MOV_CH_LAYOUT_MPEG_5_1_C, - 0, -}; - -static const enum MovChannelLayoutTag mov_ch_layouts_alac[] = { - MOV_CH_LAYOUT_MONO, - MOV_CH_LAYOUT_STEREO, - MOV_CH_LAYOUT_MPEG_3_0_B, - MOV_CH_LAYOUT_MPEG_4_0_B, - MOV_CH_LAYOUT_MPEG_5_0_D, - MOV_CH_LAYOUT_MPEG_5_1_D, - MOV_CH_LAYOUT_AAC_6_1, - MOV_CH_LAYOUT_MPEG_7_1_B, - 0, -}; - -static const enum MovChannelLayoutTag mov_ch_layouts_wav[] = { - MOV_CH_LAYOUT_MONO, - MOV_CH_LAYOUT_STEREO, - MOV_CH_LAYOUT_MATRIXSTEREO, - MOV_CH_LAYOUT_MPEG_3_0_A, - MOV_CH_LAYOUT_QUADRAPHONIC, - MOV_CH_LAYOUT_MPEG_5_0_A, - MOV_CH_LAYOUT_MPEG_5_1_A, - MOV_CH_LAYOUT_MPEG_6_1_A, - MOV_CH_LAYOUT_MPEG_7_1_A, - MOV_CH_LAYOUT_MPEG_7_1_C, - MOV_CH_LAYOUT_SMPTE_DTV, - 0, -}; - -static const struct { - enum AVCodecID codec_id; - const enum MovChannelLayoutTag *layouts; -} mov_codec_ch_layouts[] = { - { AV_CODEC_ID_AAC, mov_ch_layouts_aac }, - { AV_CODEC_ID_AC3, mov_ch_layouts_ac3 }, - { AV_CODEC_ID_ALAC, mov_ch_layouts_alac }, - { AV_CODEC_ID_PCM_U8, mov_ch_layouts_wav }, - { AV_CODEC_ID_PCM_S8, mov_ch_layouts_wav }, - { AV_CODEC_ID_PCM_S16LE, mov_ch_layouts_wav }, - { AV_CODEC_ID_PCM_S16BE, mov_ch_layouts_wav }, - { AV_CODEC_ID_PCM_S24LE, mov_ch_layouts_wav }, - { AV_CODEC_ID_PCM_S24BE, mov_ch_layouts_wav }, - { AV_CODEC_ID_PCM_S32LE, mov_ch_layouts_wav }, - { AV_CODEC_ID_PCM_S32BE, mov_ch_layouts_wav }, - { AV_CODEC_ID_PCM_F32LE, mov_ch_layouts_wav }, - { AV_CODEC_ID_PCM_F32BE, mov_ch_layouts_wav }, - { AV_CODEC_ID_PCM_F64LE, mov_ch_layouts_wav }, - { AV_CODEC_ID_PCM_F64BE, mov_ch_layouts_wav }, - { AV_CODEC_ID_NONE, NULL }, -}; - -uint64_t ff_mov_get_channel_layout(uint32_t tag, uint32_t bitmap) -{ - int i, channels; - const struct MovChannelLayoutMap *layout_map; - - /* use ff_mov_get_channel_label() to build a layout instead */ - if (tag == MOV_CH_LAYOUT_USE_DESCRIPTIONS) - return 0; - - /* handle the use of the channel bitmap */ - if (tag == MOV_CH_LAYOUT_USE_BITMAP) - return bitmap < 0x40000 ? bitmap : 0; - - /* get the layout map based on the channel count for the specified layout tag */ - channels = tag & 0xFFFF; - if (channels > 9) - channels = 0; - layout_map = mov_ch_layout_map[channels]; - - /* find the channel layout for the specified layout tag */ - for (i = 0; layout_map[i].tag != 0; i++) { - if (layout_map[i].tag == tag) - break; - } - return layout_map[i].layout; -} - -static uint32_t mov_get_channel_label(uint32_t label) -{ - if (label == 0) - return 0; - if (label <= 18) - return 1U << (label - 1); - if (label == 38) - return AV_CH_STEREO_LEFT; - if (label == 39) - return AV_CH_STEREO_RIGHT; - return 0; -} - -uint32_t ff_mov_get_channel_layout_tag(enum AVCodecID codec_id, - uint64_t channel_layout, - uint32_t *bitmap) -{ - int i, j; - uint32_t tag = 0; - const enum MovChannelLayoutTag *layouts = NULL; - - /* find the layout list for the specified codec */ - for (i = 0; mov_codec_ch_layouts[i].codec_id != AV_CODEC_ID_NONE; i++) { - if (mov_codec_ch_layouts[i].codec_id == codec_id) - break; - } - if (mov_codec_ch_layouts[i].codec_id != AV_CODEC_ID_NONE) - layouts = mov_codec_ch_layouts[i].layouts; - - if (layouts) { - int channels; - const struct MovChannelLayoutMap *layout_map; - - /* get the layout map based on the channel count */ - channels = av_get_channel_layout_nb_channels(channel_layout); - if (channels > 9) - channels = 0; - layout_map = mov_ch_layout_map[channels]; - - /* find the layout tag for the specified channel layout */ - for (i = 0; layouts[i] != 0; i++) { - if ((layouts[i] & 0xFFFF) != channels) - continue; - for (j = 0; layout_map[j].tag != 0; j++) { - if (layout_map[j].tag == layouts[i] && - layout_map[j].layout == channel_layout) - break; - } - if (layout_map[j].tag) - break; - } - tag = layouts[i]; - } - - /* if no tag was found, use channel bitmap as a backup if possible */ - if (tag == 0 && channel_layout > 0 && channel_layout < 0x40000) { - tag = MOV_CH_LAYOUT_USE_BITMAP; - *bitmap = (uint32_t)channel_layout; - } else - *bitmap = 0; - - /* TODO: set channel descriptions as a secondary backup */ - - return tag; -} - -int ff_mov_read_chan(AVFormatContext *s, AVIOContext *pb, AVStream *st, - int64_t size) -{ - uint32_t layout_tag, bitmap, num_descr, label_mask; - int i; - - if (size < 12) - return AVERROR_INVALIDDATA; - - layout_tag = avio_rb32(pb); - bitmap = avio_rb32(pb); - num_descr = avio_rb32(pb); - - av_dlog(s, "chan: layout=%u bitmap=%u num_descr=%u\n", - layout_tag, bitmap, num_descr); - - if (size < 12ULL + num_descr * 20ULL) - return 0; - - label_mask = 0; - for (i = 0; i < num_descr; i++) { - uint32_t label; - label = avio_rb32(pb); // mChannelLabel - avio_rb32(pb); // mChannelFlags - avio_rl32(pb); // mCoordinates[0] - avio_rl32(pb); // mCoordinates[1] - avio_rl32(pb); // mCoordinates[2] - size -= 20; - if (layout_tag == 0) { - uint32_t mask_incr = mov_get_channel_label(label); - if (mask_incr == 0) { - label_mask = 0; - break; - } - label_mask |= mask_incr; - } - } - if (layout_tag == 0) { - if (label_mask) - st->codec->channel_layout = label_mask; - } else - st->codec->channel_layout = ff_mov_get_channel_layout(layout_tag, bitmap); - avio_skip(pb, size - 12); - - return 0; -} diff --git a/ffmpeg1/libavformat/mov_chan.h b/ffmpeg1/libavformat/mov_chan.h deleted file mode 100644 index 3fae939..0000000 --- a/ffmpeg1/libavformat/mov_chan.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2011 Justin Ruggles - * - * 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 - */ - -/** - * mov 'chan' tag reading/writing. - * @author Justin Ruggles - */ - -#ifndef AVFORMAT_MOV_CHAN_H -#define AVFORMAT_MOV_CHAN_H - -#include - -#include "libavcodec/avcodec.h" -#include "avformat.h" - -/** - * Get the channel layout for the specified channel layout tag. - * - * @param[in] tag channel layout tag - * @param[out] bitmap channel bitmap (only used if needed) - * @return channel layout - */ -uint64_t ff_mov_get_channel_layout(uint32_t tag, uint32_t bitmap); - -/** - * Get the channel layout tag for the specified codec id and channel layout. - * If the layout tag was not found, use a channel bitmap if possible. - * - * @param[in] codec_id codec id - * @param[in] channel_layout channel layout - * @param[out] bitmap channel bitmap - * @return channel layout tag - */ -uint32_t ff_mov_get_channel_layout_tag(enum AVCodecID codec_id, - uint64_t channel_layout, - uint32_t *bitmap); - -/** - * Read 'chan' tag from the input stream. - * - * @param s AVFormatContext - * @param pb AVIOContext - * @param st The stream to set codec values for - * @param size Remaining size in the 'chan' tag - * @return 0 if ok, or negative AVERROR code on failure - */ -int ff_mov_read_chan(AVFormatContext *s, AVIOContext *pb, AVStream *st, - int64_t size); - -#endif /* AVFORMAT_MOV_CHAN_H */ diff --git a/ffmpeg1/libavformat/movenc.c b/ffmpeg1/libavformat/movenc.c deleted file mode 100644 index 42496b5..0000000 --- a/ffmpeg1/libavformat/movenc.c +++ /dev/null @@ -1,4084 +0,0 @@ -/* - * MOV, 3GP, MP4 muxer - * Copyright (c) 2003 Thomas Raivio - * Copyright (c) 2004 Gildas Bazin - * Copyright (c) 2009 Baptiste Coudurier - * - * 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 "movenc.h" -#include "avformat.h" -#include "avio_internal.h" -#include "riff.h" -#include "avio.h" -#include "isom.h" -#include "avc.h" -#include "libavcodec/get_bits.h" -#include "libavcodec/put_bits.h" -#include "libavcodec/vc1.h" -#include "internal.h" -#include "libavutil/avstring.h" -#include "libavutil/intfloat.h" -#include "libavutil/mathematics.h" -#include "libavutil/opt.h" -#include "libavutil/dict.h" -#include "rtpenc.h" -#include "mov_chan.h" - -#undef NDEBUG -#include - -static const AVOption options[] = { - { "movflags", "MOV muxer flags", offsetof(MOVMuxContext, flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" }, - { "rtphint", "Add RTP hint tracks", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_RTP_HINT}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" }, - { "moov_size", "maximum moov size so it can be placed at the begin", offsetof(MOVMuxContext, reserved_moov_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, 0 }, - { "empty_moov", "Make the initial moov atom empty (not supported by QuickTime)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_EMPTY_MOOV}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" }, - { "frag_keyframe", "Fragment at video keyframes", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FRAG_KEYFRAME}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" }, - { "separate_moof", "Write separate moof/mdat atoms for each track", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_SEPARATE_MOOF}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" }, - { "frag_custom", "Flush fragments on caller requests", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FRAG_CUSTOM}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" }, - { "isml", "Create a live smooth streaming feed (for pushing to a publishing point)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_ISML}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" }, - { "faststart", "Run a second pass to put the moov at the beginning of the file", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FASTSTART}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" }, - FF_RTP_FLAG_OPTS(MOVMuxContext, rtp_flags), - { "skip_iods", "Skip writing iods atom.", offsetof(MOVMuxContext, iods_skip), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM}, - { "iods_audio_profile", "iods audio profile atom.", offsetof(MOVMuxContext, iods_audio_profile), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 255, AV_OPT_FLAG_ENCODING_PARAM}, - { "iods_video_profile", "iods video profile atom.", offsetof(MOVMuxContext, iods_video_profile), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 255, AV_OPT_FLAG_ENCODING_PARAM}, - { "frag_duration", "Maximum fragment duration", offsetof(MOVMuxContext, max_fragment_duration), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM}, - { "min_frag_duration", "Minimum fragment duration", offsetof(MOVMuxContext, min_fragment_duration), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM}, - { "frag_size", "Maximum fragment size", offsetof(MOVMuxContext, max_fragment_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM}, - { "ism_lookahead", "Number of lookahead entries for ISM files", offsetof(MOVMuxContext, ism_lookahead), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM}, - { "use_editlist", "use edit list", offsetof(MOVMuxContext, use_editlist), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, AV_OPT_FLAG_ENCODING_PARAM}, - { NULL }, -}; - -#define MOV_CLASS(flavor)\ -static const AVClass flavor ## _muxer_class = {\ - .class_name = #flavor " muxer",\ - .item_name = av_default_item_name,\ - .option = options,\ - .version = LIBAVUTIL_VERSION_INT,\ -}; - -//FIXME support 64 bit variant with wide placeholders -static int64_t update_size(AVIOContext *pb, int64_t pos) -{ - int64_t curpos = avio_tell(pb); - avio_seek(pb, pos, SEEK_SET); - avio_wb32(pb, curpos - pos); /* rewrite size */ - avio_seek(pb, curpos, SEEK_SET); - - return curpos - pos; -} - -static int supports_edts(MOVMuxContext *mov) -{ - // EDTS with fragments is tricky as we dont know the duration when its written - return (mov->use_editlist<0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT)) || mov->use_editlist>0; -} - -static int is_co64_required(const MOVTrack *track) -{ - int i; - - for (i = 0; i < track->entry; i++) { - if (!track->cluster[i].chunkNum) - continue; - if (track->cluster[i].pos + track->data_offset > UINT32_MAX) - return 1; - } - return 0; -} - -/* Chunk offset atom */ -static int mov_write_stco_tag(AVIOContext *pb, MOVTrack *track) -{ - int i; - int mode64 = is_co64_required(track); // use 32 bit size variant if possible - int64_t pos = avio_tell(pb); - avio_wb32(pb, 0); /* size */ - if (mode64) - ffio_wfourcc(pb, "co64"); - else - ffio_wfourcc(pb, "stco"); - avio_wb32(pb, 0); /* version & flags */ - avio_wb32(pb, track->chunkCount); /* entry count */ - for (i=0; ientry; i++) { - if(!track->cluster[i].chunkNum) - continue; - if(mode64 == 1) - avio_wb64(pb, track->cluster[i].pos + track->data_offset); - else - avio_wb32(pb, track->cluster[i].pos + track->data_offset); - } - return update_size(pb, pos); -} - -/* Sample size atom */ -static int mov_write_stsz_tag(AVIOContext *pb, MOVTrack *track) -{ - int equalChunks = 1; - int i, j, entries = 0, tst = -1, oldtst = -1; - - int64_t pos = avio_tell(pb); - avio_wb32(pb, 0); /* size */ - ffio_wfourcc(pb, "stsz"); - avio_wb32(pb, 0); /* version & flags */ - - for (i=0; ientry; i++) { - tst = track->cluster[i].size/track->cluster[i].entries; - if(oldtst != -1 && tst != oldtst) { - equalChunks = 0; - } - oldtst = tst; - entries += track->cluster[i].entries; - } - if (equalChunks && track->entry) { - int sSize = track->entry ? track->cluster[0].size/track->cluster[0].entries : 0; - sSize = FFMAX(1, sSize); // adpcm mono case could make sSize == 0 - avio_wb32(pb, sSize); // sample size - avio_wb32(pb, entries); // sample count - } - else { - avio_wb32(pb, 0); // sample size - avio_wb32(pb, entries); // sample count - for (i=0; ientry; i++) { - for (j=0; jcluster[i].entries; j++) { - avio_wb32(pb, track->cluster[i].size / - track->cluster[i].entries); - } - } - } - return update_size(pb, pos); -} - -/* Sample to chunk atom */ -static int mov_write_stsc_tag(AVIOContext *pb, MOVTrack *track) -{ - int index = 0, oldval = -1, i; - int64_t entryPos, curpos; - - int64_t pos = avio_tell(pb); - avio_wb32(pb, 0); /* size */ - ffio_wfourcc(pb, "stsc"); - avio_wb32(pb, 0); // version & flags - entryPos = avio_tell(pb); - avio_wb32(pb, track->chunkCount); // entry count - for (i=0; ientry; i++) { - if (oldval != track->cluster[i].samples_in_chunk && track->cluster[i].chunkNum) - { - avio_wb32(pb, track->cluster[i].chunkNum); // first chunk - avio_wb32(pb, track->cluster[i].samples_in_chunk); // samples per chunk - avio_wb32(pb, 0x1); // sample description index - oldval = track->cluster[i].samples_in_chunk; - index++; - } - } - curpos = avio_tell(pb); - avio_seek(pb, entryPos, SEEK_SET); - avio_wb32(pb, index); // rewrite size - avio_seek(pb, curpos, SEEK_SET); - - return update_size(pb, pos); -} - -/* Sync sample atom */ -static int mov_write_stss_tag(AVIOContext *pb, MOVTrack *track, uint32_t flag) -{ - int64_t curpos, entryPos; - int i, index = 0; - int64_t pos = avio_tell(pb); - avio_wb32(pb, 0); // size - ffio_wfourcc(pb, flag == MOV_SYNC_SAMPLE ? "stss" : "stps"); - avio_wb32(pb, 0); // version & flags - entryPos = avio_tell(pb); - avio_wb32(pb, track->entry); // entry count - for (i=0; ientry; i++) { - if (track->cluster[i].flags & flag) { - avio_wb32(pb, i+1); - index++; - } - } - curpos = avio_tell(pb); - avio_seek(pb, entryPos, SEEK_SET); - avio_wb32(pb, index); // rewrite size - avio_seek(pb, curpos, SEEK_SET); - return update_size(pb, pos); -} - -static int mov_write_amr_tag(AVIOContext *pb, MOVTrack *track) -{ - avio_wb32(pb, 0x11); /* size */ - if (track->mode == MODE_MOV) ffio_wfourcc(pb, "samr"); - else ffio_wfourcc(pb, "damr"); - ffio_wfourcc(pb, "FFMP"); - avio_w8(pb, 0); /* decoder version */ - - avio_wb16(pb, 0x81FF); /* Mode set (all modes for AMR_NB) */ - avio_w8(pb, 0x00); /* Mode change period (no restriction) */ - avio_w8(pb, 0x01); /* Frames per sample */ - return 0x11; -} - -static int mov_write_ac3_tag(AVIOContext *pb, MOVTrack *track) -{ - GetBitContext gbc; - PutBitContext pbc; - uint8_t buf[3]; - int fscod, bsid, bsmod, acmod, lfeon, frmsizecod; - - if (track->vos_len < 7) - return -1; - - avio_wb32(pb, 11); - ffio_wfourcc(pb, "dac3"); - - init_get_bits(&gbc, track->vos_data + 4, (track->vos_len - 4) * 8); - fscod = get_bits(&gbc, 2); - frmsizecod = get_bits(&gbc, 6); - bsid = get_bits(&gbc, 5); - bsmod = get_bits(&gbc, 3); - acmod = get_bits(&gbc, 3); - if (acmod == 2) { - skip_bits(&gbc, 2); // dsurmod - } else { - if ((acmod & 1) && acmod != 1) - skip_bits(&gbc, 2); // cmixlev - if (acmod & 4) - skip_bits(&gbc, 2); // surmixlev - } - lfeon = get_bits1(&gbc); - - init_put_bits(&pbc, buf, sizeof(buf)); - put_bits(&pbc, 2, fscod); - put_bits(&pbc, 5, bsid); - put_bits(&pbc, 3, bsmod); - put_bits(&pbc, 3, acmod); - put_bits(&pbc, 1, lfeon); - put_bits(&pbc, 5, frmsizecod>>1); // bit_rate_code - put_bits(&pbc, 5, 0); // reserved - - flush_put_bits(&pbc); - avio_write(pb, buf, sizeof(buf)); - - return 11; -} - -/** - * This function writes extradata "as is". - * Extradata must be formatted like a valid atom (with size and tag). - */ -static int mov_write_extradata_tag(AVIOContext *pb, MOVTrack *track) -{ - avio_write(pb, track->enc->extradata, track->enc->extradata_size); - return track->enc->extradata_size; -} - -static int mov_write_enda_tag(AVIOContext *pb) -{ - avio_wb32(pb, 10); - ffio_wfourcc(pb, "enda"); - avio_wb16(pb, 1); /* little endian */ - return 10; -} - -static int mov_write_enda_tag_be(AVIOContext *pb) -{ - avio_wb32(pb, 10); - ffio_wfourcc(pb, "enda"); - avio_wb16(pb, 0); /* big endian */ - return 10; -} - -static void put_descr(AVIOContext *pb, int tag, unsigned int size) -{ - int i = 3; - avio_w8(pb, tag); - for(; i>0; i--) - avio_w8(pb, (size>>(7*i)) | 0x80); - avio_w8(pb, size & 0x7F); -} - -static unsigned compute_avg_bitrate(MOVTrack *track) -{ - uint64_t size = 0; - int i; - if (!track->track_duration) - return 0; - for (i = 0; i < track->entry; i++) - size += track->cluster[i].size; - return size * 8 * track->timescale / track->track_duration; -} - -static int mov_write_esds_tag(AVIOContext *pb, MOVTrack *track) // Basic -{ - int64_t pos = avio_tell(pb); - int decoder_specific_info_len = track->vos_len ? 5 + track->vos_len : 0; - unsigned avg_bitrate; - - avio_wb32(pb, 0); // size - ffio_wfourcc(pb, "esds"); - avio_wb32(pb, 0); // Version - - // ES descriptor - put_descr(pb, 0x03, 3 + 5+13 + decoder_specific_info_len + 5+1); - avio_wb16(pb, track->track_id); - avio_w8(pb, 0x00); // flags (= no flags) - - // DecoderConfig descriptor - put_descr(pb, 0x04, 13 + decoder_specific_info_len); - - // Object type indication - if ((track->enc->codec_id == AV_CODEC_ID_MP2 || - track->enc->codec_id == AV_CODEC_ID_MP3) && - track->enc->sample_rate > 24000) - avio_w8(pb, 0x6B); // 11172-3 - else - avio_w8(pb, ff_codec_get_tag(ff_mp4_obj_type, track->enc->codec_id)); - - // the following fields is made of 6 bits to identify the streamtype (4 for video, 5 for audio) - // plus 1 bit to indicate upstream and 1 bit set to 1 (reserved) - if(track->enc->codec_type == AVMEDIA_TYPE_AUDIO) - avio_w8(pb, 0x15); // flags (= Audiostream) - else - avio_w8(pb, 0x11); // flags (= Visualstream) - - avio_wb24(pb, track->enc->rc_buffer_size >> 3); // Buffersize DB - - avg_bitrate = compute_avg_bitrate(track); - // maxbitrate (FIXME should be max rate in any 1 sec window) - avio_wb32(pb, FFMAX3(track->enc->bit_rate, track->enc->rc_max_rate, avg_bitrate)); - avio_wb32(pb, avg_bitrate); - - if (track->vos_len) { - // DecoderSpecific info descriptor - put_descr(pb, 0x05, track->vos_len); - avio_write(pb, track->vos_data, track->vos_len); - } - - // SL descriptor - put_descr(pb, 0x06, 1); - avio_w8(pb, 0x02); - return update_size(pb, pos); -} - -static int mov_pcm_le_gt16(enum AVCodecID codec_id) -{ - return codec_id == AV_CODEC_ID_PCM_S24LE || - codec_id == AV_CODEC_ID_PCM_S32LE || - codec_id == AV_CODEC_ID_PCM_F32LE || - codec_id == AV_CODEC_ID_PCM_F64LE; -} - -static int mov_pcm_be_gt16(enum AVCodecID codec_id) -{ - return codec_id == AV_CODEC_ID_PCM_S24BE || - codec_id == AV_CODEC_ID_PCM_S32BE || - codec_id == AV_CODEC_ID_PCM_F32BE || - codec_id == AV_CODEC_ID_PCM_F64BE; -} - -static int mov_write_ms_tag(AVIOContext *pb, MOVTrack *track) -{ - int64_t pos = avio_tell(pb); - avio_wb32(pb, 0); - avio_wl32(pb, track->tag); // store it byteswapped - track->enc->codec_tag = av_bswap16(track->tag >> 16); - ff_put_wav_header(pb, track->enc); - return update_size(pb, pos); -} - -static int mov_write_wfex_tag(AVIOContext *pb, MOVTrack *track) -{ - int64_t pos = avio_tell(pb); - avio_wb32(pb, 0); - ffio_wfourcc(pb, "wfex"); - ff_put_wav_header(pb, track->enc); - return update_size(pb, pos); -} - -static int mov_write_chan_tag(AVIOContext *pb, MOVTrack *track) -{ - uint32_t layout_tag, bitmap; - int64_t pos = avio_tell(pb); - - layout_tag = ff_mov_get_channel_layout_tag(track->enc->codec_id, - track->enc->channel_layout, - &bitmap); - if (!layout_tag) { - av_log(track->enc, AV_LOG_WARNING, "not writing 'chan' tag due to " - "lack of channel information\n"); - return 0; - } - - avio_wb32(pb, 0); // Size - ffio_wfourcc(pb, "chan"); // Type - avio_w8(pb, 0); // Version - avio_wb24(pb, 0); // Flags - avio_wb32(pb, layout_tag); // mChannelLayoutTag - avio_wb32(pb, bitmap); // mChannelBitmap - avio_wb32(pb, 0); // mNumberChannelDescriptions - - return update_size(pb, pos); -} - -static int mov_write_wave_tag(AVIOContext *pb, MOVTrack *track) -{ - int64_t pos = avio_tell(pb); - - avio_wb32(pb, 0); /* size */ - ffio_wfourcc(pb, "wave"); - - if (track->enc->codec_id != AV_CODEC_ID_QDM2) { - avio_wb32(pb, 12); /* size */ - ffio_wfourcc(pb, "frma"); - avio_wl32(pb, track->tag); - } - - if (track->enc->codec_id == AV_CODEC_ID_AAC) { - /* useless atom needed by mplayer, ipod, not needed by quicktime */ - avio_wb32(pb, 12); /* size */ - ffio_wfourcc(pb, "mp4a"); - avio_wb32(pb, 0); - mov_write_esds_tag(pb, track); - } else if (mov_pcm_le_gt16(track->enc->codec_id)) { - mov_write_enda_tag(pb); - } else if (mov_pcm_be_gt16(track->enc->codec_id)) { - mov_write_enda_tag_be(pb); - } else if (track->enc->codec_id == AV_CODEC_ID_AMR_NB) { - mov_write_amr_tag(pb, track); - } else if (track->enc->codec_id == AV_CODEC_ID_AC3) { - mov_write_ac3_tag(pb, track); - } else if (track->enc->codec_id == AV_CODEC_ID_ALAC || - track->enc->codec_id == AV_CODEC_ID_QDM2) { - mov_write_extradata_tag(pb, track); - } else if (track->enc->codec_id == AV_CODEC_ID_ADPCM_MS || - track->enc->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV) { - mov_write_ms_tag(pb, track); - } - - avio_wb32(pb, 8); /* size */ - avio_wb32(pb, 0); /* null tag */ - - return update_size(pb, pos); -} - -static int mov_write_dvc1_structs(MOVTrack *track, uint8_t *buf) -{ - uint8_t *unescaped; - const uint8_t *start, *next, *end = track->vos_data + track->vos_len; - int unescaped_size, seq_found = 0; - int level = 0, interlace = 0; - int packet_seq = track->vc1_info.packet_seq; - int packet_entry = track->vc1_info.packet_entry; - int slices = track->vc1_info.slices; - PutBitContext pbc; - - if (track->start_dts == AV_NOPTS_VALUE) { - /* No packets written yet, vc1_info isn't authoritative yet. */ - /* Assume inline sequence and entry headers. This will be - * overwritten at the end if the file is seekable. */ - packet_seq = packet_entry = 1; - } - - unescaped = av_mallocz(track->vos_len + FF_INPUT_BUFFER_PADDING_SIZE); - if (!unescaped) - return AVERROR(ENOMEM); - start = find_next_marker(track->vos_data, end); - for (next = start; next < end; start = next) { - GetBitContext gb; - int size; - next = find_next_marker(start + 4, end); - size = next - start - 4; - if (size <= 0) - continue; - unescaped_size = vc1_unescape_buffer(start + 4, size, unescaped); - init_get_bits(&gb, unescaped, 8 * unescaped_size); - if (AV_RB32(start) == VC1_CODE_SEQHDR) { - int profile = get_bits(&gb, 2); - if (profile != PROFILE_ADVANCED) { - av_free(unescaped); - return AVERROR(ENOSYS); - } - seq_found = 1; - level = get_bits(&gb, 3); - /* chromaformat, frmrtq_postproc, bitrtq_postproc, postprocflag, - * width, height */ - skip_bits_long(&gb, 2 + 3 + 5 + 1 + 2*12); - skip_bits(&gb, 1); /* broadcast */ - interlace = get_bits1(&gb); - skip_bits(&gb, 4); /* tfcntrflag, finterpflag, reserved, psf */ - } - } - if (!seq_found) { - av_free(unescaped); - return AVERROR(ENOSYS); - } - - init_put_bits(&pbc, buf, 7); - /* VC1DecSpecStruc */ - put_bits(&pbc, 4, 12); /* profile - advanced */ - put_bits(&pbc, 3, level); - put_bits(&pbc, 1, 0); /* reserved */ - /* VC1AdvDecSpecStruc */ - put_bits(&pbc, 3, level); - put_bits(&pbc, 1, 0); /* cbr */ - put_bits(&pbc, 6, 0); /* reserved */ - put_bits(&pbc, 1, !interlace); /* no interlace */ - put_bits(&pbc, 1, !packet_seq); /* no multiple seq */ - put_bits(&pbc, 1, !packet_entry); /* no multiple entry */ - put_bits(&pbc, 1, !slices); /* no slice code */ - put_bits(&pbc, 1, 0); /* no bframe */ - put_bits(&pbc, 1, 0); /* reserved */ - put_bits32(&pbc, track->enc->time_base.den); /* framerate */ - flush_put_bits(&pbc); - - av_free(unescaped); - - return 0; -} - -static int mov_write_dvc1_tag(AVIOContext *pb, MOVTrack *track) -{ - uint8_t buf[7] = { 0 }; - int ret; - - if ((ret = mov_write_dvc1_structs(track, buf)) < 0) - return ret; - - avio_wb32(pb, track->vos_len + 8 + sizeof(buf)); - ffio_wfourcc(pb, "dvc1"); - track->vc1_info.struct_offset = avio_tell(pb); - avio_write(pb, buf, sizeof(buf)); - avio_write(pb, track->vos_data, track->vos_len); - - return 0; -} - -static int mov_write_glbl_tag(AVIOContext *pb, MOVTrack *track) -{ - avio_wb32(pb, track->vos_len + 8); - ffio_wfourcc(pb, "glbl"); - avio_write(pb, track->vos_data, track->vos_len); - return 8 + track->vos_len; -} - -/** - * Compute flags for 'lpcm' tag. - * See CoreAudioTypes and AudioStreamBasicDescription at Apple. - */ -static int mov_get_lpcm_flags(enum AVCodecID codec_id) -{ - switch (codec_id) { - case AV_CODEC_ID_PCM_F32BE: - case AV_CODEC_ID_PCM_F64BE: - return 11; - case AV_CODEC_ID_PCM_F32LE: - case AV_CODEC_ID_PCM_F64LE: - return 9; - case AV_CODEC_ID_PCM_U8: - return 10; - case AV_CODEC_ID_PCM_S16BE: - case AV_CODEC_ID_PCM_S24BE: - case AV_CODEC_ID_PCM_S32BE: - return 14; - case AV_CODEC_ID_PCM_S8: - case AV_CODEC_ID_PCM_S16LE: - case AV_CODEC_ID_PCM_S24LE: - case AV_CODEC_ID_PCM_S32LE: - return 12; - default: - return 0; - } -} - -static int get_cluster_duration(MOVTrack *track, int cluster_idx) -{ - int64_t next_dts; - - if (cluster_idx >= track->entry) - return 0; - - if (cluster_idx + 1 == track->entry) - next_dts = track->track_duration + track->start_dts; - else - next_dts = track->cluster[cluster_idx + 1].dts; - - return next_dts - track->cluster[cluster_idx].dts; -} - -static int get_samples_per_packet(MOVTrack *track) -{ - int i, first_duration; - -// return track->enc->frame_size; - - /* use 1 for raw PCM */ - if (!track->audio_vbr) - return 1; - - /* check to see if duration is constant for all clusters */ - if (!track->entry) - return 0; - first_duration = get_cluster_duration(track, 0); - for (i = 1; i < track->entry; i++) { - if (get_cluster_duration(track, i) != first_duration) - return 0; - } - return first_duration; -} - -static int mov_write_audio_tag(AVIOContext *pb, MOVTrack *track) -{ - int64_t pos = avio_tell(pb); - int version = 0; - uint32_t tag = track->tag; - - if (track->mode == MODE_MOV) { - if (track->timescale > UINT16_MAX) { - if (mov_get_lpcm_flags(track->enc->codec_id)) - tag = AV_RL32("lpcm"); - version = 2; - } else if (track->audio_vbr || mov_pcm_le_gt16(track->enc->codec_id) || - mov_pcm_be_gt16(track->enc->codec_id) || - track->enc->codec_id == AV_CODEC_ID_ADPCM_MS || - track->enc->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV || - track->enc->codec_id == AV_CODEC_ID_QDM2) { - version = 1; - } - } - - avio_wb32(pb, 0); /* size */ - avio_wl32(pb, tag); // store it byteswapped - avio_wb32(pb, 0); /* Reserved */ - avio_wb16(pb, 0); /* Reserved */ - avio_wb16(pb, 1); /* Data-reference index, XXX == 1 */ - - /* SoundDescription */ - avio_wb16(pb, version); /* Version */ - avio_wb16(pb, 0); /* Revision level */ - avio_wb32(pb, 0); /* Reserved */ - - if (version == 2) { - avio_wb16(pb, 3); - avio_wb16(pb, 16); - avio_wb16(pb, 0xfffe); - avio_wb16(pb, 0); - avio_wb32(pb, 0x00010000); - avio_wb32(pb, 72); - avio_wb64(pb, av_double2int(track->enc->sample_rate)); - avio_wb32(pb, track->enc->channels); - avio_wb32(pb, 0x7F000000); - avio_wb32(pb, av_get_bits_per_sample(track->enc->codec_id)); - avio_wb32(pb, mov_get_lpcm_flags(track->enc->codec_id)); - avio_wb32(pb, track->sample_size); - avio_wb32(pb, get_samples_per_packet(track)); - } else { - if (track->mode == MODE_MOV) { - avio_wb16(pb, track->enc->channels); - if (track->enc->codec_id == AV_CODEC_ID_PCM_U8 || - track->enc->codec_id == AV_CODEC_ID_PCM_S8) - avio_wb16(pb, 8); /* bits per sample */ - else - avio_wb16(pb, 16); - avio_wb16(pb, track->audio_vbr ? -2 : 0); /* compression ID */ - } else { /* reserved for mp4/3gp */ - avio_wb16(pb, 2); - avio_wb16(pb, 16); - avio_wb16(pb, 0); - } - - avio_wb16(pb, 0); /* packet size (= 0) */ - avio_wb16(pb, track->enc->sample_rate <= UINT16_MAX ? - track->enc->sample_rate : 0); - avio_wb16(pb, 0); /* Reserved */ - } - - if(version == 1) { /* SoundDescription V1 extended info */ - if (mov_pcm_le_gt16(track->enc->codec_id) || - mov_pcm_be_gt16(track->enc->codec_id)) - avio_wb32(pb, 1); /* must be 1 for uncompressed formats */ - else - avio_wb32(pb, track->enc->frame_size); /* Samples per packet */ - avio_wb32(pb, track->sample_size / track->enc->channels); /* Bytes per packet */ - avio_wb32(pb, track->sample_size); /* Bytes per frame */ - avio_wb32(pb, 2); /* Bytes per sample */ - } - - if(track->mode == MODE_MOV && - (track->enc->codec_id == AV_CODEC_ID_AAC || - track->enc->codec_id == AV_CODEC_ID_AC3 || - track->enc->codec_id == AV_CODEC_ID_AMR_NB || - track->enc->codec_id == AV_CODEC_ID_ALAC || - track->enc->codec_id == AV_CODEC_ID_ADPCM_MS || - track->enc->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV || - track->enc->codec_id == AV_CODEC_ID_QDM2 || - (mov_pcm_le_gt16(track->enc->codec_id) && version==1) || - (mov_pcm_be_gt16(track->enc->codec_id) && version==1))) - mov_write_wave_tag(pb, track); - else if(track->tag == MKTAG('m','p','4','a')) - mov_write_esds_tag(pb, track); - else if(track->enc->codec_id == AV_CODEC_ID_AMR_NB) - mov_write_amr_tag(pb, track); - else if(track->enc->codec_id == AV_CODEC_ID_AC3) - mov_write_ac3_tag(pb, track); - else if(track->enc->codec_id == AV_CODEC_ID_ALAC) - mov_write_extradata_tag(pb, track); - else if (track->enc->codec_id == AV_CODEC_ID_WMAPRO) - mov_write_wfex_tag(pb, track); - else if (track->vos_len > 0) - mov_write_glbl_tag(pb, track); - - if (track->mode == MODE_MOV && track->enc->codec_type == AVMEDIA_TYPE_AUDIO) - mov_write_chan_tag(pb, track); - - return update_size(pb, pos); -} - -static int mov_write_d263_tag(AVIOContext *pb) -{ - avio_wb32(pb, 0xf); /* size */ - ffio_wfourcc(pb, "d263"); - ffio_wfourcc(pb, "FFMP"); - avio_w8(pb, 0); /* decoder version */ - /* FIXME use AVCodecContext level/profile, when encoder will set values */ - avio_w8(pb, 0xa); /* level */ - avio_w8(pb, 0); /* profile */ - return 0xf; -} - -static int mov_write_avcc_tag(AVIOContext *pb, MOVTrack *track) -{ - int64_t pos = avio_tell(pb); - - avio_wb32(pb, 0); - ffio_wfourcc(pb, "avcC"); - ff_isom_write_avcc(pb, track->vos_data, track->vos_len); - return update_size(pb, pos); -} - -/* also used by all avid codecs (dv, imx, meridien) and their variants */ -static int mov_write_avid_tag(AVIOContext *pb, MOVTrack *track) -{ - int i; - avio_wb32(pb, 24); /* size */ - ffio_wfourcc(pb, "ACLR"); - ffio_wfourcc(pb, "ACLR"); - ffio_wfourcc(pb, "0001"); - avio_wb32(pb, 2); /* yuv range: full 1 / normal 2 */ - avio_wb32(pb, 0); /* unknown */ - - avio_wb32(pb, 24); /* size */ - ffio_wfourcc(pb, "APRG"); - ffio_wfourcc(pb, "APRG"); - ffio_wfourcc(pb, "0001"); - avio_wb32(pb, 1); /* unknown */ - avio_wb32(pb, 0); /* unknown */ - - avio_wb32(pb, 120); /* size */ - ffio_wfourcc(pb, "ARES"); - ffio_wfourcc(pb, "ARES"); - ffio_wfourcc(pb, "0001"); - avio_wb32(pb, AV_RB32(track->vos_data + 0x28)); /* dnxhd cid, some id ? */ - avio_wb32(pb, track->enc->width); - /* values below are based on samples created with quicktime and avid codecs */ - if (track->vos_data[5] & 2) { // interlaced - avio_wb32(pb, track->enc->height/2); - avio_wb32(pb, 2); /* unknown */ - avio_wb32(pb, 0); /* unknown */ - avio_wb32(pb, 4); /* unknown */ - } else { - avio_wb32(pb, track->enc->height); - avio_wb32(pb, 1); /* unknown */ - avio_wb32(pb, 0); /* unknown */ - if (track->enc->height == 1080) - avio_wb32(pb, 5); /* unknown */ - else - avio_wb32(pb, 6); /* unknown */ - } - /* padding */ - for (i = 0; i < 10; i++) - avio_wb64(pb, 0); - - /* extra padding for stsd needed */ - avio_wb32(pb, 0); - return 0; -} - -static int mp4_get_codec_tag(AVFormatContext *s, MOVTrack *track) -{ - int tag = track->enc->codec_tag; - - if (!ff_codec_get_tag(ff_mp4_obj_type, track->enc->codec_id)) - return 0; - - if (track->enc->codec_id == AV_CODEC_ID_H264) tag = MKTAG('a','v','c','1'); - else if (track->enc->codec_id == AV_CODEC_ID_AC3) tag = MKTAG('a','c','-','3'); - else if (track->enc->codec_id == AV_CODEC_ID_DIRAC) tag = MKTAG('d','r','a','c'); - else if (track->enc->codec_id == AV_CODEC_ID_MOV_TEXT) tag = MKTAG('t','x','3','g'); - else if (track->enc->codec_id == AV_CODEC_ID_VC1) tag = MKTAG('v','c','-','1'); - else if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO) tag = MKTAG('m','p','4','v'); - else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO) tag = MKTAG('m','p','4','a'); - - return tag; -} - -static const AVCodecTag codec_ipod_tags[] = { - { AV_CODEC_ID_H264, MKTAG('a','v','c','1') }, - { AV_CODEC_ID_MPEG4, MKTAG('m','p','4','v') }, - { AV_CODEC_ID_AAC, MKTAG('m','p','4','a') }, - { AV_CODEC_ID_ALAC, MKTAG('a','l','a','c') }, - { AV_CODEC_ID_AC3, MKTAG('a','c','-','3') }, - { AV_CODEC_ID_MOV_TEXT, MKTAG('t','x','3','g') }, - { AV_CODEC_ID_MOV_TEXT, MKTAG('t','e','x','t') }, - { AV_CODEC_ID_NONE, 0 }, -}; - -static int ipod_get_codec_tag(AVFormatContext *s, MOVTrack *track) -{ - int tag = track->enc->codec_tag; - - // keep original tag for subs, ipod supports both formats - if (!(track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE && - (tag == MKTAG('t','x','3','g') || - tag == MKTAG('t','e','x','t')))) - tag = ff_codec_get_tag(codec_ipod_tags, track->enc->codec_id); - - if (!av_match_ext(s->filename, "m4a") && !av_match_ext(s->filename, "m4v")) - av_log(s, AV_LOG_WARNING, "Warning, extension is not .m4a nor .m4v " - "Quicktime/Ipod might not play the file\n"); - - return tag; -} - -static int mov_get_dv_codec_tag(AVFormatContext *s, MOVTrack *track) -{ - int tag; - - if (track->enc->width == 720) { /* SD */ - if (track->enc->height == 480) { /* NTSC */ - if (track->enc->pix_fmt == AV_PIX_FMT_YUV422P) tag = MKTAG('d','v','5','n'); - else tag = MKTAG('d','v','c',' '); - }else if (track->enc->pix_fmt == AV_PIX_FMT_YUV422P) tag = MKTAG('d','v','5','p'); - else if (track->enc->pix_fmt == AV_PIX_FMT_YUV420P) tag = MKTAG('d','v','c','p'); - else tag = MKTAG('d','v','p','p'); - } else if (track->enc->height == 720) { /* HD 720 line */ - if (track->enc->time_base.den == 50) tag = MKTAG('d','v','h','q'); - else tag = MKTAG('d','v','h','p'); - } else if (track->enc->height == 1080) { /* HD 1080 line */ - if (track->enc->time_base.den == 25) tag = MKTAG('d','v','h','5'); - else tag = MKTAG('d','v','h','6'); - } else { - av_log(s, AV_LOG_ERROR, "unsupported height for dv codec\n"); - return 0; - } - - return tag; -} - -static const struct { - enum AVPixelFormat pix_fmt; - uint32_t tag; - unsigned bps; -} mov_pix_fmt_tags[] = { - { AV_PIX_FMT_YUYV422, MKTAG('y','u','v','2'), 0 }, - { AV_PIX_FMT_YUYV422, MKTAG('y','u','v','s'), 0 }, - { AV_PIX_FMT_UYVY422, MKTAG('2','v','u','y'), 0 }, - { AV_PIX_FMT_RGB555BE,MKTAG('r','a','w',' '), 16 }, - { AV_PIX_FMT_RGB555LE,MKTAG('L','5','5','5'), 16 }, - { AV_PIX_FMT_RGB565LE,MKTAG('L','5','6','5'), 16 }, - { AV_PIX_FMT_RGB565BE,MKTAG('B','5','6','5'), 16 }, - { AV_PIX_FMT_GRAY16BE,MKTAG('b','1','6','g'), 16 }, - { AV_PIX_FMT_RGB24, MKTAG('r','a','w',' '), 24 }, - { AV_PIX_FMT_BGR24, MKTAG('2','4','B','G'), 24 }, - { AV_PIX_FMT_ARGB, MKTAG('r','a','w',' '), 32 }, - { AV_PIX_FMT_BGRA, MKTAG('B','G','R','A'), 32 }, - { AV_PIX_FMT_RGBA, MKTAG('R','G','B','A'), 32 }, - { AV_PIX_FMT_ABGR, MKTAG('A','B','G','R'), 32 }, - { AV_PIX_FMT_RGB48BE, MKTAG('b','4','8','r'), 48 }, -}; - -static int mov_get_rawvideo_codec_tag(AVFormatContext *s, MOVTrack *track) -{ - int tag = track->enc->codec_tag; - int i; - - for (i = 0; i < FF_ARRAY_ELEMS(mov_pix_fmt_tags); i++) { - if (track->enc->pix_fmt == mov_pix_fmt_tags[i].pix_fmt) { - tag = mov_pix_fmt_tags[i].tag; - track->enc->bits_per_coded_sample = mov_pix_fmt_tags[i].bps; - if (track->enc->codec_tag == mov_pix_fmt_tags[i].tag) - break; - } - } - - return tag; -} - -static int mov_get_codec_tag(AVFormatContext *s, MOVTrack *track) -{ - int tag = track->enc->codec_tag; - - if (!tag || (track->enc->strict_std_compliance >= FF_COMPLIANCE_NORMAL && - (track->enc->codec_id == AV_CODEC_ID_DVVIDEO || - track->enc->codec_id == AV_CODEC_ID_RAWVIDEO || - track->enc->codec_id == AV_CODEC_ID_H263 || - av_get_bits_per_sample(track->enc->codec_id)))) { // pcm audio - if (track->enc->codec_id == AV_CODEC_ID_DVVIDEO) - tag = mov_get_dv_codec_tag(s, track); - else if (track->enc->codec_id == AV_CODEC_ID_RAWVIDEO) - tag = mov_get_rawvideo_codec_tag(s, track); - else if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO) { - tag = ff_codec_get_tag(ff_codec_movvideo_tags, track->enc->codec_id); - if (!tag) { // if no mac fcc found, try with Microsoft tags - tag = ff_codec_get_tag(ff_codec_bmp_tags, track->enc->codec_id); - if (tag) - av_log(s, AV_LOG_WARNING, "Using MS style video codec tag, " - "the file may be unplayable!\n"); - } - } else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO) { - tag = ff_codec_get_tag(ff_codec_movaudio_tags, track->enc->codec_id); - if (!tag) { // if no mac fcc found, try with Microsoft tags - int ms_tag = ff_codec_get_tag(ff_codec_wav_tags, track->enc->codec_id); - if (ms_tag) { - tag = MKTAG('m', 's', ((ms_tag >> 8) & 0xff), (ms_tag & 0xff)); - av_log(s, AV_LOG_WARNING, "Using MS style audio codec tag, " - "the file may be unplayable!\n"); - } - } - } else if (track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE) - tag = ff_codec_get_tag(ff_codec_movsubtitle_tags, track->enc->codec_id); - } - - return tag; -} - -static const AVCodecTag codec_3gp_tags[] = { - { AV_CODEC_ID_H263, MKTAG('s','2','6','3') }, - { AV_CODEC_ID_H264, MKTAG('a','v','c','1') }, - { AV_CODEC_ID_MPEG4, MKTAG('m','p','4','v') }, - { AV_CODEC_ID_AAC, MKTAG('m','p','4','a') }, - { AV_CODEC_ID_AMR_NB, MKTAG('s','a','m','r') }, - { AV_CODEC_ID_AMR_WB, MKTAG('s','a','w','b') }, - { AV_CODEC_ID_MOV_TEXT, MKTAG('t','x','3','g') }, - { AV_CODEC_ID_NONE, 0 }, -}; - -static const AVCodecTag codec_f4v_tags[] = { // XXX: add GIF/PNG/JPEG? - { AV_CODEC_ID_MP3, MKTAG('.','m','p','3') }, - { AV_CODEC_ID_AAC, MKTAG('m','p','4','a') }, - { AV_CODEC_ID_H264, MKTAG('a','v','c','1') }, - { AV_CODEC_ID_VP6F, MKTAG('V','P','6','F') }, - { AV_CODEC_ID_NONE, 0 }, -}; - -static int mov_find_codec_tag(AVFormatContext *s, MOVTrack *track) -{ - int tag; - - if (track->mode == MODE_MP4 || track->mode == MODE_PSP) - tag = mp4_get_codec_tag(s, track); - else if (track->mode == MODE_ISM) { - tag = mp4_get_codec_tag(s, track); - if (!tag && track->enc->codec_id == AV_CODEC_ID_WMAPRO) - tag = MKTAG('w', 'm', 'a', ' '); - } else if (track->mode == MODE_IPOD) - tag = ipod_get_codec_tag(s, track); - else if (track->mode & MODE_3GP) - tag = ff_codec_get_tag(codec_3gp_tags, track->enc->codec_id); - else if (track->mode & MODE_F4V) - tag = ff_codec_get_tag(codec_f4v_tags, track->enc->codec_id); - else - tag = mov_get_codec_tag(s, track); - - return tag; -} - -/** Write uuid atom. - * Needed to make file play in iPods running newest firmware - * goes after avcC atom in moov.trak.mdia.minf.stbl.stsd.avc1 - */ -static int mov_write_uuid_tag_ipod(AVIOContext *pb) -{ - avio_wb32(pb, 28); - ffio_wfourcc(pb, "uuid"); - avio_wb32(pb, 0x6b6840f2); - avio_wb32(pb, 0x5f244fc5); - avio_wb32(pb, 0xba39a51b); - avio_wb32(pb, 0xcf0323f3); - avio_wb32(pb, 0x0); - return 28; -} - -static const uint16_t fiel_data[] = { - 0x0000, 0x0100, 0x0201, 0x0206, 0x0209, 0x020e -}; - -static int mov_write_fiel_tag(AVIOContext *pb, MOVTrack *track) -{ - unsigned mov_field_order = 0; - if (track->enc->field_order < FF_ARRAY_ELEMS(fiel_data)) - mov_field_order = fiel_data[track->enc->field_order]; - else - return 0; - avio_wb32(pb, 10); - ffio_wfourcc(pb, "fiel"); - avio_wb16(pb, mov_field_order); - return 10; -} - -static int mov_write_subtitle_tag(AVIOContext *pb, MOVTrack *track) -{ - int64_t pos = avio_tell(pb); - avio_wb32(pb, 0); /* size */ - avio_wl32(pb, track->tag); // store it byteswapped - avio_wb32(pb, 0); /* Reserved */ - avio_wb16(pb, 0); /* Reserved */ - avio_wb16(pb, 1); /* Data-reference index */ - - if (track->enc->extradata_size) - avio_write(pb, track->enc->extradata, track->enc->extradata_size); - - return update_size(pb, pos); -} - -static int mov_write_pasp_tag(AVIOContext *pb, MOVTrack *track) -{ - AVRational sar; - av_reduce(&sar.num, &sar.den, track->enc->sample_aspect_ratio.num, - track->enc->sample_aspect_ratio.den, INT_MAX); - - avio_wb32(pb, 16); - ffio_wfourcc(pb, "pasp"); - avio_wb32(pb, sar.num); - avio_wb32(pb, sar.den); - return 16; -} - -static int mov_write_video_tag(AVIOContext *pb, MOVTrack *track) -{ - int64_t pos = avio_tell(pb); - char compressor_name[32] = { 0 }; - - avio_wb32(pb, 0); /* size */ - avio_wl32(pb, track->tag); // store it byteswapped - avio_wb32(pb, 0); /* Reserved */ - avio_wb16(pb, 0); /* Reserved */ - avio_wb16(pb, 1); /* Data-reference index */ - - avio_wb16(pb, 0); /* Codec stream version */ - avio_wb16(pb, 0); /* Codec stream revision (=0) */ - if (track->mode == MODE_MOV) { - ffio_wfourcc(pb, "FFMP"); /* Vendor */ - if(track->enc->codec_id == AV_CODEC_ID_RAWVIDEO) { - avio_wb32(pb, 0); /* Temporal Quality */ - avio_wb32(pb, 0x400); /* Spatial Quality = lossless*/ - } else { - avio_wb32(pb, 0x200); /* Temporal Quality = normal */ - avio_wb32(pb, 0x200); /* Spatial Quality = normal */ - } - } else { - avio_wb32(pb, 0); /* Reserved */ - avio_wb32(pb, 0); /* Reserved */ - avio_wb32(pb, 0); /* Reserved */ - } - avio_wb16(pb, track->enc->width); /* Video width */ - avio_wb16(pb, track->height); /* Video height */ - avio_wb32(pb, 0x00480000); /* Horizontal resolution 72dpi */ - avio_wb32(pb, 0x00480000); /* Vertical resolution 72dpi */ - avio_wb32(pb, 0); /* Data size (= 0) */ - avio_wb16(pb, 1); /* Frame count (= 1) */ - - /* FIXME not sure, ISO 14496-1 draft where it shall be set to 0 */ - if (track->mode == MODE_MOV && track->enc->codec && track->enc->codec->name) - av_strlcpy(compressor_name,track->enc->codec->name,32); - avio_w8(pb, strlen(compressor_name)); - avio_write(pb, compressor_name, 31); - - if (track->mode == MODE_MOV && track->enc->bits_per_coded_sample) - avio_wb16(pb, track->enc->bits_per_coded_sample); - else - avio_wb16(pb, 0x18); /* Reserved */ - avio_wb16(pb, 0xffff); /* Reserved */ - if(track->tag == MKTAG('m','p','4','v')) - mov_write_esds_tag(pb, track); - else if(track->enc->codec_id == AV_CODEC_ID_H263) - mov_write_d263_tag(pb); - else if(track->enc->codec_id == AV_CODEC_ID_AVUI || - track->enc->codec_id == AV_CODEC_ID_SVQ3) { - mov_write_extradata_tag(pb, track); - avio_wb32(pb, 0); - } else if(track->enc->codec_id == AV_CODEC_ID_DNXHD) - mov_write_avid_tag(pb, track); - else if(track->enc->codec_id == AV_CODEC_ID_H264) { - mov_write_avcc_tag(pb, track); - if(track->mode == MODE_IPOD) - mov_write_uuid_tag_ipod(pb); - } else if (track->enc->codec_id == AV_CODEC_ID_VC1 && track->vos_len > 0) - mov_write_dvc1_tag(pb, track); - else if (track->vos_len > 0) - mov_write_glbl_tag(pb, track); - - if (track->enc->codec_id != AV_CODEC_ID_H264 && - track->enc->codec_id != AV_CODEC_ID_MPEG4 && - track->enc->codec_id != AV_CODEC_ID_DNXHD) - if (track->enc->field_order != AV_FIELD_UNKNOWN) - mov_write_fiel_tag(pb, track); - - if (track->enc->sample_aspect_ratio.den && track->enc->sample_aspect_ratio.num && - track->enc->sample_aspect_ratio.den != track->enc->sample_aspect_ratio.num) { - mov_write_pasp_tag(pb, track); - } - - return update_size(pb, pos); -} - -static int mov_write_tmcd_tag(AVIOContext *pb, MOVTrack *track) -{ - int64_t pos = avio_tell(pb); - int frame_duration = av_rescale(track->timescale, track->enc->time_base.num, track->enc->time_base.den); - int nb_frames = 1.0/av_q2d(track->enc->time_base) + 0.5; - - if (nb_frames > 255) { - av_log(NULL, AV_LOG_ERROR, "fps %d is too large\n", nb_frames); - return AVERROR(EINVAL); - } - - avio_wb32(pb, 0); /* size */ - ffio_wfourcc(pb, "tmcd"); /* Data format */ - avio_wb32(pb, 0); /* Reserved */ - avio_wb32(pb, 1); /* Data reference index */ - avio_wb32(pb, 0); /* Flags */ - avio_wb32(pb, track->timecode_flags); /* Flags (timecode) */ - avio_wb32(pb, track->timescale); /* Timescale */ - avio_wb32(pb, frame_duration); /* Frame duration */ - avio_w8(pb, nb_frames); /* Number of frames */ - avio_wb24(pb, 0); /* Reserved */ - /* TODO: source reference string */ - return update_size(pb, pos); -} - -static int mov_write_rtp_tag(AVIOContext *pb, MOVTrack *track) -{ - int64_t pos = avio_tell(pb); - avio_wb32(pb, 0); /* size */ - ffio_wfourcc(pb, "rtp "); - avio_wb32(pb, 0); /* Reserved */ - avio_wb16(pb, 0); /* Reserved */ - avio_wb16(pb, 1); /* Data-reference index */ - - avio_wb16(pb, 1); /* Hint track version */ - avio_wb16(pb, 1); /* Highest compatible version */ - avio_wb32(pb, track->max_packet_size); /* Max packet size */ - - avio_wb32(pb, 12); /* size */ - ffio_wfourcc(pb, "tims"); - avio_wb32(pb, track->timescale); - - return update_size(pb, pos); -} - -static int mov_write_stsd_tag(AVIOContext *pb, MOVTrack *track) -{ - int64_t pos = avio_tell(pb); - avio_wb32(pb, 0); /* size */ - ffio_wfourcc(pb, "stsd"); - avio_wb32(pb, 0); /* version & flags */ - avio_wb32(pb, 1); /* entry count */ - if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO) - mov_write_video_tag(pb, track); - else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO) - mov_write_audio_tag(pb, track); - else if (track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE) - mov_write_subtitle_tag(pb, track); - else if (track->enc->codec_tag == MKTAG('r','t','p',' ')) - mov_write_rtp_tag(pb, track); - else if (track->enc->codec_tag == MKTAG('t','m','c','d')) - mov_write_tmcd_tag(pb, track); - return update_size(pb, pos); -} - -static int mov_write_ctts_tag(AVIOContext *pb, MOVTrack *track) -{ - MOVStts *ctts_entries; - uint32_t entries = 0; - uint32_t atom_size; - int i; - - ctts_entries = av_malloc((track->entry + 1) * sizeof(*ctts_entries)); /* worst case */ - ctts_entries[0].count = 1; - ctts_entries[0].duration = track->cluster[0].cts; - for (i=1; ientry; i++) { - if (track->cluster[i].cts == ctts_entries[entries].duration) { - ctts_entries[entries].count++; /* compress */ - } else { - entries++; - ctts_entries[entries].duration = track->cluster[i].cts; - ctts_entries[entries].count = 1; - } - } - entries++; /* last one */ - atom_size = 16 + (entries * 8); - avio_wb32(pb, atom_size); /* size */ - ffio_wfourcc(pb, "ctts"); - avio_wb32(pb, 0); /* version & flags */ - avio_wb32(pb, entries); /* entry count */ - for (i=0; ienc->codec_type == AVMEDIA_TYPE_AUDIO && !track->audio_vbr) { - stts_entries = av_malloc(sizeof(*stts_entries)); /* one entry */ - stts_entries[0].count = track->sample_count; - stts_entries[0].duration = 1; - entries = 1; - } else { - stts_entries = track->entry ? - av_malloc(track->entry * sizeof(*stts_entries)) : /* worst case */ - NULL; - for (i=0; ientry; i++) { - int duration = get_cluster_duration(track, i); - if (i && duration == stts_entries[entries].duration) { - stts_entries[entries].count++; /* compress */ - } else { - entries++; - stts_entries[entries].duration = duration; - stts_entries[entries].count = 1; - } - } - entries++; /* last one */ - } - atom_size = 16 + (entries * 8); - avio_wb32(pb, atom_size); /* size */ - ffio_wfourcc(pb, "stts"); - avio_wb32(pb, 0); /* version & flags */ - avio_wb32(pb, entries); /* entry count */ - for (i=0; ienc->codec_type == AVMEDIA_TYPE_VIDEO || - track->enc->codec_tag == MKTAG('r','t','p',' ')) && - track->has_keyframes && track->has_keyframes < track->entry) - mov_write_stss_tag(pb, track, MOV_SYNC_SAMPLE); - if (track->mode == MODE_MOV && track->flags & MOV_TRACK_STPS) - mov_write_stss_tag(pb, track, MOV_PARTIAL_SYNC_SAMPLE); - if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO && - track->flags & MOV_TRACK_CTTS) - mov_write_ctts_tag(pb, track); - mov_write_stsc_tag(pb, track); - mov_write_stsz_tag(pb, track); - mov_write_stco_tag(pb, track); - return update_size(pb, pos); -} - -static int mov_write_dinf_tag(AVIOContext *pb) -{ - int64_t pos = avio_tell(pb); - avio_wb32(pb, 0); /* size */ - ffio_wfourcc(pb, "dinf"); - mov_write_dref_tag(pb); - return update_size(pb, pos); -} - -static int mov_write_nmhd_tag(AVIOContext *pb) -{ - avio_wb32(pb, 12); - ffio_wfourcc(pb, "nmhd"); - avio_wb32(pb, 0); - return 12; -} - -static int mov_write_tcmi_tag(AVIOContext *pb, MOVTrack *track) -{ - int64_t pos = avio_tell(pb); - const char *font = "Lucida Grande"; - avio_wb32(pb, 0); /* size */ - ffio_wfourcc(pb, "tcmi"); /* timecode media information atom */ - avio_wb32(pb, 0); /* version & flags */ - avio_wb16(pb, 0); /* text font */ - avio_wb16(pb, 0); /* text face */ - avio_wb16(pb, 12); /* text size */ - avio_wb16(pb, 0); /* (unknown, not in the QT specs...) */ - avio_wb16(pb, 0x0000); /* text color (red) */ - avio_wb16(pb, 0x0000); /* text color (green) */ - avio_wb16(pb, 0x0000); /* text color (blue) */ - avio_wb16(pb, 0xffff); /* background color (red) */ - avio_wb16(pb, 0xffff); /* background color (green) */ - avio_wb16(pb, 0xffff); /* background color (blue) */ - avio_w8(pb, strlen(font)); /* font len (part of the pascal string) */ - avio_write(pb, font, strlen(font)); /* font name */ - return update_size(pb, pos); -} - -static int mov_write_gmhd_tag(AVIOContext *pb, MOVTrack *track) -{ - int64_t pos = avio_tell(pb); - avio_wb32(pb, 0); /* size */ - ffio_wfourcc(pb, "gmhd"); - avio_wb32(pb, 0x18); /* gmin size */ - ffio_wfourcc(pb, "gmin");/* generic media info */ - avio_wb32(pb, 0); /* version & flags */ - avio_wb16(pb, 0x40); /* graphics mode = */ - avio_wb16(pb, 0x8000); /* opColor (r?) */ - avio_wb16(pb, 0x8000); /* opColor (g?) */ - avio_wb16(pb, 0x8000); /* opColor (b?) */ - avio_wb16(pb, 0); /* balance */ - avio_wb16(pb, 0); /* reserved */ - - /* - * This special text atom is required for - * Apple Quicktime chapters. The contents - * don't appear to be documented, so the - * bytes are copied verbatim. - */ - if (track->tag != MKTAG('c','6','0','8')) { - avio_wb32(pb, 0x2C); /* size */ - ffio_wfourcc(pb, "text"); - avio_wb16(pb, 0x01); - avio_wb32(pb, 0x00); - avio_wb32(pb, 0x00); - avio_wb32(pb, 0x00); - avio_wb32(pb, 0x01); - avio_wb32(pb, 0x00); - avio_wb32(pb, 0x00); - avio_wb32(pb, 0x00); - avio_wb32(pb, 0x00004000); - avio_wb16(pb, 0x0000); - } - - if (track->enc->codec_tag == MKTAG('t','m','c','d')) { - int64_t tmcd_pos = avio_tell(pb); - avio_wb32(pb, 0); /* size */ - ffio_wfourcc(pb, "tmcd"); - mov_write_tcmi_tag(pb, track); - update_size(pb, tmcd_pos); - } - return update_size(pb, pos); -} - -static int mov_write_smhd_tag(AVIOContext *pb) -{ - avio_wb32(pb, 16); /* size */ - ffio_wfourcc(pb, "smhd"); - avio_wb32(pb, 0); /* version & flags */ - avio_wb16(pb, 0); /* reserved (balance, normally = 0) */ - avio_wb16(pb, 0); /* reserved */ - return 16; -} - -static int mov_write_vmhd_tag(AVIOContext *pb) -{ - avio_wb32(pb, 0x14); /* size (always 0x14) */ - ffio_wfourcc(pb, "vmhd"); - avio_wb32(pb, 0x01); /* version & flags */ - avio_wb64(pb, 0); /* reserved (graphics mode = copy) */ - return 0x14; -} - -static int mov_write_hdlr_tag(AVIOContext *pb, MOVTrack *track) -{ - const char *hdlr, *descr = NULL, *hdlr_type = NULL; - int64_t pos = avio_tell(pb); - - if (!track) { /* no media --> data handler */ - hdlr = "dhlr"; - hdlr_type = "url "; - descr = "DataHandler"; - } else { - hdlr = (track->mode == MODE_MOV) ? "mhlr" : "\0\0\0\0"; - if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO) { - hdlr_type = "vide"; - descr = "VideoHandler"; - } else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO) { - hdlr_type = "soun"; - descr = "SoundHandler"; - } else if (track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE) { - if (track->tag == MKTAG('c','6','0','8')) { - hdlr_type = "clcp"; - descr = "ClosedCaptionHandler"; - } else { - if (track->tag == MKTAG('t','x','3','g')) hdlr_type = "sbtl"; - else hdlr_type = "text"; - descr = "SubtitleHandler"; - } - } else if (track->enc->codec_tag == MKTAG('t','m','c','d')) { - hdlr_type = "tmcd"; - descr = "TimeCodeHandler"; - } else if (track->enc->codec_tag == MKTAG('r','t','p',' ')) { - hdlr_type = "hint"; - descr = "HintHandler"; - } else { - hdlr = "dhlr"; - hdlr_type = "url "; - descr = "DataHandler"; - } - } - - avio_wb32(pb, 0); /* size */ - ffio_wfourcc(pb, "hdlr"); - avio_wb32(pb, 0); /* Version & flags */ - avio_write(pb, hdlr, 4); /* handler */ - ffio_wfourcc(pb, hdlr_type); /* handler type */ - avio_wb32(pb ,0); /* reserved */ - avio_wb32(pb ,0); /* reserved */ - avio_wb32(pb ,0); /* reserved */ - if (!track || track->mode == MODE_MOV) - avio_w8(pb, strlen(descr)); /* pascal string */ - avio_write(pb, descr, strlen(descr)); /* handler description */ - if (track && track->mode != MODE_MOV) - avio_w8(pb, 0); /* c string */ - return update_size(pb, pos); -} - -static int mov_write_hmhd_tag(AVIOContext *pb) -{ - /* This atom must be present, but leaving the values at zero - * seems harmless. */ - avio_wb32(pb, 28); /* size */ - ffio_wfourcc(pb, "hmhd"); - avio_wb32(pb, 0); /* version, flags */ - avio_wb16(pb, 0); /* maxPDUsize */ - avio_wb16(pb, 0); /* avgPDUsize */ - avio_wb32(pb, 0); /* maxbitrate */ - avio_wb32(pb, 0); /* avgbitrate */ - avio_wb32(pb, 0); /* reserved */ - return 28; -} - -static int mov_write_minf_tag(AVIOContext *pb, MOVTrack *track) -{ - int64_t pos = avio_tell(pb); - avio_wb32(pb, 0); /* size */ - ffio_wfourcc(pb, "minf"); - if(track->enc->codec_type == AVMEDIA_TYPE_VIDEO) - mov_write_vmhd_tag(pb); - else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO) - mov_write_smhd_tag(pb); - else if (track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE) { - if (track->tag == MKTAG('t','e','x','t') || track->tag == MKTAG('c','6','0','8')) { - mov_write_gmhd_tag(pb, track); - } else { - mov_write_nmhd_tag(pb); - } - } else if (track->tag == MKTAG('t','m','c','d')) { - mov_write_gmhd_tag(pb, track); - } else if (track->tag == MKTAG('r','t','p',' ')) { - mov_write_hmhd_tag(pb); - } - if (track->mode == MODE_MOV) /* FIXME: Why do it for MODE_MOV only ? */ - mov_write_hdlr_tag(pb, NULL); - mov_write_dinf_tag(pb); - mov_write_stbl_tag(pb, track); - return update_size(pb, pos); -} - -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); - avio_wb24(pb, 0); /* flags */ - if (version == 1) { - avio_wb64(pb, track->time); - avio_wb64(pb, track->time); - } else { - avio_wb32(pb, track->time); /* creation time */ - avio_wb32(pb, track->time); /* modification time */ - } - avio_wb32(pb, track->timescale); /* time scale (sample rate for audio) */ - 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) */ - - if(version!=0 && track->mode == MODE_MOV){ - av_log(NULL, AV_LOG_ERROR, - "FATAL error, file duration too long for timebase, this file will not be\n" - "playable with quicktime. Choose a different timebase or a different\n" - "container format\n"); - } - - return 32; -} - -static int mov_write_mdia_tag(AVIOContext *pb, MOVTrack *track) -{ - int64_t pos = avio_tell(pb); - avio_wb32(pb, 0); /* size */ - ffio_wfourcc(pb, "mdia"); - mov_write_mdhd_tag(pb, track); - mov_write_hdlr_tag(pb, track); - mov_write_minf_tag(pb, track); - return update_size(pb, pos); -} - -/* transformation matrix - |a b u| - |c d v| - |tx ty w| */ -static void write_matrix(AVIOContext *pb, int16_t a, int16_t b, int16_t c, - int16_t d, int16_t tx, int16_t ty) -{ - avio_wb32(pb, a << 16); /* 16.16 format */ - avio_wb32(pb, b << 16); /* 16.16 format */ - avio_wb32(pb, 0); /* u in 2.30 format */ - avio_wb32(pb, c << 16); /* 16.16 format */ - avio_wb32(pb, d << 16); /* 16.16 format */ - avio_wb32(pb, 0); /* v in 2.30 format */ - avio_wb32(pb, tx << 16); /* 16.16 format */ - avio_wb32(pb, ty << 16); /* 16.16 format */ - avio_wb32(pb, 1 << 30); /* w in 2.30 format */ -} - -static int mov_write_tkhd_tag(AVIOContext *pb, MOVTrack *track, AVStream *st) -{ - int64_t duration = av_rescale_rnd(track->track_duration, MOV_TIMESCALE, - track->timescale, AV_ROUND_UP); - int version = duration < INT32_MAX ? 0 : 1; - int rotation = 0; - - 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); - avio_wb24(pb, track->secondary ? 0x2 : 0xf); /* flags (first track enabled) */ - if (version == 1) { - avio_wb64(pb, track->time); - avio_wb64(pb, track->time); - } else { - avio_wb32(pb, track->time); /* creation time */ - avio_wb32(pb, track->time); /* modification time */ - } - avio_wb32(pb, track->track_id); /* track-id */ - avio_wb32(pb, 0); /* reserved */ - 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 */ - avio_wb16(pb, 0); /* layer */ - avio_wb16(pb, st ? st->codec->codec_type : 0); /* alternate group) */ - /* Volume, only for audio */ - if(track->enc->codec_type == AVMEDIA_TYPE_AUDIO) - avio_wb16(pb, 0x0100); - else - avio_wb16(pb, 0); - avio_wb16(pb, 0); /* reserved */ - - /* Matrix structure */ - if (st && st->metadata) { - AVDictionaryEntry *rot = av_dict_get(st->metadata, "rotate", NULL, 0); - rotation = (rot && rot->value) ? atoi(rot->value) : 0; - } - if (rotation == 90) { - write_matrix(pb, 0, 1, -1, 0, track->enc->height, 0); - } else if (rotation == 180) { - write_matrix(pb, -1, 0, 0, -1, track->enc->width, track->enc->height); - } else if (rotation == 270) { - write_matrix(pb, 0, -1, 1, 0, 0, track->enc->width); - } else { - write_matrix(pb, 1, 0, 0, 1, 0, 0); - } - /* Track width and height, for visual only */ - if(st && (track->enc->codec_type == AVMEDIA_TYPE_VIDEO || - track->enc->codec_type == AVMEDIA_TYPE_SUBTITLE)) { - if(track->mode == MODE_MOV) { - avio_wb32(pb, track->enc->width << 16); - avio_wb32(pb, track->height << 16); - } else { - double sample_aspect_ratio = av_q2d(st->sample_aspect_ratio); - if(!sample_aspect_ratio || track->height != track->enc->height) - sample_aspect_ratio = 1; - avio_wb32(pb, sample_aspect_ratio * track->enc->width*0x10000); - avio_wb32(pb, track->height*0x10000); - } - } - else { - avio_wb32(pb, 0); - avio_wb32(pb, 0); - } - return 0x5c; -} - -static int mov_write_tapt_tag(AVIOContext *pb, MOVTrack *track) -{ - int32_t width = av_rescale(track->enc->sample_aspect_ratio.num, track->enc->width, - track->enc->sample_aspect_ratio.den); - - int64_t pos = avio_tell(pb); - - avio_wb32(pb, 0); /* size */ - ffio_wfourcc(pb, "tapt"); - - avio_wb32(pb, 20); - ffio_wfourcc(pb, "clef"); - avio_wb32(pb, 0); - avio_wb32(pb, width << 16); - avio_wb32(pb, track->enc->height << 16); - - avio_wb32(pb, 20); - ffio_wfourcc(pb, "prof"); - avio_wb32(pb, 0); - avio_wb32(pb, width << 16); - avio_wb32(pb, track->enc->height << 16); - - avio_wb32(pb, 20); - ffio_wfourcc(pb, "enof"); - avio_wb32(pb, 0); - avio_wb32(pb, track->enc->width << 16); - avio_wb32(pb, track->enc->height << 16); - - return update_size(pb, pos); -} - -// This box seems important for the psp playback ... without it the movie seems to hang -static int mov_write_edts_tag(AVIOContext *pb, MOVTrack *track) -{ - int64_t duration = av_rescale_rnd(track->track_duration, MOV_TIMESCALE, - track->timescale, AV_ROUND_UP); - int version = duration < INT32_MAX ? 0 : 1; - int entry_size, entry_count, size; - int64_t delay, start_ct = track->cluster[0].cts; - delay = av_rescale_rnd(track->cluster[0].dts + start_ct, MOV_TIMESCALE, - track->timescale, AV_ROUND_DOWN); - version |= delay < INT32_MAX ? 0 : 1; - - entry_size = (version == 1) ? 20 : 12; - entry_count = 1 + (delay > 0); - size = 24 + entry_count * entry_size; - - /* write the atom data */ - avio_wb32(pb, size); - ffio_wfourcc(pb, "edts"); - avio_wb32(pb, size - 8); - ffio_wfourcc(pb, "elst"); - avio_w8(pb, version); - avio_wb24(pb, 0); /* flags */ - - avio_wb32(pb, entry_count); - if (delay > 0) { /* add an empty edit to delay presentation */ - if (version == 1) { - avio_wb64(pb, delay); - avio_wb64(pb, -1); - } else { - avio_wb32(pb, delay); - avio_wb32(pb, -1); - } - avio_wb32(pb, 0x00010000); - } else { - av_assert0(av_rescale_rnd(track->cluster[0].dts, MOV_TIMESCALE, track->timescale, AV_ROUND_DOWN) <= 0); - start_ct = -FFMIN(track->cluster[0].dts, 0); //FFMIN needed due to rounding - duration += delay; - } - - /* duration */ - if (version == 1) { - avio_wb64(pb, duration); - avio_wb64(pb, start_ct); - } else { - avio_wb32(pb, duration); - avio_wb32(pb, start_ct); - } - avio_wb32(pb, 0x00010000); - return size; -} - -static int mov_write_tref_tag(AVIOContext *pb, MOVTrack *track) -{ - avio_wb32(pb, 20); // size - ffio_wfourcc(pb, "tref"); - avio_wb32(pb, 12); // size (subatom) - avio_wl32(pb, track->tref_tag); - avio_wb32(pb, track->tref_id); - return 20; -} - -// goes at the end of each track! ... Critical for PSP playback ("Incompatible data" without it) -static int mov_write_uuid_tag_psp(AVIOContext *pb, MOVTrack *mov) -{ - avio_wb32(pb, 0x34); /* size ... reports as 28 in mp4box! */ - ffio_wfourcc(pb, "uuid"); - ffio_wfourcc(pb, "USMT"); - avio_wb32(pb, 0x21d24fce); - avio_wb32(pb, 0xbb88695c); - avio_wb32(pb, 0xfac9c740); - avio_wb32(pb, 0x1c); // another size here! - ffio_wfourcc(pb, "MTDT"); - avio_wb32(pb, 0x00010012); - avio_wb32(pb, 0x0a); - avio_wb32(pb, 0x55c40000); - avio_wb32(pb, 0x1); - avio_wb32(pb, 0x0); - return 0x34; -} - -static int mov_write_udta_sdp(AVIOContext *pb, MOVTrack *track) -{ - - AVFormatContext *ctx = track->rtp_ctx; - char buf[1000] = ""; - int len; - - ff_sdp_write_media(buf, sizeof(buf), ctx->streams[0], track->src_track, - NULL, NULL, 0, 0, ctx); - av_strlcatf(buf, sizeof(buf), "a=control:streamid=%d\r\n", track->track_id); - len = strlen(buf); - - avio_wb32(pb, len + 24); - ffio_wfourcc(pb, "udta"); - avio_wb32(pb, len + 16); - ffio_wfourcc(pb, "hnti"); - avio_wb32(pb, len + 8); - ffio_wfourcc(pb, "sdp "); - avio_write(pb, buf, len); - return len + 24; -} - -static int mov_write_trak_tag(AVIOContext *pb, MOVMuxContext *mov, - MOVTrack *track, AVStream *st) -{ - int64_t pos = avio_tell(pb); - avio_wb32(pb, 0); /* size */ - ffio_wfourcc(pb, "trak"); - mov_write_tkhd_tag(pb, track, st); - if (supports_edts(mov)) - mov_write_edts_tag(pb, track); // PSP Movies and several other cases require edts box - if (track->tref_tag) - mov_write_tref_tag(pb, track); - mov_write_mdia_tag(pb, track); - if (track->mode == MODE_PSP) - mov_write_uuid_tag_psp(pb,track); // PSP Movies require this uuid box - if (track->tag == MKTAG('r','t','p',' ')) - mov_write_udta_sdp(pb, track); - if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO && track->mode == MODE_MOV) { - double sample_aspect_ratio = av_q2d(st->sample_aspect_ratio); - if (st->sample_aspect_ratio.num && 1.0 != sample_aspect_ratio) - mov_write_tapt_tag(pb, track); - }; - return update_size(pb, pos); -} - -static int mov_write_iods_tag(AVIOContext *pb, MOVMuxContext *mov) -{ - int i, has_audio = 0, has_video = 0; - int64_t pos = avio_tell(pb); - int audio_profile = mov->iods_audio_profile; - int video_profile = mov->iods_video_profile; - for (i = 0; i < mov->nb_streams; i++) { - if(mov->tracks[i].entry > 0) { - has_audio |= mov->tracks[i].enc->codec_type == AVMEDIA_TYPE_AUDIO; - has_video |= mov->tracks[i].enc->codec_type == AVMEDIA_TYPE_VIDEO; - } - } - if (audio_profile < 0) - audio_profile = 0xFF - has_audio; - if (video_profile < 0) - video_profile = 0xFF - has_video; - avio_wb32(pb, 0x0); /* size */ - ffio_wfourcc(pb, "iods"); - avio_wb32(pb, 0); /* version & flags */ - put_descr(pb, 0x10, 7); - avio_wb16(pb, 0x004f); - avio_w8(pb, 0xff); - avio_w8(pb, 0xff); - avio_w8(pb, audio_profile); - avio_w8(pb, video_profile); - avio_w8(pb, 0xff); - return update_size(pb, pos); -} - -static int mov_write_trex_tag(AVIOContext *pb, MOVTrack *track) -{ - avio_wb32(pb, 0x20); /* size */ - ffio_wfourcc(pb, "trex"); - avio_wb32(pb, 0); /* version & flags */ - avio_wb32(pb, track->track_id); /* track ID */ - avio_wb32(pb, 1); /* default sample description index */ - avio_wb32(pb, 0); /* default sample duration */ - avio_wb32(pb, 0); /* default sample size */ - avio_wb32(pb, 0); /* default sample flags */ - return 0; -} - -static int mov_write_mvex_tag(AVIOContext *pb, MOVMuxContext *mov) -{ - int64_t pos = avio_tell(pb); - int i; - avio_wb32(pb, 0x0); /* size */ - ffio_wfourcc(pb, "mvex"); - for (i = 0; i < mov->nb_streams; i++) - mov_write_trex_tag(pb, &mov->tracks[i]); - return update_size(pb, pos); -} - -static int mov_write_mvhd_tag(AVIOContext *pb, MOVMuxContext *mov) -{ - int max_track_id = 1, i; - int64_t max_track_len_temp, max_track_len = 0; - int version; - - for (i=0; inb_streams; i++) { - if(mov->tracks[i].entry > 0) { - max_track_len_temp = av_rescale_rnd(mov->tracks[i].track_duration, - MOV_TIMESCALE, - mov->tracks[i].timescale, - AV_ROUND_UP); - if (max_track_len < max_track_len_temp) - max_track_len = max_track_len_temp; - if (max_track_id < mov->tracks[i].track_id) - max_track_id = mov->tracks[i].track_id; - } - } - - version = max_track_len < UINT32_MAX ? 0 : 1; - (version == 1) ? avio_wb32(pb, 120) : avio_wb32(pb, 108); /* size */ - ffio_wfourcc(pb, "mvhd"); - avio_w8(pb, version); - avio_wb24(pb, 0); /* flags */ - if (version == 1) { - avio_wb64(pb, mov->time); - avio_wb64(pb, mov->time); - } else { - avio_wb32(pb, mov->time); /* creation time */ - avio_wb32(pb, mov->time); /* modification time */ - } - avio_wb32(pb, MOV_TIMESCALE); - (version == 1) ? avio_wb64(pb, max_track_len) : avio_wb32(pb, max_track_len); /* duration of longest track */ - - avio_wb32(pb, 0x00010000); /* reserved (preferred rate) 1.0 = normal */ - avio_wb16(pb, 0x0100); /* reserved (preferred volume) 1.0 = normal */ - avio_wb16(pb, 0); /* reserved */ - avio_wb32(pb, 0); /* reserved */ - avio_wb32(pb, 0); /* reserved */ - - /* Matrix structure */ - write_matrix(pb, 1, 0, 0, 1, 0, 0); - - avio_wb32(pb, 0); /* reserved (preview time) */ - avio_wb32(pb, 0); /* reserved (preview duration) */ - avio_wb32(pb, 0); /* reserved (poster time) */ - avio_wb32(pb, 0); /* reserved (selection time) */ - avio_wb32(pb, 0); /* reserved (selection duration) */ - avio_wb32(pb, 0); /* reserved (current time) */ - avio_wb32(pb, max_track_id + 1); /* Next track id */ - return 0x6c; -} - -static int mov_write_itunes_hdlr_tag(AVIOContext *pb, MOVMuxContext *mov, - AVFormatContext *s) -{ - avio_wb32(pb, 33); /* size */ - ffio_wfourcc(pb, "hdlr"); - avio_wb32(pb, 0); - avio_wb32(pb, 0); - ffio_wfourcc(pb, "mdir"); - ffio_wfourcc(pb, "appl"); - avio_wb32(pb, 0); - avio_wb32(pb, 0); - avio_w8(pb, 0); - return 33; -} - -/* helper function to write a data tag with the specified string as data */ -static int mov_write_string_data_tag(AVIOContext *pb, const char *data, int lang, int long_style) -{ - if(long_style){ - int size = 16 + strlen(data); - avio_wb32(pb, size); /* size */ - ffio_wfourcc(pb, "data"); - avio_wb32(pb, 1); - avio_wb32(pb, 0); - avio_write(pb, data, strlen(data)); - return size; - }else{ - if (!lang) - lang = ff_mov_iso639_to_lang("und", 1); - avio_wb16(pb, strlen(data)); /* string length */ - avio_wb16(pb, lang); - avio_write(pb, data, strlen(data)); - return strlen(data) + 4; - } -} - -static int mov_write_string_tag(AVIOContext *pb, const char *name, const char *value, int lang, int long_style){ - int size = 0; - if (value && value[0]) { - int64_t pos = avio_tell(pb); - avio_wb32(pb, 0); /* size */ - ffio_wfourcc(pb, name); - mov_write_string_data_tag(pb, value, lang, long_style); - size = update_size(pb, pos); - } - return size; -} - -static int mov_write_string_metadata(AVFormatContext *s, AVIOContext *pb, - const char *name, const char *tag, - int long_style) -{ - int l, lang = 0, len, len2; - AVDictionaryEntry *t, *t2 = NULL; - char tag2[16]; - - if (!(t = av_dict_get(s->metadata, tag, NULL, 0))) - return 0; - - len = strlen(t->key); - snprintf(tag2, sizeof(tag2), "%s-", tag); - while ((t2 = av_dict_get(s->metadata, tag2, t2, AV_DICT_IGNORE_SUFFIX))) { - len2 = strlen(t2->key); - if (len2 == len+4 && !strcmp(t->value, t2->value) - && (l=ff_mov_iso639_to_lang(&t2->key[len2-3], 1)) >= 0) { - lang = l; - break; - } - } - return mov_write_string_tag(pb, name, t->value, lang, long_style); -} - -/* iTunes bpm number */ -static int mov_write_tmpo_tag(AVIOContext *pb, AVFormatContext *s) -{ - AVDictionaryEntry *t = av_dict_get(s->metadata, "tmpo", NULL, 0); - int size = 0, tmpo = t ? atoi(t->value) : 0; - if (tmpo) { - size = 26; - avio_wb32(pb, size); - ffio_wfourcc(pb, "tmpo"); - avio_wb32(pb, size-8); /* size */ - ffio_wfourcc(pb, "data"); - avio_wb32(pb, 0x15); //type specifier - avio_wb32(pb, 0); - avio_wb16(pb, tmpo); // data - } - return size; -} - -/* iTunes track number */ -static int mov_write_trkn_tag(AVIOContext *pb, MOVMuxContext *mov, - AVFormatContext *s) -{ - AVDictionaryEntry *t = av_dict_get(s->metadata, "track", NULL, 0); - int size = 0, track = t ? atoi(t->value) : 0; - if (track) { - avio_wb32(pb, 32); /* size */ - ffio_wfourcc(pb, "trkn"); - avio_wb32(pb, 24); /* size */ - ffio_wfourcc(pb, "data"); - avio_wb32(pb, 0); // 8 bytes empty - avio_wb32(pb, 0); - avio_wb16(pb, 0); // empty - avio_wb16(pb, track); // track number - avio_wb16(pb, 0); // total track number - avio_wb16(pb, 0); // empty - size = 32; - } - return size; -} - -static int mov_write_int8_metadata(AVFormatContext *s, AVIOContext *pb, - const char *name, const char *tag, - int len) -{ - AVDictionaryEntry *t = NULL; - uint8_t num; - - if (!(t = av_dict_get(s->metadata, tag, NULL, 0))) - return 0; - num = atoi(t->value); - - avio_wb32(pb, len+8); - ffio_wfourcc(pb, name); - if (len==4) avio_wb32(pb, num); - else avio_w8 (pb, num); - return len+8; -} - -/* iTunes meta data list */ -static int mov_write_ilst_tag(AVIOContext *pb, MOVMuxContext *mov, - AVFormatContext *s) -{ - int64_t pos = avio_tell(pb); - avio_wb32(pb, 0); /* size */ - ffio_wfourcc(pb, "ilst"); - mov_write_string_metadata(s, pb, "\251nam", "title" , 1); - mov_write_string_metadata(s, pb, "\251ART", "artist" , 1); - mov_write_string_metadata(s, pb, "aART", "album_artist", 1); - mov_write_string_metadata(s, pb, "\251wrt", "composer" , 1); - mov_write_string_metadata(s, pb, "\251alb", "album" , 1); - mov_write_string_metadata(s, pb, "\251day", "date" , 1); - mov_write_string_tag(pb, "\251too", LIBAVFORMAT_IDENT, 0, 1); - mov_write_string_metadata(s, pb, "\251cmt", "comment" , 1); - mov_write_string_metadata(s, pb, "\251gen", "genre" , 1); - mov_write_string_metadata(s, pb, "\251cpy", "copyright", 1); - mov_write_string_metadata(s, pb, "\251grp", "grouping" , 1); - mov_write_string_metadata(s, pb, "\251lyr", "lyrics" , 1); - mov_write_string_metadata(s, pb, "desc", "description",1); - mov_write_string_metadata(s, pb, "ldes", "synopsis" , 1); - mov_write_string_metadata(s, pb, "tvsh", "show" , 1); - mov_write_string_metadata(s, pb, "tven", "episode_id",1); - mov_write_string_metadata(s, pb, "tvnn", "network" , 1); - mov_write_int8_metadata (s, pb, "tves", "episode_sort",4); - mov_write_int8_metadata (s, pb, "tvsn", "season_number",4); - mov_write_int8_metadata (s, pb, "stik", "media_type",1); - mov_write_int8_metadata (s, pb, "hdvd", "hd_video", 1); - mov_write_int8_metadata (s, pb, "pgap", "gapless_playback",1); - mov_write_trkn_tag(pb, mov, s); - mov_write_tmpo_tag(pb, s); - return update_size(pb, pos); -} - -/* iTunes meta data tag */ -static int mov_write_meta_tag(AVIOContext *pb, MOVMuxContext *mov, - AVFormatContext *s) -{ - int size = 0; - int64_t pos = avio_tell(pb); - avio_wb32(pb, 0); /* size */ - ffio_wfourcc(pb, "meta"); - avio_wb32(pb, 0); - mov_write_itunes_hdlr_tag(pb, mov, s); - mov_write_ilst_tag(pb, mov, s); - size = update_size(pb, pos); - return size; -} - -static int utf8len(const uint8_t *b) -{ - int len=0; - int val; - while(*b){ - GET_UTF8(val, *b++, return -1;) - len++; - } - return len; -} - -static int ascii_to_wc(AVIOContext *pb, const uint8_t *b) -{ - int val; - while(*b){ - GET_UTF8(val, *b++, return -1;) - avio_wb16(pb, val); - } - avio_wb16(pb, 0x00); - return 0; -} - -static uint16_t language_code(const char *str) -{ - return (((str[0]-0x60) & 0x1F) << 10) + (((str[1]-0x60) & 0x1F) << 5) + ((str[2]-0x60) & 0x1F); -} - -static int mov_write_3gp_udta_tag(AVIOContext *pb, AVFormatContext *s, - const char *tag, const char *str) -{ - int64_t pos = avio_tell(pb); - AVDictionaryEntry *t = av_dict_get(s->metadata, str, NULL, 0); - if (!t || !utf8len(t->value)) - return 0; - avio_wb32(pb, 0); /* size */ - ffio_wfourcc(pb, tag); /* type */ - avio_wb32(pb, 0); /* version + flags */ - if (!strcmp(tag, "yrrc")) - avio_wb16(pb, atoi(t->value)); - else { - avio_wb16(pb, language_code("eng")); /* language */ - avio_write(pb, t->value, strlen(t->value)+1); /* UTF8 string value */ - if (!strcmp(tag, "albm") && - (t = av_dict_get(s->metadata, "track", NULL, 0))) - avio_w8(pb, atoi(t->value)); - } - return update_size(pb, pos); -} - -static int mov_write_chpl_tag(AVIOContext *pb, AVFormatContext *s) -{ - int64_t pos = avio_tell(pb); - int i, nb_chapters = FFMIN(s->nb_chapters, 255); - - avio_wb32(pb, 0); // size - ffio_wfourcc(pb, "chpl"); - avio_wb32(pb, 0x01000000); // version + flags - avio_wb32(pb, 0); // unknown - avio_w8(pb, nb_chapters); - - for (i = 0; i < nb_chapters; i++) { - AVChapter *c = s->chapters[i]; - AVDictionaryEntry *t; - avio_wb64(pb, av_rescale_q(c->start, c->time_base, (AVRational){1,10000000})); - - if ((t = av_dict_get(c->metadata, "title", NULL, 0))) { - int len = FFMIN(strlen(t->value), 255); - avio_w8(pb, len); - avio_write(pb, t->value, len); - } else - avio_w8(pb, 0); - } - return update_size(pb, pos); -} - -static int mov_write_udta_tag(AVIOContext *pb, MOVMuxContext *mov, - AVFormatContext *s) -{ - AVIOContext *pb_buf; - int i, ret, size; - uint8_t *buf; - - for (i = 0; i < s->nb_streams; i++) - if (mov->tracks[i].enc->flags & CODEC_FLAG_BITEXACT) { - return 0; - } - - ret = avio_open_dyn_buf(&pb_buf); - if(ret < 0) - return ret; - - if (mov->mode & MODE_3GP) { - mov_write_3gp_udta_tag(pb_buf, s, "perf", "artist"); - mov_write_3gp_udta_tag(pb_buf, s, "titl", "title"); - mov_write_3gp_udta_tag(pb_buf, s, "auth", "author"); - mov_write_3gp_udta_tag(pb_buf, s, "gnre", "genre"); - mov_write_3gp_udta_tag(pb_buf, s, "dscp", "comment"); - mov_write_3gp_udta_tag(pb_buf, s, "albm", "album"); - mov_write_3gp_udta_tag(pb_buf, s, "cprt", "copyright"); - mov_write_3gp_udta_tag(pb_buf, s, "yrrc", "date"); - } else if (mov->mode == MODE_MOV) { // the title field breaks gtkpod with mp4 and my suspicion is that stuff is not valid in mp4 - mov_write_string_metadata(s, pb_buf, "\251ART", "artist" , 0); - mov_write_string_metadata(s, pb_buf, "\251nam", "title" , 0); - mov_write_string_metadata(s, pb_buf, "\251aut", "author" , 0); - mov_write_string_metadata(s, pb_buf, "\251alb", "album" , 0); - mov_write_string_metadata(s, pb_buf, "\251day", "date" , 0); - mov_write_string_metadata(s, pb_buf, "\251swr", "encoder" , 0); - // currently ignored by mov.c - mov_write_string_metadata(s, pb_buf, "\251des", "comment" , 0); - // add support for libquicktime, this atom is also actually read by mov.c - mov_write_string_metadata(s, pb_buf, "\251cmt", "comment" , 0); - mov_write_string_metadata(s, pb_buf, "\251gen", "genre" , 0); - mov_write_string_metadata(s, pb_buf, "\251cpy", "copyright" , 0); - } else { - /* iTunes meta data */ - mov_write_meta_tag(pb_buf, mov, s); - } - - if (s->nb_chapters) - mov_write_chpl_tag(pb_buf, s); - - if ((size = avio_close_dyn_buf(pb_buf, &buf)) > 0) { - avio_wb32(pb, size+8); - ffio_wfourcc(pb, "udta"); - avio_write(pb, buf, size); - } - av_free(buf); - - return 0; -} - -static void mov_write_psp_udta_tag(AVIOContext *pb, - const char *str, const char *lang, int type) -{ - int len = utf8len(str)+1; - if(len<=0) - return; - avio_wb16(pb, len*2+10); /* size */ - avio_wb32(pb, type); /* type */ - avio_wb16(pb, language_code(lang)); /* language */ - avio_wb16(pb, 0x01); /* ? */ - ascii_to_wc(pb, str); -} - -static int mov_write_uuidusmt_tag(AVIOContext *pb, AVFormatContext *s) -{ - AVDictionaryEntry *title = av_dict_get(s->metadata, "title", NULL, 0); - int64_t pos, pos2; - - if (title) { - pos = avio_tell(pb); - avio_wb32(pb, 0); /* size placeholder*/ - ffio_wfourcc(pb, "uuid"); - ffio_wfourcc(pb, "USMT"); - avio_wb32(pb, 0x21d24fce); /* 96 bit UUID */ - avio_wb32(pb, 0xbb88695c); - avio_wb32(pb, 0xfac9c740); - - pos2 = avio_tell(pb); - avio_wb32(pb, 0); /* size placeholder*/ - ffio_wfourcc(pb, "MTDT"); - avio_wb16(pb, 4); - - // ? - avio_wb16(pb, 0x0C); /* size */ - avio_wb32(pb, 0x0B); /* type */ - avio_wb16(pb, language_code("und")); /* language */ - avio_wb16(pb, 0x0); /* ? */ - avio_wb16(pb, 0x021C); /* data */ - - mov_write_psp_udta_tag(pb, LIBAVCODEC_IDENT, "eng", 0x04); - mov_write_psp_udta_tag(pb, title->value, "eng", 0x01); - mov_write_psp_udta_tag(pb, "2006/04/01 11:11:11", "und", 0x03); - - update_size(pb, pos2); - return update_size(pb, pos); - } - - return 0; -} - -static void build_chunks(MOVTrack *trk) -{ - int i; - MOVIentry *chunk= &trk->cluster[0]; - uint64_t chunkSize = chunk->size; - chunk->chunkNum= 1; - if (trk->chunkCount) - return; - trk->chunkCount= 1; - for(i=1; ientry; i++){ - if(chunk->pos + chunkSize == trk->cluster[i].pos && - chunkSize + trk->cluster[i].size < (1<<20)){ - chunkSize += trk->cluster[i].size; - chunk->samples_in_chunk += trk->cluster[i].entries; - }else{ - trk->cluster[i].chunkNum = chunk->chunkNum+1; - chunk=&trk->cluster[i]; - chunkSize = chunk->size; - trk->chunkCount++; - } - } -} - -static int mov_write_moov_tag(AVIOContext *pb, MOVMuxContext *mov, - AVFormatContext *s) -{ - int i; - int64_t pos = avio_tell(pb); - int not_first[AVMEDIA_TYPE_NB]={0}; - avio_wb32(pb, 0); /* size placeholder*/ - ffio_wfourcc(pb, "moov"); - - for (i=0; inb_streams; i++) { - if (mov->tracks[i].entry <= 0 && !(mov->flags & FF_MOV_FLAG_FRAGMENT)) - continue; - - mov->tracks[i].time = mov->time; - mov->tracks[i].track_id = i+1; - - if (mov->tracks[i].entry) - build_chunks(&mov->tracks[i]); - } - - if (mov->chapter_track) - for (i=0; inb_streams; i++) { - mov->tracks[i].tref_tag = MKTAG('c','h','a','p'); - mov->tracks[i].tref_id = mov->tracks[mov->chapter_track].track_id; - } - for (i = 0; i < mov->nb_streams; i++) { - if (mov->tracks[i].tag == MKTAG('r','t','p',' ')) { - mov->tracks[i].tref_tag = MKTAG('h','i','n','t'); - mov->tracks[i].tref_id = - mov->tracks[mov->tracks[i].src_track].track_id; - } - } - for (i = 0; i < mov->nb_streams; i++) { - if (mov->tracks[i].tag == MKTAG('t','m','c','d')) { - int src_trk = mov->tracks[i].src_track; - mov->tracks[src_trk].tref_tag = mov->tracks[i].tag; - mov->tracks[src_trk].tref_id = mov->tracks[i].track_id; - mov->tracks[i].track_duration = mov->tracks[src_trk].track_duration; - } - } - - mov_write_mvhd_tag(pb, mov); - if (mov->mode != MODE_MOV && !mov->iods_skip) - mov_write_iods_tag(pb, mov); - for (i=0; inb_streams; i++) { - if (mov->tracks[i].entry > 0 || mov->flags & FF_MOV_FLAG_FRAGMENT) { - if(i < s->nb_streams){ - int codec_type= s->streams[i]->codec->codec_type; - if(codec_type==AVMEDIA_TYPE_AUDIO || codec_type==AVMEDIA_TYPE_SUBTITLE){ - mov->tracks[i].secondary= not_first[codec_type]; - not_first[codec_type]= 1; - } - } - mov_write_trak_tag(pb, mov, &(mov->tracks[i]), i < s->nb_streams ? s->streams[i] : NULL); - } - } - if (mov->flags & FF_MOV_FLAG_FRAGMENT) - mov_write_mvex_tag(pb, mov); /* QuickTime requires trak to precede this */ - - if (mov->mode == MODE_PSP) - mov_write_uuidusmt_tag(pb, s); - else - mov_write_udta_tag(pb, mov, s); - - return update_size(pb, pos); -} - -static void param_write_int(AVIOContext *pb, const char *name, int value) -{ - avio_printf(pb, "\n", name, value); -} - -static void param_write_string(AVIOContext *pb, const char *name, const char *value) -{ - avio_printf(pb, "\n", name, value); -} - -static void param_write_hex(AVIOContext *pb, const char *name, const uint8_t *value, int len) -{ - char buf[150]; - len = FFMIN(sizeof(buf)/2 - 1, len); - ff_data_to_hex(buf, value, len, 0); - buf[2*len] = '\0'; - avio_printf(pb, "\n", name, buf); -} - -static int mov_write_isml_manifest(AVIOContext *pb, MOVMuxContext *mov) -{ - int64_t pos = avio_tell(pb); - int i; - const uint8_t uuid[] = { - 0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd, - 0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66 - }; - - avio_wb32(pb, 0); - ffio_wfourcc(pb, "uuid"); - avio_write(pb, uuid, sizeof(uuid)); - avio_wb32(pb, 0); - - avio_printf(pb, "\n"); - avio_printf(pb, "\n"); - avio_printf(pb, "\n"); - avio_printf(pb, "\n", - LIBAVFORMAT_IDENT); - avio_printf(pb, "\n"); - avio_printf(pb, "\n"); - avio_printf(pb, "\n"); - for (i = 0; i < mov->nb_streams; i++) { - MOVTrack *track = &mov->tracks[i]; - const char *type; - /* track->track_id is initialized in write_moov, and thus isn't known - * here yet */ - int track_id = i + 1; - - if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO) { - type = "video"; - } else if (track->enc->codec_type == AVMEDIA_TYPE_AUDIO) { - type = "audio"; - } else { - continue; - } - avio_printf(pb, "<%s systemBitrate=\"%d\">\n", type, - track->enc->bit_rate); - param_write_int(pb, "systemBitrate", track->enc->bit_rate); - param_write_int(pb, "trackID", track_id); - if (track->enc->codec_type == AVMEDIA_TYPE_VIDEO) { - if (track->enc->codec_id == AV_CODEC_ID_H264) { - uint8_t *ptr; - int size = track->enc->extradata_size; - if (!ff_avc_write_annexb_extradata(track->enc->extradata, &ptr, - &size)) { - param_write_hex(pb, "CodecPrivateData", - ptr ? ptr : track->enc->extradata, - size); - av_free(ptr); - } - param_write_string(pb, "FourCC", "H264"); - } else if (track->enc->codec_id == AV_CODEC_ID_VC1) { - param_write_string(pb, "FourCC", "WVC1"); - param_write_hex(pb, "CodecPrivateData", track->enc->extradata, - track->enc->extradata_size); - } - param_write_int(pb, "MaxWidth", track->enc->width); - param_write_int(pb, "MaxHeight", track->enc->height); - param_write_int(pb, "DisplayWidth", track->enc->width); - param_write_int(pb, "DisplayHeight", track->enc->height); - } else { - if (track->enc->codec_id == AV_CODEC_ID_AAC) { - param_write_string(pb, "FourCC", "AACL"); - } else if (track->enc->codec_id == AV_CODEC_ID_WMAPRO) { - param_write_string(pb, "FourCC", "WMAP"); - } - param_write_hex(pb, "CodecPrivateData", track->enc->extradata, - track->enc->extradata_size); - param_write_int(pb, "AudioTag", ff_codec_get_tag(ff_codec_wav_tags, - track->enc->codec_id)); - param_write_int(pb, "Channels", track->enc->channels); - param_write_int(pb, "SamplingRate", track->enc->sample_rate); - param_write_int(pb, "BitsPerSample", 16); - param_write_int(pb, "PacketSize", track->enc->block_align ? - track->enc->block_align : 4); - } - avio_printf(pb, "\n", type); - } - avio_printf(pb, "\n"); - avio_printf(pb, "\n"); - avio_printf(pb, "\n"); - - return update_size(pb, pos); -} - -static int mov_write_mfhd_tag(AVIOContext *pb, MOVMuxContext *mov) -{ - avio_wb32(pb, 16); - ffio_wfourcc(pb, "mfhd"); - avio_wb32(pb, 0); - avio_wb32(pb, mov->fragments); - return 0; -} - -static int mov_write_tfhd_tag(AVIOContext *pb, MOVTrack *track, - int64_t moof_offset) -{ - int64_t pos = avio_tell(pb); - uint32_t flags = MOV_TFHD_DEFAULT_SIZE | MOV_TFHD_DEFAULT_DURATION | - MOV_TFHD_BASE_DATA_OFFSET; - if (!track->entry) { - flags |= MOV_TFHD_DURATION_IS_EMPTY; - } else { - 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 &= ~(MOV_TFHD_DEFAULT_SIZE | MOV_TFHD_DEFAULT_DURATION); - - avio_wb32(pb, 0); /* size placeholder */ - ffio_wfourcc(pb, "tfhd"); - avio_w8(pb, 0); /* version */ - avio_wb24(pb, flags); - - avio_wb32(pb, track->track_id); /* track-id */ - if (flags & MOV_TFHD_BASE_DATA_OFFSET) - avio_wb64(pb, moof_offset); - if (flags & MOV_TFHD_DEFAULT_DURATION) { - track->default_duration = get_cluster_duration(track, 0); - avio_wb32(pb, track->default_duration); - } - 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 & MOV_TFHD_DEFAULT_FLAGS) { - track->default_sample_flags = - track->enc->codec_type == AVMEDIA_TYPE_VIDEO ? - (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); - } - - return update_size(pb, pos); -} - -static uint32_t get_sample_flags(MOVTrack *track, MOVIentry *entry) -{ - 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 = MOV_TRUN_DATA_OFFSET; - int i; - - for (i = 0; i < track->entry; i++) { - if (get_cluster_duration(track, i) != track->default_duration) - flags |= MOV_TRUN_SAMPLE_DURATION; - if (track->cluster[i].size != track->default_size) - flags |= MOV_TRUN_SAMPLE_SIZE; - if (i > 0 && get_sample_flags(track, &track->cluster[i]) != track->default_sample_flags) - flags |= MOV_TRUN_SAMPLE_FLAGS; - } - if (!(flags & MOV_TRUN_SAMPLE_FLAGS)) - flags |= MOV_TRUN_FIRST_SAMPLE_FLAGS; - if (track->flags & MOV_TRACK_CTTS) - flags |= MOV_TRUN_SAMPLE_CTS; - - avio_wb32(pb, 0); /* size placeholder */ - ffio_wfourcc(pb, "trun"); - avio_w8(pb, 0); /* version */ - avio_wb24(pb, flags); - - avio_wb32(pb, track->entry); /* sample count */ - track->moof_size_offset = avio_tell(pb); - avio_wb32(pb, 0); /* data offset */ - if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) - avio_wb32(pb, get_sample_flags(track, &track->cluster[0])); - - for (i = 0; i < track->entry; i++) { - if (flags & MOV_TRUN_SAMPLE_DURATION) - avio_wb32(pb, get_cluster_duration(track, i)); - if (flags & MOV_TRUN_SAMPLE_SIZE) - avio_wb32(pb, track->cluster[i].size); - if (flags & MOV_TRUN_SAMPLE_FLAGS) - avio_wb32(pb, get_sample_flags(track, &track->cluster[i])); - if (flags & MOV_TRUN_SAMPLE_CTS) - avio_wb32(pb, track->cluster[i].cts); - } - - return update_size(pb, pos); -} - -static int mov_write_tfxd_tag(AVIOContext *pb, MOVTrack *track) -{ - int64_t pos = avio_tell(pb); - const uint8_t uuid[] = { - 0x6d, 0x1d, 0x9b, 0x05, 0x42, 0xd5, 0x44, 0xe6, - 0x80, 0xe2, 0x14, 0x1d, 0xaf, 0xf7, 0x57, 0xb2 - }; - - avio_wb32(pb, 0); /* size placeholder */ - ffio_wfourcc(pb, "uuid"); - avio_write(pb, uuid, sizeof(uuid)); - avio_w8(pb, 1); - avio_wb24(pb, 0); - avio_wb64(pb, track->frag_start); - avio_wb64(pb, track->start_dts + track->track_duration - - track->cluster[0].dts); - - return update_size(pb, pos); -} - -static int mov_write_tfrf_tag(AVIOContext *pb, MOVMuxContext *mov, - MOVTrack *track, int entry) -{ - int n = track->nb_frag_info - 1 - entry, i; - int size = 8 + 16 + 4 + 1 + 16*n; - const uint8_t uuid[] = { - 0xd4, 0x80, 0x7e, 0xf2, 0xca, 0x39, 0x46, 0x95, - 0x8e, 0x54, 0x26, 0xcb, 0x9e, 0x46, 0xa7, 0x9f - }; - - if (entry < 0) - return 0; - - avio_seek(pb, track->frag_info[entry].tfrf_offset, SEEK_SET); - avio_wb32(pb, size); - ffio_wfourcc(pb, "uuid"); - avio_write(pb, uuid, sizeof(uuid)); - avio_w8(pb, 1); - avio_wb24(pb, 0); - avio_w8(pb, n); - for (i = 0; i < n; i++) { - int index = entry + 1 + i; - avio_wb64(pb, track->frag_info[index].time); - avio_wb64(pb, track->frag_info[index].duration); - } - if (n < mov->ism_lookahead) { - int free_size = 16*(mov->ism_lookahead - n); - avio_wb32(pb, free_size); - ffio_wfourcc(pb, "free"); - for (i = 0; i < free_size - 8; i++) - avio_w8(pb, 0); - } - - return 0; -} - -static int mov_write_tfrf_tags(AVIOContext *pb, MOVMuxContext *mov, - MOVTrack *track) -{ - int64_t pos = avio_tell(pb); - int i; - for (i = 0; i < mov->ism_lookahead; i++) { - /* Update the tfrf tag for the last ism_lookahead fragments, - * nb_frag_info - 1 is the next fragment to be written. */ - mov_write_tfrf_tag(pb, mov, track, track->nb_frag_info - 2 - i); - } - avio_seek(pb, pos, SEEK_SET); - return 0; -} - -static int mov_write_traf_tag(AVIOContext *pb, MOVMuxContext *mov, - MOVTrack *track, int64_t moof_offset) -{ - int64_t pos = avio_tell(pb); - avio_wb32(pb, 0); /* size placeholder */ - ffio_wfourcc(pb, "traf"); - - mov_write_tfhd_tag(pb, track, moof_offset); - mov_write_trun_tag(pb, track); - if (mov->mode == MODE_ISM) { - mov_write_tfxd_tag(pb, track); - - if (mov->ism_lookahead) { - int i, size = 16 + 4 + 1 + 16*mov->ism_lookahead; - - track->tfrf_offset = avio_tell(pb); - avio_wb32(pb, 8 + size); - ffio_wfourcc(pb, "free"); - for (i = 0; i < size; i++) - avio_w8(pb, 0); - } - } - - return update_size(pb, pos); -} - -static int mov_write_moof_tag(AVIOContext *pb, MOVMuxContext *mov, int tracks) -{ - int64_t pos = avio_tell(pb), end; - int i, moof_size; - - avio_wb32(pb, 0); /* size placeholder */ - ffio_wfourcc(pb, "moof"); - - mov_write_mfhd_tag(pb, mov); - for (i = 0; i < mov->nb_streams; i++) { - MOVTrack *track = &mov->tracks[i]; - if (tracks >= 0 && i != tracks) - continue; - if (!track->entry) - continue; - mov_write_traf_tag(pb, mov, track, pos); - } - - end = avio_tell(pb); - moof_size = end - pos; - for (i = 0; i < mov->nb_streams; i++) { - MOVTrack *track = &mov->tracks[i]; - if (tracks >= 0 && i != tracks) - continue; - if (!track->entry) - continue; - avio_seek(pb, mov->tracks[i].moof_size_offset, SEEK_SET); - avio_wb32(pb, moof_size + 8 + mov->tracks[i].data_offset); - } - avio_seek(pb, end, SEEK_SET); - - return update_size(pb, pos); -} - -static int mov_write_tfra_tag(AVIOContext *pb, MOVTrack *track) -{ - int64_t pos = avio_tell(pb); - int i; - - avio_wb32(pb, 0); /* size placeholder */ - ffio_wfourcc(pb, "tfra"); - avio_w8(pb, 1); /* version */ - avio_wb24(pb, 0); - - avio_wb32(pb, track->track_id); - avio_wb32(pb, 0); /* length of traf/trun/sample num */ - avio_wb32(pb, track->nb_frag_info); - for (i = 0; i < track->nb_frag_info; i++) { - avio_wb64(pb, track->frag_info[i].time); - avio_wb64(pb, track->frag_info[i].offset); - avio_w8(pb, 1); /* traf number */ - avio_w8(pb, 1); /* trun number */ - avio_w8(pb, 1); /* sample number */ - } - - return update_size(pb, pos); -} - -static int mov_write_mfra_tag(AVIOContext *pb, MOVMuxContext *mov) -{ - int64_t pos = avio_tell(pb); - int i; - - avio_wb32(pb, 0); /* size placeholder */ - ffio_wfourcc(pb, "mfra"); - /* An empty mfra atom is enough to indicate to the publishing point that - * the stream has ended. */ - if (mov->flags & FF_MOV_FLAG_ISML) - return update_size(pb, pos); - - for (i = 0; i < mov->nb_streams; i++) { - MOVTrack *track = &mov->tracks[i]; - if (track->nb_frag_info) - mov_write_tfra_tag(pb, track); - } - - avio_wb32(pb, 16); - ffio_wfourcc(pb, "mfro"); - avio_wb32(pb, 0); /* version + flags */ - avio_wb32(pb, avio_tell(pb) + 4 - pos); - - return update_size(pb, pos); -} - -static int mov_write_mdat_tag(AVIOContext *pb, MOVMuxContext *mov) -{ - avio_wb32(pb, 8); // placeholder for extended size field (64 bit) - ffio_wfourcc(pb, mov->mode == MODE_MOV ? "wide" : "free"); - - mov->mdat_pos = avio_tell(pb); - avio_wb32(pb, 0); /* size placeholder*/ - ffio_wfourcc(pb, "mdat"); - return 0; -} - -/* TODO: This needs to be more general */ -static int mov_write_ftyp_tag(AVIOContext *pb, AVFormatContext *s) -{ - MOVMuxContext *mov = s->priv_data; - int64_t pos = avio_tell(pb); - int has_h264 = 0, has_video = 0; - int minor = 0x200; - int i; - - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) - has_video = 1; - if (st->codec->codec_id == AV_CODEC_ID_H264) - has_h264 = 1; - } - - avio_wb32(pb, 0); /* size */ - ffio_wfourcc(pb, "ftyp"); - - if (mov->mode == MODE_3GP) { - ffio_wfourcc(pb, has_h264 ? "3gp6" : "3gp4"); - minor = has_h264 ? 0x100 : 0x200; - } else if (mov->mode & MODE_3G2) { - ffio_wfourcc(pb, has_h264 ? "3g2b" : "3g2a"); - minor = has_h264 ? 0x20000 : 0x10000; - }else if (mov->mode == MODE_PSP) - ffio_wfourcc(pb, "MSNV"); - else if (mov->mode == MODE_MP4) - ffio_wfourcc(pb, "isom"); - else if (mov->mode == MODE_IPOD) - ffio_wfourcc(pb, has_video ? "M4V ":"M4A "); - else if (mov->mode == MODE_ISM) - ffio_wfourcc(pb, "isml"); - else if (mov->mode == MODE_F4V) - ffio_wfourcc(pb, "f4v "); - else - ffio_wfourcc(pb, "qt "); - - avio_wb32(pb, minor); - - if(mov->mode == MODE_MOV) - ffio_wfourcc(pb, "qt "); - else if (mov->mode == MODE_ISM) { - ffio_wfourcc(pb, "piff"); - ffio_wfourcc(pb, "iso2"); - } else { - ffio_wfourcc(pb, "isom"); - ffio_wfourcc(pb, "iso2"); - if(has_h264) - ffio_wfourcc(pb, "avc1"); - } - - if (mov->mode == MODE_3GP) - ffio_wfourcc(pb, has_h264 ? "3gp6":"3gp4"); - else if (mov->mode & MODE_3G2) - ffio_wfourcc(pb, has_h264 ? "3g2b":"3g2a"); - else if (mov->mode == MODE_PSP) - ffio_wfourcc(pb, "MSNV"); - else if (mov->mode == MODE_MP4) - ffio_wfourcc(pb, "mp41"); - return update_size(pb, pos); -} - -static void mov_write_uuidprof_tag(AVIOContext *pb, AVFormatContext *s) -{ - AVCodecContext *video_codec = s->streams[0]->codec; - AVCodecContext *audio_codec = s->streams[1]->codec; - int audio_rate = audio_codec->sample_rate; - int frame_rate = ((video_codec->time_base.den) * (0x10000))/ (video_codec->time_base.num); - int audio_kbitrate = audio_codec->bit_rate / 1000; - int video_kbitrate = FFMIN(video_codec->bit_rate / 1000, 800 - audio_kbitrate); - - avio_wb32(pb, 0x94); /* size */ - ffio_wfourcc(pb, "uuid"); - ffio_wfourcc(pb, "PROF"); - - avio_wb32(pb, 0x21d24fce); /* 96 bit UUID */ - avio_wb32(pb, 0xbb88695c); - avio_wb32(pb, 0xfac9c740); - - avio_wb32(pb, 0x0); /* ? */ - avio_wb32(pb, 0x3); /* 3 sections ? */ - - avio_wb32(pb, 0x14); /* size */ - ffio_wfourcc(pb, "FPRF"); - avio_wb32(pb, 0x0); /* ? */ - avio_wb32(pb, 0x0); /* ? */ - avio_wb32(pb, 0x0); /* ? */ - - avio_wb32(pb, 0x2c); /* size */ - ffio_wfourcc(pb, "APRF");/* audio */ - avio_wb32(pb, 0x0); - avio_wb32(pb, 0x2); /* TrackID */ - ffio_wfourcc(pb, "mp4a"); - avio_wb32(pb, 0x20f); - avio_wb32(pb, 0x0); - avio_wb32(pb, audio_kbitrate); - avio_wb32(pb, audio_kbitrate); - avio_wb32(pb, audio_rate); - avio_wb32(pb, audio_codec->channels); - - avio_wb32(pb, 0x34); /* size */ - ffio_wfourcc(pb, "VPRF"); /* video */ - avio_wb32(pb, 0x0); - avio_wb32(pb, 0x1); /* TrackID */ - if (video_codec->codec_id == AV_CODEC_ID_H264) { - ffio_wfourcc(pb, "avc1"); - avio_wb16(pb, 0x014D); - avio_wb16(pb, 0x0015); - } else { - ffio_wfourcc(pb, "mp4v"); - avio_wb16(pb, 0x0000); - avio_wb16(pb, 0x0103); - } - avio_wb32(pb, 0x0); - avio_wb32(pb, video_kbitrate); - avio_wb32(pb, video_kbitrate); - avio_wb32(pb, frame_rate); - avio_wb32(pb, frame_rate); - avio_wb16(pb, video_codec->width); - avio_wb16(pb, video_codec->height); - avio_wb32(pb, 0x010001); /* ? */ -} - -static int mov_parse_mpeg2_frame(AVPacket *pkt, uint32_t *flags) -{ - uint32_t c = -1; - int i, closed_gop = 0; - - for (i = 0; i < pkt->size - 4; i++) { - c = (c<<8) + pkt->data[i]; - if (c == 0x1b8) { // gop - closed_gop = pkt->data[i+4]>>6 & 0x01; - } else if (c == 0x100) { // pic - int temp_ref = (pkt->data[i+1]<<2) | (pkt->data[i+2]>>6); - if (!temp_ref || closed_gop) // I picture is not reordered - *flags = MOV_SYNC_SAMPLE; - else - *flags = MOV_PARTIAL_SYNC_SAMPLE; - break; - } - } - return 0; -} - -static void mov_parse_vc1_frame(AVPacket *pkt, MOVTrack *trk, int fragment) -{ - const uint8_t *start, *next, *end = pkt->data + pkt->size; - int seq = 0, entry = 0; - int key = pkt->flags & AV_PKT_FLAG_KEY; - start = find_next_marker(pkt->data, end); - for (next = start; next < end; start = next) { - next = find_next_marker(start + 4, end); - switch (AV_RB32(start)) { - case VC1_CODE_SEQHDR: - seq = 1; - break; - case VC1_CODE_ENTRYPOINT: - entry = 1; - break; - case VC1_CODE_SLICE: - trk->vc1_info.slices = 1; - break; - } - } - if (!trk->entry && !fragment) { - /* First packet in first fragment */ - trk->vc1_info.first_packet_seq = seq; - trk->vc1_info.first_packet_entry = entry; - } else if ((seq && !trk->vc1_info.packet_seq) || - (entry && !trk->vc1_info.packet_entry)) { - int i; - for (i = 0; i < trk->entry; i++) - trk->cluster[i].flags &= ~MOV_SYNC_SAMPLE; - trk->has_keyframes = 0; - if (seq) - trk->vc1_info.packet_seq = 1; - if (entry) - trk->vc1_info.packet_entry = 1; - if (!fragment) { - /* First fragment */ - if ((!seq || trk->vc1_info.first_packet_seq) && - (!entry || trk->vc1_info.first_packet_entry)) { - /* First packet had the same headers as this one, readd the - * sync sample flag. */ - trk->cluster[0].flags |= MOV_SYNC_SAMPLE; - trk->has_keyframes = 1; - } - } - } - if (trk->vc1_info.packet_seq && trk->vc1_info.packet_entry) - key = seq && entry; - else if (trk->vc1_info.packet_seq) - key = seq; - else if (trk->vc1_info.packet_entry) - key = entry; - if (key) { - trk->cluster[trk->entry].flags |= MOV_SYNC_SAMPLE; - trk->has_keyframes++; - } -} - -static int get_moov_size(AVFormatContext *s) -{ - int ret; - uint8_t *buf; - AVIOContext *moov_buf; - MOVMuxContext *mov = s->priv_data; - - if ((ret = avio_open_dyn_buf(&moov_buf)) < 0) - return ret; - mov_write_moov_tag(moov_buf, mov, s); - ret = avio_close_dyn_buf(moov_buf, &buf); - av_free(buf); - return ret; -} - -static int mov_flush_fragment(AVFormatContext *s) -{ - MOVMuxContext *mov = s->priv_data; - int i, first_track = -1; - int64_t mdat_size = 0; - - if (!(mov->flags & FF_MOV_FLAG_FRAGMENT)) - return 0; - - if (!(mov->flags & FF_MOV_FLAG_EMPTY_MOOV) && mov->fragments == 0) { - int64_t pos = avio_tell(s->pb); - uint8_t *buf; - int buf_size, moov_size; - - for (i = 0; i < mov->nb_streams; i++) - if (!mov->tracks[i].entry) - break; - /* Don't write the initial moov unless all tracks have data */ - if (i < mov->nb_streams) - return 0; - - moov_size = get_moov_size(s); - for (i = 0; i < mov->nb_streams; i++) - mov->tracks[i].data_offset = pos + moov_size + 8; - - mov_write_moov_tag(s->pb, mov, s); - - buf_size = avio_close_dyn_buf(mov->mdat_buf, &buf); - mov->mdat_buf = NULL; - avio_wb32(s->pb, buf_size + 8); - ffio_wfourcc(s->pb, "mdat"); - avio_write(s->pb, buf, buf_size); - av_free(buf); - - mov->fragments++; - mov->mdat_size = 0; - for (i = 0; i < mov->nb_streams; i++) { - if (mov->tracks[i].entry) - mov->tracks[i].frag_start += mov->tracks[i].start_dts + - mov->tracks[i].track_duration - - mov->tracks[i].cluster[0].dts; - mov->tracks[i].entry = 0; - } - avio_flush(s->pb); - return 0; - } - - for (i = 0; i < mov->nb_streams; i++) { - MOVTrack *track = &mov->tracks[i]; - if (mov->flags & FF_MOV_FLAG_SEPARATE_MOOF) - track->data_offset = 0; - else - track->data_offset = mdat_size; - if (!track->mdat_buf) - continue; - mdat_size += avio_tell(track->mdat_buf); - if (first_track < 0) - first_track = i; - } - - if (!mdat_size) - return 0; - - for (i = 0; i < mov->nb_streams; i++) { - MOVTrack *track = &mov->tracks[i]; - int buf_size, write_moof = 1, moof_tracks = -1; - uint8_t *buf; - int64_t duration = 0; - - if (track->entry) - duration = track->start_dts + track->track_duration - - track->cluster[0].dts; - if (mov->flags & FF_MOV_FLAG_SEPARATE_MOOF) { - if (!track->mdat_buf) - continue; - mdat_size = avio_tell(track->mdat_buf); - moof_tracks = i; - } else { - write_moof = i == first_track; - } - - if (write_moof) { - MOVFragmentInfo *info; - avio_flush(s->pb); - track->nb_frag_info++; - track->frag_info = av_realloc(track->frag_info, - sizeof(*track->frag_info) * - track->nb_frag_info); - info = &track->frag_info[track->nb_frag_info - 1]; - info->offset = avio_tell(s->pb); - info->time = mov->tracks[i].frag_start; - info->duration = duration; - mov_write_tfrf_tags(s->pb, mov, track); - - mov_write_moof_tag(s->pb, mov, moof_tracks); - info->tfrf_offset = track->tfrf_offset; - mov->fragments++; - - avio_wb32(s->pb, mdat_size + 8); - ffio_wfourcc(s->pb, "mdat"); - } - - if (track->entry) - track->frag_start += duration; - track->entry = 0; - if (!track->mdat_buf) - continue; - buf_size = avio_close_dyn_buf(track->mdat_buf, &buf); - track->mdat_buf = NULL; - - avio_write(s->pb, buf, buf_size); - av_free(buf); - } - - mov->mdat_size = 0; - - avio_flush(s->pb); - return 0; -} - -int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - MOVMuxContext *mov = s->priv_data; - AVIOContext *pb = s->pb; - MOVTrack *trk = &mov->tracks[pkt->stream_index]; - AVCodecContext *enc = trk->enc; - unsigned int samples_in_chunk = 0; - int size= pkt->size; - uint8_t *reformatted_data = NULL; - - if (mov->flags & FF_MOV_FLAG_FRAGMENT) { - int ret; - if (mov->fragments > 0) { - if (!trk->mdat_buf) { - if ((ret = avio_open_dyn_buf(&trk->mdat_buf)) < 0) - return ret; - } - pb = trk->mdat_buf; - } else { - if (!mov->mdat_buf) { - if ((ret = avio_open_dyn_buf(&mov->mdat_buf)) < 0) - return ret; - } - pb = mov->mdat_buf; - } - } - - if (enc->codec_id == AV_CODEC_ID_AMR_NB) { - /* We must find out how many AMR blocks there are in one packet */ - static uint16_t packed_size[16] = - {13, 14, 16, 18, 20, 21, 27, 32, 6, 0, 0, 0, 0, 0, 0, 1}; - int len = 0; - - while (len < size && samples_in_chunk < 100) { - len += packed_size[(pkt->data[len] >> 3) & 0x0F]; - samples_in_chunk++; - } - if (samples_in_chunk > 1) { - av_log(s, AV_LOG_ERROR, "fatal error, input is not a single packet, implement a AVParser for it\n"); - return -1; - } - } else if (enc->codec_id == AV_CODEC_ID_ADPCM_MS || - enc->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV) { - samples_in_chunk = enc->frame_size; - } else if (trk->sample_size) - samples_in_chunk = size / trk->sample_size; - else - samples_in_chunk = 1; - - /* copy extradata if it exists */ - if (trk->vos_len == 0 && enc->extradata_size > 0) { - trk->vos_len = enc->extradata_size; - trk->vos_data = av_malloc(trk->vos_len); - memcpy(trk->vos_data, enc->extradata, trk->vos_len); - } - - if (enc->codec_id == AV_CODEC_ID_H264 && trk->vos_len > 0 && *(uint8_t *)trk->vos_data != 1) { - /* from x264 or from bytestream h264 */ - /* nal reformating needed */ - if (trk->hint_track >= 0 && trk->hint_track < mov->nb_streams) { - ff_avc_parse_nal_units_buf(pkt->data, &reformatted_data, - &size); - avio_write(pb, reformatted_data, size); - } else { - size = ff_avc_parse_nal_units(pb, pkt->data, pkt->size); - } - } else if (enc->codec_id == AV_CODEC_ID_AAC && pkt->size > 2 && - (AV_RB16(pkt->data) & 0xfff0) == 0xfff0) { - av_log(s, AV_LOG_ERROR, "malformated aac bitstream, use -absf aac_adtstoasc\n"); - return -1; - } else { - avio_write(pb, pkt->data, size); - } - - if ((enc->codec_id == AV_CODEC_ID_DNXHD || - enc->codec_id == AV_CODEC_ID_AC3) && !trk->vos_len) { - /* copy frame to create needed atoms */ - trk->vos_len = size; - trk->vos_data = av_malloc(size); - if (!trk->vos_data) - return AVERROR(ENOMEM); - memcpy(trk->vos_data, pkt->data, size); - } - - if (!(trk->entry % MOV_INDEX_CLUSTER_SIZE)) { - trk->cluster = av_realloc_f(trk->cluster, sizeof(*trk->cluster), (trk->entry + MOV_INDEX_CLUSTER_SIZE)); - if (!trk->cluster) - return -1; - } - - trk->cluster[trk->entry].pos = avio_tell(pb) - size; - trk->cluster[trk->entry].samples_in_chunk = samples_in_chunk; - trk->cluster[trk->entry].chunkNum = 0; - trk->cluster[trk->entry].size = size; - trk->cluster[trk->entry].entries = samples_in_chunk; - trk->cluster[trk->entry].dts = pkt->dts; - if (!trk->entry && trk->start_dts != AV_NOPTS_VALUE) { - /* First packet of a new fragment. We already wrote the duration - * of the last packet of the previous fragment based on track_duration, - * which might not exactly match our dts. Therefore adjust the dts - * of this packet to be what the previous packets duration implies. */ - trk->cluster[trk->entry].dts = trk->start_dts + trk->track_duration; - } - if (!trk->entry && trk->start_dts == AV_NOPTS_VALUE && !supports_edts(mov)) { - trk->cluster[trk->entry].dts = trk->start_dts = 0; - } - if (trk->start_dts == AV_NOPTS_VALUE) - trk->start_dts = pkt->dts; - trk->track_duration = pkt->dts - trk->start_dts + pkt->duration; - trk->last_sample_is_subtitle_end = 0; - - if (pkt->pts == AV_NOPTS_VALUE) { - av_log(s, AV_LOG_WARNING, "pts has no value\n"); - pkt->pts = pkt->dts; - } - if (pkt->dts != pkt->pts) - trk->flags |= MOV_TRACK_CTTS; - trk->cluster[trk->entry].cts = pkt->pts - pkt->dts; - trk->cluster[trk->entry].flags = 0; - if (enc->codec_id == AV_CODEC_ID_VC1) { - mov_parse_vc1_frame(pkt, trk, mov->fragments); - } else if (pkt->flags & AV_PKT_FLAG_KEY) { - if (mov->mode == MODE_MOV && enc->codec_id == AV_CODEC_ID_MPEG2VIDEO && - trk->entry > 0) { // force sync sample for the first key frame - mov_parse_mpeg2_frame(pkt, &trk->cluster[trk->entry].flags); - if (trk->cluster[trk->entry].flags & MOV_PARTIAL_SYNC_SAMPLE) - trk->flags |= MOV_TRACK_STPS; - } else { - trk->cluster[trk->entry].flags = MOV_SYNC_SAMPLE; - } - if (trk->cluster[trk->entry].flags & MOV_SYNC_SAMPLE) - trk->has_keyframes++; - } - trk->entry++; - trk->sample_count += samples_in_chunk; - mov->mdat_size += size; - - avio_flush(pb); - - if (trk->hint_track >= 0 && trk->hint_track < mov->nb_streams) - ff_mov_add_hinted_packet(s, pkt, trk->hint_track, trk->entry, - reformatted_data, size); - av_free(reformatted_data); - return 0; -} - -static int mov_write_single_packet(AVFormatContext *s, AVPacket *pkt) -{ - MOVMuxContext *mov = s->priv_data; - MOVTrack *trk = &mov->tracks[pkt->stream_index]; - AVCodecContext *enc = trk->enc; - int64_t frag_duration = 0; - int size = pkt->size; - - if (!pkt->size) return 0; /* Discard 0 sized packets */ - - if (trk->entry && pkt->stream_index < s->nb_streams) - frag_duration = av_rescale_q(pkt->dts - trk->cluster[0].dts, - s->streams[pkt->stream_index]->time_base, - AV_TIME_BASE_Q); - if ((mov->max_fragment_duration && - frag_duration >= mov->max_fragment_duration) || - (mov->max_fragment_size && mov->mdat_size + size >= mov->max_fragment_size) || - (mov->flags & FF_MOV_FLAG_FRAG_KEYFRAME && - enc->codec_type == AVMEDIA_TYPE_VIDEO && - trk->entry && pkt->flags & AV_PKT_FLAG_KEY)) { - if (frag_duration >= mov->min_fragment_duration) - mov_flush_fragment(s); - } - - return ff_mov_write_packet(s, pkt); -} - -static int mov_write_subtitle_end_packet(AVFormatContext *s, - int stream_index, - int64_t dts) { - AVPacket end; - uint8_t data[2] = {0}; - int ret; - - av_init_packet(&end); - end.size = sizeof(data); - end.data = data; - end.pts = dts; - end.dts = dts; - end.duration = 0; - end.stream_index = stream_index; - - ret = mov_write_single_packet(s, &end); - av_free_packet(&end); - - return ret; -} - -static int mov_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - if (!pkt) { - mov_flush_fragment(s); - return 1; - } else { - int i; - MOVMuxContext *mov = s->priv_data; - - if (!pkt->size) return 0; /* Discard 0 sized packets */ - - /* - * Subtitles require special handling. - * - * 1) For full complaince, every track must have a sample at - * dts == 0, which is rarely true for subtitles. So, as soon - * as we see any packet with dts > 0, write an empty subtitle - * at dts == 0 for any subtitle track with no samples in it. - * - * 2) For each subtitle track, check if the current packet's - * dts is past the duration of the last subtitle sample. If - * so, we now need to write an end sample for that subtitle. - * - * This must be done conditionally to allow for subtitles that - * immediately replace each other, in which case an end sample - * is not needed, and is, in fact, actively harmful. - * - * 3) See mov_write_trailer for how the final end sample is - * handled. - */ - for (i = 0; i < mov->nb_streams; i++) { - MOVTrack *trk = &mov->tracks[i]; - int ret; - - if (trk->enc->codec_id == AV_CODEC_ID_MOV_TEXT && - trk->track_duration < pkt->dts && - (trk->entry == 0 || !trk->last_sample_is_subtitle_end)) { - ret = mov_write_subtitle_end_packet(s, i, trk->track_duration); - if (ret < 0) return ret; - trk->last_sample_is_subtitle_end = 1; - } - } - - return mov_write_single_packet(s, pkt); - } -} - -// QuickTime chapters involve an additional text track with the chapter names -// as samples, and a tref pointing from the other tracks to the chapter one. -static void mov_create_chapter_track(AVFormatContext *s, int tracknum) -{ - AVIOContext *pb; - - MOVMuxContext *mov = s->priv_data; - MOVTrack *track = &mov->tracks[tracknum]; - AVPacket pkt = { .stream_index = tracknum, .flags = AV_PKT_FLAG_KEY }; - int i, len; - - track->mode = mov->mode; - track->tag = MKTAG('t','e','x','t'); - track->timescale = MOV_TIMESCALE; - track->enc = avcodec_alloc_context3(NULL); - track->enc->codec_type = AVMEDIA_TYPE_SUBTITLE; - - if (avio_open_dyn_buf(&pb) >= 0) { - int size; - uint8_t *buf; - - /* Stub header (usually for Quicktime chapter track) */ - // TextSampleEntry - avio_wb32(pb, 0x01); // displayFlags - avio_w8(pb, 0x00); // horizontal justification - avio_w8(pb, 0x00); // vertical justification - avio_w8(pb, 0x00); // bgColourRed - avio_w8(pb, 0x00); // bgColourGreen - avio_w8(pb, 0x00); // bgColourBlue - avio_w8(pb, 0x00); // bgColourAlpha - // BoxRecord - avio_wb16(pb, 0x00); // defTextBoxTop - avio_wb16(pb, 0x00); // defTextBoxLeft - avio_wb16(pb, 0x00); // defTextBoxBottom - avio_wb16(pb, 0x00); // defTextBoxRight - // StyleRecord - avio_wb16(pb, 0x00); // startChar - avio_wb16(pb, 0x00); // endChar - avio_wb16(pb, 0x01); // fontID - avio_w8(pb, 0x00); // fontStyleFlags - avio_w8(pb, 0x00); // fontSize - avio_w8(pb, 0x00); // fgColourRed - avio_w8(pb, 0x00); // fgColourGreen - avio_w8(pb, 0x00); // fgColourBlue - avio_w8(pb, 0x00); // fgColourAlpha - // FontTableBox - avio_wb32(pb, 0x0D); // box size - ffio_wfourcc(pb, "ftab"); // box atom name - avio_wb16(pb, 0x01); // entry count - // FontRecord - avio_wb16(pb, 0x01); // font ID - avio_w8(pb, 0x00); // font name length - - if ((size = avio_close_dyn_buf(pb, &buf)) > 0) { - track->enc->extradata = buf; - track->enc->extradata_size = size; - } else { - av_free(&buf); - } - } - - for (i = 0; i < s->nb_chapters; i++) { - AVChapter *c = s->chapters[i]; - AVDictionaryEntry *t; - - int64_t end = av_rescale_q(c->end, c->time_base, (AVRational){1,MOV_TIMESCALE}); - pkt.pts = pkt.dts = av_rescale_q(c->start, c->time_base, (AVRational){1,MOV_TIMESCALE}); - pkt.duration = end - pkt.dts; - - if ((t = av_dict_get(c->metadata, "title", NULL, 0))) { - len = strlen(t->value); - pkt.size = len+2; - pkt.data = av_malloc(pkt.size); - AV_WB16(pkt.data, len); - memcpy(pkt.data+2, t->value, len); - ff_mov_write_packet(s, &pkt); - av_freep(&pkt.data); - } - } -} - -static int mov_create_timecode_track(AVFormatContext *s, int index, int src_index, const char *tcstr) -{ - int ret; - MOVMuxContext *mov = s->priv_data; - MOVTrack *track = &mov->tracks[index]; - AVStream *src_st = s->streams[src_index]; - AVTimecode tc; - AVPacket pkt = {.stream_index = index, .flags = AV_PKT_FLAG_KEY, .size = 4}; - AVRational rate = {src_st->codec->time_base.den, src_st->codec->time_base.num}; - - /* if the codec time base makes no sense, try to fallback on stream frame rate */ - if (av_timecode_check_frame_rate(rate) < 0) { - av_log(s, AV_LOG_DEBUG, "timecode: tbc=%d/%d invalid, fallback on %d/%d\n", - rate.num, rate.den, src_st->avg_frame_rate.num, src_st->avg_frame_rate.den); - rate = src_st->avg_frame_rate; - } - - /* compute the frame number */ - ret = av_timecode_init_from_string(&tc, rate, tcstr, s); - if (ret < 0) - return ret; - - /* tmcd track based on video stream */ - track->mode = mov->mode; - track->tag = MKTAG('t','m','c','d'); - track->src_track = src_index; - track->timescale = mov->tracks[src_index].timescale; - if (tc.flags & AV_TIMECODE_FLAG_DROPFRAME) - track->timecode_flags |= MOV_TIMECODE_FLAG_DROPFRAME; - - /* encode context: tmcd data stream */ - track->enc = avcodec_alloc_context3(NULL); - track->enc->codec_type = AVMEDIA_TYPE_DATA; - track->enc->codec_tag = track->tag; - track->enc->time_base = src_st->codec->time_base; - - /* the tmcd track just contains one packet with the frame number */ - pkt.data = av_malloc(pkt.size); - AV_WB32(pkt.data, tc.start); - ret = ff_mov_write_packet(s, &pkt); - av_free(pkt.data); - return ret; -} - -static int mov_write_header(AVFormatContext *s) -{ - AVIOContext *pb = s->pb; - MOVMuxContext *mov = s->priv_data; - AVDictionaryEntry *t, *global_tcr = av_dict_get(s->metadata, "timecode", NULL, 0); - int i, hint_track = 0, tmcd_track = 0; - - /* Set the FRAGMENT flag if any of the fragmentation methods are - * enabled. */ - if (mov->max_fragment_duration || mov->max_fragment_size || - mov->flags & (FF_MOV_FLAG_EMPTY_MOOV | - FF_MOV_FLAG_FRAG_KEYFRAME | - FF_MOV_FLAG_FRAG_CUSTOM)) - mov->flags |= FF_MOV_FLAG_FRAGMENT; - - /* faststart: moov at the beginning of the file, if supported */ - if (mov->flags & FF_MOV_FLAG_FASTSTART) { - if (mov->flags & FF_MOV_FLAG_FRAGMENT) - mov->flags &= ~FF_MOV_FLAG_FASTSTART; - else - mov->reserved_moov_size = -1; - } - - if (!supports_edts(mov) && s->avoid_negative_ts < 0) { - s->avoid_negative_ts = 1; - } - - /* Non-seekable output is ok if using fragmentation. If ism_lookahead - * is enabled, we don't support non-seekable output at all. */ - if (!s->pb->seekable && - ((!(mov->flags & FF_MOV_FLAG_FRAGMENT) && - !(s->oformat && !strcmp(s->oformat->name, "ismv"))) - || mov->ism_lookahead)) { - av_log(s, AV_LOG_ERROR, "muxer does not support non seekable output\n"); - return -1; - } - - /* Default mode == MP4 */ - mov->mode = MODE_MP4; - - if (s->oformat != NULL) { - if (!strcmp("3gp", s->oformat->name)) mov->mode = MODE_3GP; - else if (!strcmp("3g2", s->oformat->name)) mov->mode = MODE_3GP|MODE_3G2; - else if (!strcmp("mov", s->oformat->name)) mov->mode = MODE_MOV; - else if (!strcmp("psp", s->oformat->name)) mov->mode = MODE_PSP; - else if (!strcmp("ipod",s->oformat->name)) mov->mode = MODE_IPOD; - else if (!strcmp("ismv",s->oformat->name)) mov->mode = MODE_ISM; - else if (!strcmp("f4v", s->oformat->name)) mov->mode = MODE_F4V; - - mov_write_ftyp_tag(pb,s); - if (mov->mode == MODE_PSP) { - if (s->nb_streams != 2) { - av_log(s, AV_LOG_ERROR, "PSP mode need one video and one audio stream\n"); - return -1; - } - mov_write_uuidprof_tag(pb,s); - } - } - - mov->nb_streams = s->nb_streams; - if (mov->mode & (MODE_MOV|MODE_IPOD) && s->nb_chapters) - mov->chapter_track = mov->nb_streams++; - - if (mov->flags & FF_MOV_FLAG_RTP_HINT) { - /* Add hint tracks for each audio and video stream */ - hint_track = mov->nb_streams; - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO || - st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - mov->nb_streams++; - } - } - } - - if (mov->mode == MODE_MOV) { - tmcd_track = mov->nb_streams; - - /* +1 tmcd track for each video stream with a timecode */ - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && - (global_tcr || av_dict_get(st->metadata, "timecode", NULL, 0))) - mov->nb_meta_tmcd++; - } - - /* check if there is already a tmcd track to remux */ - if (mov->nb_meta_tmcd) { - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - if (st->codec->codec_tag == MKTAG('t','m','c','d')) { - av_log(s, AV_LOG_WARNING, "You requested a copy of the original timecode track " - "so timecode metadata are now ignored\n"); - mov->nb_meta_tmcd = 0; - } - } - } - - mov->nb_streams += mov->nb_meta_tmcd; - } - - mov->tracks = av_mallocz(mov->nb_streams*sizeof(*mov->tracks)); - if (!mov->tracks) - return AVERROR(ENOMEM); - - for(i=0; inb_streams; i++){ - AVStream *st= s->streams[i]; - MOVTrack *track= &mov->tracks[i]; - AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL,0); - - track->enc = st->codec; - track->language = ff_mov_iso639_to_lang(lang?lang->value:"und", mov->mode!=MODE_MOV); - if (track->language < 0) - track->language = 0; - track->mode = mov->mode; - track->tag = mov_find_codec_tag(s, track); - if (!track->tag) { - av_log(s, AV_LOG_ERROR, "track %d: could not find tag, " - "codec not currently supported in container\n", i); - goto error; - } - /* If hinting of this track is enabled by a later hint track, - * this is updated. */ - track->hint_track = -1; - track->start_dts = AV_NOPTS_VALUE; - if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO){ - if (track->tag == MKTAG('m','x','3','p') || track->tag == MKTAG('m','x','3','n') || - track->tag == MKTAG('m','x','4','p') || track->tag == MKTAG('m','x','4','n') || - track->tag == MKTAG('m','x','5','p') || track->tag == MKTAG('m','x','5','n')) { - if (st->codec->width != 720 || (st->codec->height != 608 && st->codec->height != 512)) { - av_log(s, AV_LOG_ERROR, "D-10/IMX must use 720x608 or 720x512 video resolution\n"); - goto error; - } - track->height = track->tag>>24 == 'n' ? 486 : 576; - } - track->timescale = st->codec->time_base.den; - while(track->timescale < 10000) - track->timescale *= 2; - if (track->mode == MODE_MOV && track->timescale > 100000) - av_log(s, AV_LOG_WARNING, - "WARNING codec timebase is very high. If duration is too long,\n" - "file may not be playable by quicktime. Specify a shorter timebase\n" - "or choose different container.\n"); - }else if(st->codec->codec_type == AVMEDIA_TYPE_AUDIO){ - track->timescale = st->codec->sample_rate; - if(!st->codec->frame_size && !av_get_bits_per_sample(st->codec->codec_id)) { - av_log(s, AV_LOG_WARNING, "track %d: codec frame size is not set\n", i); - track->audio_vbr = 1; - }else if(st->codec->codec_id == AV_CODEC_ID_ADPCM_MS || - st->codec->codec_id == AV_CODEC_ID_ADPCM_IMA_WAV || - st->codec->codec_id == AV_CODEC_ID_ILBC){ - if (!st->codec->block_align) { - av_log(s, AV_LOG_ERROR, "track %d: codec block align is not set for adpcm\n", i); - goto error; - } - track->sample_size = st->codec->block_align; - }else if(st->codec->frame_size > 1){ /* assume compressed audio */ - track->audio_vbr = 1; - }else{ - track->sample_size = (av_get_bits_per_sample(st->codec->codec_id) >> 3) * st->codec->channels; - } - if (track->mode != MODE_MOV && - track->enc->codec_id == AV_CODEC_ID_MP3 && track->timescale < 16000) { - av_log(s, AV_LOG_ERROR, "track %d: muxing mp3 at %dhz is not supported\n", - i, track->enc->sample_rate); - goto error; - } - }else if(st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE){ - track->timescale = st->codec->time_base.den; - }else{ - track->timescale = MOV_TIMESCALE; - } - if (!track->height) - track->height = st->codec->height; - /* The ism specific timescale isn't mandatory, but is assumed by - * some tools, such as mp4split. */ - if (mov->mode == MODE_ISM) - track->timescale = 10000000; - - avpriv_set_pts_info(st, 64, 1, track->timescale); - - /* copy extradata if it exists */ - if (st->codec->extradata_size) { - track->vos_len = st->codec->extradata_size; - track->vos_data = av_malloc(track->vos_len); - memcpy(track->vos_data, st->codec->extradata, track->vos_len); - } - } - - if (mov->mode == MODE_ISM) { - /* If no fragmentation options have been set, set a default. */ - if (!(mov->flags & (FF_MOV_FLAG_FRAG_KEYFRAME | - FF_MOV_FLAG_FRAG_CUSTOM)) && - !mov->max_fragment_duration && !mov->max_fragment_size) - mov->max_fragment_duration = 5000000; - mov->flags |= FF_MOV_FLAG_EMPTY_MOOV | FF_MOV_FLAG_SEPARATE_MOOF | - FF_MOV_FLAG_FRAGMENT; - } - - if(mov->reserved_moov_size){ - mov->reserved_moov_pos= avio_tell(pb); - if (mov->reserved_moov_size > 0) - avio_skip(pb, mov->reserved_moov_size); - } - - if (!(mov->flags & FF_MOV_FLAG_FRAGMENT)) - mov_write_mdat_tag(pb, mov); - - if (t = av_dict_get(s->metadata, "creation_time", NULL, 0)) - mov->time = ff_iso8601_to_unix_time(t->value); - if (mov->time) - mov->time += 0x7C25B080; // 1970 based -> 1904 based - - if (mov->chapter_track) - mov_create_chapter_track(s, mov->chapter_track); - - if (mov->flags & FF_MOV_FLAG_RTP_HINT) { - /* Initialize the hint tracks for each audio and video stream */ - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO || - st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - ff_mov_init_hinting(s, hint_track, i); - hint_track++; - } - } - } - - if (mov->nb_meta_tmcd) { - /* Initialize the tmcd tracks */ - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - t = global_tcr; - - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { - if (!t) - t = av_dict_get(st->metadata, "timecode", NULL, 0); - if (!t) - continue; - if (mov_create_timecode_track(s, tmcd_track, i, t->value) < 0) - goto error; - tmcd_track++; - } - } - } - - avio_flush(pb); - - if (mov->flags & FF_MOV_FLAG_ISML) - mov_write_isml_manifest(pb, mov); - - if (mov->flags & FF_MOV_FLAG_EMPTY_MOOV) { - mov_write_moov_tag(pb, mov, s); - mov->fragments++; - } - - return 0; - error: - av_freep(&mov->tracks); - return -1; -} - -/** - * This function gets the moov size if moved to the top of the file: the chunk - * offset table can switch between stco (32-bit entries) to co64 (64-bit - * entries) when the moov is moved to the top, so the size of the moov would - * change. It also updates the chunk offset tables. - */ -static int compute_moov_size(AVFormatContext *s) -{ - int i, moov_size, moov_size2; - MOVMuxContext *mov = s->priv_data; - - moov_size = get_moov_size(s); - if (moov_size < 0) - return moov_size; - - for (i = 0; i < mov->nb_streams; i++) - mov->tracks[i].data_offset += moov_size; - - moov_size2 = get_moov_size(s); - if (moov_size2 < 0) - return moov_size2; - - /* if the size changed, we just switched from stco to co64 and needs to - * update the offsets */ - if (moov_size2 != moov_size) - for (i = 0; i < mov->nb_streams; i++) - mov->tracks[i].data_offset += moov_size2 - moov_size; - - return moov_size2; -} - -static int shift_data(AVFormatContext *s) -{ - int ret = 0, moov_size; - MOVMuxContext *mov = s->priv_data; - int64_t pos, pos_end = avio_tell(s->pb); - uint8_t *buf, *read_buf[2]; - int read_buf_id = 0; - int read_size[2]; - AVIOContext *read_pb; - - moov_size = compute_moov_size(s); - if (moov_size < 0) - return moov_size; - - buf = av_malloc(moov_size * 2); - if (!buf) - return AVERROR(ENOMEM); - read_buf[0] = buf; - read_buf[1] = buf + moov_size; - - /* Shift the data: the AVIO context of the output can only be used for - * writing, so we re-open the same output, but for reading. It also avoids - * a read/seek/write/seek back and forth. */ - avio_flush(s->pb); - ret = avio_open(&read_pb, s->filename, AVIO_FLAG_READ); - if (ret < 0) { - av_log(s, AV_LOG_ERROR, "Unable to re-open %s output file for " - "the second pass (faststart)\n", s->filename); - goto end; - } - - /* mark the end of the shift to up to the last data we wrote, and get ready - * for writing */ - pos_end = avio_tell(s->pb); - avio_seek(s->pb, mov->reserved_moov_pos + moov_size, SEEK_SET); - - /* start reading at where the new moov will be placed */ - avio_seek(read_pb, mov->reserved_moov_pos, SEEK_SET); - pos = avio_tell(read_pb); - -#define READ_BLOCK do { \ - read_size[read_buf_id] = avio_read(read_pb, read_buf[read_buf_id], moov_size); \ - read_buf_id ^= 1; \ -} while (0) - - /* shift data by chunk of at most moov_size */ - READ_BLOCK; - do { - int n; - READ_BLOCK; - n = read_size[read_buf_id]; - if (n <= 0) - break; - avio_write(s->pb, read_buf[read_buf_id], n); - pos += n; - } while (pos < pos_end); - avio_close(read_pb); - -end: - av_free(buf); - return ret; -} - -static int mov_write_trailer(AVFormatContext *s) -{ - MOVMuxContext *mov = s->priv_data; - AVIOContext *pb = s->pb; - int64_t moov_pos; - int res = 0; - int i; - - /* - * Before actually writing the trailer, make sure that there are no - * dangling subtitles, that need a terminating sample. - */ - for (i = 0; i < mov->nb_streams; i++) { - MOVTrack *trk = &mov->tracks[i]; - if (trk->enc->codec_id == AV_CODEC_ID_MOV_TEXT && - !trk->last_sample_is_subtitle_end) { - mov_write_subtitle_end_packet(s, i, trk->track_duration); - trk->last_sample_is_subtitle_end = 1; - } - } - - moov_pos = avio_tell(pb); - - if (!(mov->flags & FF_MOV_FLAG_FRAGMENT)) { - /* Write size of mdat tag */ - if (mov->mdat_size + 8 <= UINT32_MAX) { - avio_seek(pb, mov->mdat_pos, SEEK_SET); - avio_wb32(pb, mov->mdat_size + 8); - } else { - /* overwrite 'wide' placeholder atom */ - avio_seek(pb, mov->mdat_pos - 8, SEEK_SET); - /* special value: real atom size will be 64 bit value after - * tag field */ - avio_wb32(pb, 1); - ffio_wfourcc(pb, "mdat"); - avio_wb64(pb, mov->mdat_size + 16); - } - avio_seek(pb, mov->reserved_moov_size > 0 ? mov->reserved_moov_pos : moov_pos, SEEK_SET); - - if (mov->reserved_moov_size == -1) { - av_log(s, AV_LOG_INFO, "Starting second pass: moving header on top of the file\n"); - res = shift_data(s); - if (res == 0) { - avio_seek(s->pb, mov->reserved_moov_pos, SEEK_SET); - mov_write_moov_tag(pb, mov, s); - } - } else if (mov->reserved_moov_size > 0) { - int64_t size; - mov_write_moov_tag(pb, mov, s); - size = mov->reserved_moov_size - (avio_tell(pb) - mov->reserved_moov_pos); - if(size < 8){ - av_log(s, AV_LOG_ERROR, "reserved_moov_size is too small, needed %"PRId64" additional\n", 8-size); - return -1; - } - avio_wb32(pb, size); - ffio_wfourcc(pb, "free"); - for(i=0; ichapter_track) - av_freep(&mov->tracks[mov->chapter_track].enc); - - for (i=0; inb_streams; i++) { - if (mov->tracks[i].tag == MKTAG('r','t','p',' ')) - ff_mov_close_hinting(&mov->tracks[i]); - else if (mov->tracks[i].tag == MKTAG('t','m','c','d') && mov->nb_meta_tmcd) - av_freep(&mov->tracks[i].enc); - if (mov->flags & FF_MOV_FLAG_FRAGMENT && - mov->tracks[i].vc1_info.struct_offset && s->pb->seekable) { - int64_t off = avio_tell(pb); - uint8_t buf[7]; - if (mov_write_dvc1_structs(&mov->tracks[i], buf) >= 0) { - avio_seek(pb, mov->tracks[i].vc1_info.struct_offset, SEEK_SET); - avio_write(pb, buf, 7); - avio_seek(pb, off, SEEK_SET); - } - } - av_freep(&mov->tracks[i].cluster); - av_freep(&mov->tracks[i].frag_info); - - if (mov->tracks[i].vos_len) - av_free(mov->tracks[i].vos_data); - - } - - av_freep(&mov->tracks); - - return res; -} - -#if CONFIG_MOV_MUXER -MOV_CLASS(mov) -AVOutputFormat ff_mov_muxer = { - .name = "mov", - .long_name = NULL_IF_CONFIG_SMALL("QuickTime / MOV"), - .extensions = "mov", - .priv_data_size = sizeof(MOVMuxContext), - .audio_codec = AV_CODEC_ID_AAC, - .video_codec = CONFIG_LIBX264_ENCODER ? - AV_CODEC_ID_H264 : AV_CODEC_ID_MPEG4, - .write_header = mov_write_header, - .write_packet = mov_write_packet, - .write_trailer = mov_write_trailer, - .flags = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH, - .codec_tag = (const AVCodecTag* const []){ - ff_codec_movvideo_tags, ff_codec_movaudio_tags, 0 - }, - .priv_class = &mov_muxer_class, -}; -#endif -#if CONFIG_TGP_MUXER -MOV_CLASS(tgp) -AVOutputFormat ff_tgp_muxer = { - .name = "3gp", - .long_name = NULL_IF_CONFIG_SMALL("3GP (3GPP file format)"), - .extensions = "3gp", - .priv_data_size = sizeof(MOVMuxContext), - .audio_codec = AV_CODEC_ID_AMR_NB, - .video_codec = AV_CODEC_ID_H263, - .write_header = mov_write_header, - .write_packet = mov_write_packet, - .write_trailer = mov_write_trailer, - .flags = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH, - .codec_tag = (const AVCodecTag* const []){ codec_3gp_tags, 0 }, - .priv_class = &tgp_muxer_class, -}; -#endif -#if CONFIG_MP4_MUXER -MOV_CLASS(mp4) -AVOutputFormat ff_mp4_muxer = { - .name = "mp4", - .long_name = NULL_IF_CONFIG_SMALL("MP4 (MPEG-4 Part 14)"), - .mime_type = "application/mp4", - .extensions = "mp4", - .priv_data_size = sizeof(MOVMuxContext), - .audio_codec = AV_CODEC_ID_AAC, - .video_codec = CONFIG_LIBX264_ENCODER ? - AV_CODEC_ID_H264 : AV_CODEC_ID_MPEG4, - .write_header = mov_write_header, - .write_packet = mov_write_packet, - .write_trailer = mov_write_trailer, - .flags = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH, - .codec_tag = (const AVCodecTag* const []){ ff_mp4_obj_type, 0 }, - .priv_class = &mp4_muxer_class, -}; -#endif -#if CONFIG_PSP_MUXER -MOV_CLASS(psp) -AVOutputFormat ff_psp_muxer = { - .name = "psp", - .long_name = NULL_IF_CONFIG_SMALL("PSP MP4 (MPEG-4 Part 14)"), - .extensions = "mp4,psp", - .priv_data_size = sizeof(MOVMuxContext), - .audio_codec = AV_CODEC_ID_AAC, - .video_codec = CONFIG_LIBX264_ENCODER ? - AV_CODEC_ID_H264 : AV_CODEC_ID_MPEG4, - .write_header = mov_write_header, - .write_packet = mov_write_packet, - .write_trailer = mov_write_trailer, - .flags = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH, - .codec_tag = (const AVCodecTag* const []){ ff_mp4_obj_type, 0 }, - .priv_class = &psp_muxer_class, -}; -#endif -#if CONFIG_TG2_MUXER -MOV_CLASS(tg2) -AVOutputFormat ff_tg2_muxer = { - .name = "3g2", - .long_name = NULL_IF_CONFIG_SMALL("3GP2 (3GPP2 file format)"), - .extensions = "3g2", - .priv_data_size = sizeof(MOVMuxContext), - .audio_codec = AV_CODEC_ID_AMR_NB, - .video_codec = AV_CODEC_ID_H263, - .write_header = mov_write_header, - .write_packet = mov_write_packet, - .write_trailer = mov_write_trailer, - .flags = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH, - .codec_tag = (const AVCodecTag* const []){ codec_3gp_tags, 0 }, - .priv_class = &tg2_muxer_class, -}; -#endif -#if CONFIG_IPOD_MUXER -MOV_CLASS(ipod) -AVOutputFormat ff_ipod_muxer = { - .name = "ipod", - .long_name = NULL_IF_CONFIG_SMALL("iPod H.264 MP4 (MPEG-4 Part 14)"), - .mime_type = "application/mp4", - .extensions = "m4v,m4a", - .priv_data_size = sizeof(MOVMuxContext), - .audio_codec = AV_CODEC_ID_AAC, - .video_codec = AV_CODEC_ID_H264, - .write_header = mov_write_header, - .write_packet = mov_write_packet, - .write_trailer = mov_write_trailer, - .flags = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH, - .codec_tag = (const AVCodecTag* const []){ codec_ipod_tags, 0 }, - .priv_class = &ipod_muxer_class, -}; -#endif -#if CONFIG_ISMV_MUXER -MOV_CLASS(ismv) -AVOutputFormat ff_ismv_muxer = { - .name = "ismv", - .long_name = NULL_IF_CONFIG_SMALL("ISMV/ISMA (Smooth Streaming)"), - .mime_type = "application/mp4", - .extensions = "ismv,isma", - .priv_data_size = sizeof(MOVMuxContext), - .audio_codec = AV_CODEC_ID_AAC, - .video_codec = AV_CODEC_ID_H264, - .write_header = mov_write_header, - .write_packet = mov_write_packet, - .write_trailer = mov_write_trailer, - .flags = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH, - .codec_tag = (const AVCodecTag* const []){ ff_mp4_obj_type, 0 }, - .priv_class = &ismv_muxer_class, -}; -#endif -#if CONFIG_F4V_MUXER -MOV_CLASS(f4v) -AVOutputFormat ff_f4v_muxer = { - .name = "f4v", - .long_name = NULL_IF_CONFIG_SMALL("F4V Adobe Flash Video"), - .mime_type = "application/f4v", - .extensions = "f4v", - .priv_data_size = sizeof(MOVMuxContext), - .audio_codec = AV_CODEC_ID_AAC, - .video_codec = AV_CODEC_ID_H264, - .write_header = mov_write_header, - .write_packet = mov_write_packet, - .write_trailer = mov_write_trailer, - .flags = AVFMT_GLOBALHEADER | AVFMT_ALLOW_FLUSH, - .codec_tag = (const AVCodecTag* const []){ codec_f4v_tags, 0 }, - .priv_class = &f4v_muxer_class, -}; -#endif diff --git a/ffmpeg1/libavformat/movenc.h b/ffmpeg1/libavformat/movenc.h deleted file mode 100644 index a5db895..0000000 --- a/ffmpeg1/libavformat/movenc.h +++ /dev/null @@ -1,190 +0,0 @@ -/* - * MOV, 3GP, MP4 muxer - * Copyright (c) 2003 Thomas Raivio - * Copyright (c) 2004 Gildas Bazin - * Copyright (c) 2009 Baptiste Coudurier - * - * 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 AVFORMAT_MOVENC_H -#define AVFORMAT_MOVENC_H - -#include "avformat.h" - -#define MOV_INDEX_CLUSTER_SIZE 16384 -#define MOV_TIMESCALE 1000 - -#define RTP_MAX_PACKET_SIZE 1450 - -#define MODE_MP4 0x01 -#define MODE_MOV 0x02 -#define MODE_3GP 0x04 -#define MODE_PSP 0x08 // example working PSP command line: -// 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 -#define MODE_F4V 0x80 - -typedef struct MOVIentry { - uint64_t pos; - int64_t dts; - unsigned int size; - unsigned int samples_in_chunk; - unsigned int chunkNum; ///< Chunk number if the current entry is a chunk start otherwise 0 - unsigned int entries; - int cts; -#define MOV_SYNC_SAMPLE 0x0001 -#define MOV_PARTIAL_SYNC_SAMPLE 0x0002 - uint32_t flags; -} MOVIentry; - -typedef struct HintSample { - uint8_t *data; - int size; - int sample_number; - int offset; - int own_data; -} HintSample; - -typedef struct HintSampleQueue { - int size; - int len; - HintSample *samples; -} HintSampleQueue; - -typedef struct MOVFragmentInfo { - int64_t offset; - int64_t time; - int64_t duration; - int64_t tfrf_offset; -} MOVFragmentInfo; - -typedef struct MOVIndex { - int mode; - int entry; - unsigned timescale; - uint64_t time; - int64_t track_duration; - int last_sample_is_subtitle_end; - long sample_count; - long sample_size; - long chunkCount; - int has_keyframes; -#define MOV_TRACK_CTTS 0x0001 -#define MOV_TRACK_STPS 0x0002 - uint32_t flags; -#define MOV_TIMECODE_FLAG_DROPFRAME 0x0001 -#define MOV_TIMECODE_FLAG_24HOURSMAX 0x0002 -#define MOV_TIMECODE_FLAG_ALLOWNEGATIVE 0x0004 - uint32_t timecode_flags; - int language; - int secondary; - int track_id; - int tag; ///< stsd fourcc - AVCodecContext *enc; - - int vos_len; - uint8_t *vos_data; - 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 - 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 (or tmcd) track describes - AVFormatContext *rtp_ctx; ///< the format context for the hinting rtp muxer - uint32_t prev_rtp_ts; - int64_t cur_rtp_ts_unwrapped; - uint32_t max_packet_size; - - 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; - - struct { - int64_t struct_offset; - int first_packet_seq; - int first_packet_entry; - int packet_seq; - int packet_entry; - int slices; - } vc1_info; -} MOVTrack; - -typedef struct MOVMuxContext { - const AVClass *av_class; - int mode; - int64_t time; - int nb_streams; - int nb_meta_tmcd; ///< number of new created tmcd track based on metadata (aka not data copy) - int chapter_track; ///< qt chapter track number - int64_t mdat_pos; - uint64_t mdat_size; - MOVTrack *tracks; - - int flags; - int rtp_flags; - int reserved_moov_size; ///< 0 for disabled, -1 for automatic, size otherwise - int64_t reserved_moov_pos; - - int iods_skip; - int iods_video_profile; - int iods_audio_profile; - - int fragments; - int max_fragment_duration; - int min_fragment_duration; - int max_fragment_size; - int ism_lookahead; - AVIOContext *mdat_buf; - - int use_editlist; -} 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 -#define FF_MOV_FLAG_ISML 64 -#define FF_MOV_FLAG_FASTSTART 128 - -int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt); - -int ff_mov_init_hinting(AVFormatContext *s, int index, int src_index); -int ff_mov_add_hinted_packet(AVFormatContext *s, AVPacket *pkt, - int track_index, int sample, - uint8_t *sample_data, int sample_size); -void ff_mov_close_hinting(MOVTrack *track); - -#endif /* AVFORMAT_MOVENC_H */ diff --git a/ffmpeg1/libavformat/movenchint.c b/ffmpeg1/libavformat/movenchint.c deleted file mode 100644 index cc90f0b..0000000 --- a/ffmpeg1/libavformat/movenchint.c +++ /dev/null @@ -1,462 +0,0 @@ -/* - * MOV, 3GP, MP4 muxer RTP hinting - * Copyright (c) 2010 Martin Storsjo - * - * 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 "movenc.h" -#include "libavutil/intreadwrite.h" -#include "internal.h" -#include "rtpenc_chain.h" -#include "avio_internal.h" -#include "rtp.h" - -int ff_mov_init_hinting(AVFormatContext *s, int index, int src_index) -{ - MOVMuxContext *mov = s->priv_data; - MOVTrack *track = &mov->tracks[index]; - MOVTrack *src_track = &mov->tracks[src_index]; - AVStream *src_st = s->streams[src_index]; - int ret = AVERROR(ENOMEM); - - track->tag = MKTAG('r','t','p',' '); - track->src_track = src_index; - - track->enc = avcodec_alloc_context3(NULL); - if (!track->enc) - goto fail; - track->enc->codec_type = AVMEDIA_TYPE_DATA; - track->enc->codec_tag = track->tag; - - ret = ff_rtp_chain_mux_open(&track->rtp_ctx, s, src_st, NULL, - RTP_MAX_PACKET_SIZE, src_index); - if (ret < 0) - goto fail; - - /* Copy the RTP AVStream timebase back to the hint AVStream */ - track->timescale = track->rtp_ctx->streams[0]->time_base.den; - - /* Mark the hinted track that packets written to it should be - * sent to this track for hinting. */ - src_track->hint_track = index; - return 0; -fail: - av_log(s, AV_LOG_WARNING, - "Unable to initialize hinting of stream %d\n", src_index); - av_freep(&track->enc); - /* Set a default timescale, to avoid crashes in av_dump_format */ - track->timescale = 90000; - return ret; -} - -/** - * Remove the first sample from the sample queue. - */ -static void sample_queue_pop(HintSampleQueue *queue) -{ - if (queue->len <= 0) - return; - if (queue->samples[0].own_data) - av_free(queue->samples[0].data); - queue->len--; - memmove(queue->samples, queue->samples + 1, sizeof(HintSample)*queue->len); -} - -/** - * Empty the sample queue, releasing all memory. - */ -static void sample_queue_free(HintSampleQueue *queue) -{ - int i; - for (i = 0; i < queue->len; i++) - if (queue->samples[i].own_data) - av_free(queue->samples[i].data); - av_freep(&queue->samples); - queue->len = 0; - queue->size = 0; -} - -/** - * Add a reference to the sample data to the sample queue. The data is - * not copied. sample_queue_retain should be called before pkt->data - * is reused/freed. - */ -static void sample_queue_push(HintSampleQueue *queue, uint8_t *data, int size, - int sample) -{ - /* No need to keep track of smaller samples, since describing them - * with immediates is more efficient. */ - if (size <= 14) - return; - if (!queue->samples || queue->len >= queue->size) { - HintSample* samples; - queue->size += 10; - samples = av_realloc(queue->samples, sizeof(HintSample)*queue->size); - if (!samples) - return; - queue->samples = samples; - } - queue->samples[queue->len].data = data; - queue->samples[queue->len].size = size; - queue->samples[queue->len].sample_number = sample; - queue->samples[queue->len].offset = 0; - queue->samples[queue->len].own_data = 0; - queue->len++; -} - -/** - * Make local copies of all referenced sample data in the queue. - */ -static void sample_queue_retain(HintSampleQueue *queue) -{ - int i; - for (i = 0; i < queue->len; ) { - HintSample *sample = &queue->samples[i]; - if (!sample->own_data) { - uint8_t* ptr = av_malloc(sample->size); - if (!ptr) { - /* Unable to allocate memory for this one, remove it */ - memmove(queue->samples + i, queue->samples + i + 1, - sizeof(HintSample)*(queue->len - i - 1)); - queue->len--; - continue; - } - memcpy(ptr, sample->data, sample->size); - sample->data = ptr; - sample->own_data = 1; - } - i++; - } -} - -/** - * Find matches of needle[n_pos ->] within haystack. If a sufficiently - * large match is found, matching bytes before n_pos are included - * in the match, too (within the limits of the arrays). - * - * @param haystack buffer that may contain parts of needle - * @param h_len length of the haystack buffer - * @param needle buffer containing source data that have been used to - * construct haystack - * @param n_pos start position in needle used for looking for matches - * @param n_len length of the needle buffer - * @param match_h_offset_ptr offset of the first matching byte within haystack - * @param match_n_offset_ptr offset of the first matching byte within needle - * @param match_len_ptr length of the matched segment - * @return 0 if a match was found, < 0 if no match was found - */ -static int match_segments(const uint8_t *haystack, int h_len, - const uint8_t *needle, int n_pos, int n_len, - int *match_h_offset_ptr, int *match_n_offset_ptr, - int *match_len_ptr) -{ - int h_pos; - for (h_pos = 0; h_pos < h_len; h_pos++) { - int match_len = 0; - int match_h_pos, match_n_pos; - - /* Check how many bytes match at needle[n_pos] and haystack[h_pos] */ - while (h_pos + match_len < h_len && n_pos + match_len < n_len && - needle[n_pos + match_len] == haystack[h_pos + match_len]) - match_len++; - if (match_len <= 8) - continue; - - /* If a sufficiently large match was found, try to expand - * the matched segment backwards. */ - match_h_pos = h_pos; - match_n_pos = n_pos; - while (match_n_pos > 0 && match_h_pos > 0 && - needle[match_n_pos - 1] == haystack[match_h_pos - 1]) { - match_n_pos--; - match_h_pos--; - match_len++; - } - if (match_len <= 14) - continue; - *match_h_offset_ptr = match_h_pos; - *match_n_offset_ptr = match_n_pos; - *match_len_ptr = match_len; - return 0; - } - return -1; -} - -/** - * Look for segments in samples in the sample queue matching the data - * in ptr. Samples not matching are removed from the queue. If a match - * is found, the next time it will look for matches starting from the - * end of the previous matched segment. - * - * @param data data to find matches for in the sample queue - * @param len length of the data buffer - * @param queue samples used for looking for matching segments - * @param pos the offset in data of the matched segment - * @param match_sample the number of the sample that contained the match - * @param match_offset the offset of the matched segment within the sample - * @param match_len the length of the matched segment - * @return 0 if a match was found, < 0 if no match was found - */ -static int find_sample_match(const uint8_t *data, int len, - HintSampleQueue *queue, int *pos, - int *match_sample, int *match_offset, - int *match_len) -{ - while (queue->len > 0) { - HintSample *sample = &queue->samples[0]; - /* If looking for matches in a new sample, skip the first 5 bytes, - * since they often may be modified/removed in the output packet. */ - if (sample->offset == 0 && sample->size > 5) - sample->offset = 5; - - if (match_segments(data, len, sample->data, sample->offset, - sample->size, pos, match_offset, match_len) == 0) { - *match_sample = sample->sample_number; - /* Next time, look for matches at this offset, with a little - * margin to this match. */ - sample->offset = *match_offset + *match_len + 5; - if (sample->offset + 10 >= sample->size) - sample_queue_pop(queue); /* Not enough useful data left */ - return 0; - } - - if (sample->offset < 10 && sample->size > 20) { - /* No match found from the start of the sample, - * try from the middle of the sample instead. */ - sample->offset = sample->size/2; - } else { - /* No match for this sample, remove it */ - sample_queue_pop(queue); - } - } - return -1; -} - -static void output_immediate(const uint8_t *data, int size, - AVIOContext *out, int *entries) -{ - while (size > 0) { - int len = size; - if (len > 14) - len = 14; - avio_w8(out, 1); /* immediate constructor */ - avio_w8(out, len); /* amount of valid data */ - avio_write(out, data, len); - data += len; - size -= len; - - for (; len < 14; len++) - avio_w8(out, 0); - - (*entries)++; - } -} - -static void output_match(AVIOContext *out, int match_sample, - int match_offset, int match_len, int *entries) -{ - avio_w8(out, 2); /* sample constructor */ - avio_w8(out, 0); /* track reference */ - avio_wb16(out, match_len); - avio_wb32(out, match_sample); - avio_wb32(out, match_offset); - avio_wb16(out, 1); /* bytes per block */ - avio_wb16(out, 1); /* samples per block */ - (*entries)++; -} - -static void describe_payload(const uint8_t *data, int size, - AVIOContext *out, int *entries, - HintSampleQueue *queue) -{ - /* Describe the payload using different constructors */ - while (size > 0) { - int match_sample, match_offset, match_len, pos; - if (find_sample_match(data, size, queue, &pos, &match_sample, - &match_offset, &match_len) < 0) - break; - output_immediate(data, pos, out, entries); - data += pos; - size -= pos; - output_match(out, match_sample, match_offset, match_len, entries); - data += match_len; - size -= match_len; - } - output_immediate(data, size, out, entries); -} - -/** - * Write an RTP hint (that may contain one or more RTP packets) - * for the packets in data. data contains one or more packets with a - * BE32 size header. - * - * @param out buffer where the hints are written - * @param data buffer containing RTP packets - * @param size the size of the data buffer - * @param trk the MOVTrack for the hint track - * @param pts pointer where the timestamp for the written RTP hint is stored - * @return the number of RTP packets in the written hint - */ -static int write_hint_packets(AVIOContext *out, const uint8_t *data, - int size, MOVTrack *trk, int64_t *pts) -{ - int64_t curpos; - int64_t count_pos, entries_pos; - int count = 0, entries; - - count_pos = avio_tell(out); - /* RTPsample header */ - avio_wb16(out, 0); /* packet count */ - avio_wb16(out, 0); /* reserved */ - - while (size > 4) { - uint32_t packet_len = AV_RB32(data); - uint16_t seq; - uint32_t ts; - - data += 4; - size -= 4; - if (packet_len > size || packet_len <= 12) - break; - if (RTP_PT_IS_RTCP(data[1])) { - /* RTCP packet, just skip */ - data += packet_len; - size -= packet_len; - continue; - } - - if (packet_len > trk->max_packet_size) - trk->max_packet_size = packet_len; - - seq = AV_RB16(&data[2]); - ts = AV_RB32(&data[4]); - - if (trk->prev_rtp_ts == 0) - trk->prev_rtp_ts = ts; - /* Unwrap the 32-bit RTP timestamp that wraps around often - * into a not (as often) wrapping 64-bit timestamp. */ - trk->cur_rtp_ts_unwrapped += (int32_t) (ts - trk->prev_rtp_ts); - trk->prev_rtp_ts = ts; - if (*pts == AV_NOPTS_VALUE) - *pts = trk->cur_rtp_ts_unwrapped; - - count++; - /* RTPpacket header */ - avio_wb32(out, 0); /* relative_time */ - avio_write(out, data, 2); /* RTP header */ - avio_wb16(out, seq); /* RTPsequenceseed */ - avio_wb16(out, 0); /* reserved + flags */ - entries_pos = avio_tell(out); - avio_wb16(out, 0); /* entry count */ - - data += 12; - size -= 12; - packet_len -= 12; - - entries = 0; - /* Write one or more constructors describing the payload data */ - describe_payload(data, packet_len, out, &entries, &trk->sample_queue); - data += packet_len; - size -= packet_len; - - curpos = avio_tell(out); - avio_seek(out, entries_pos, SEEK_SET); - avio_wb16(out, entries); - avio_seek(out, curpos, SEEK_SET); - } - - curpos = avio_tell(out); - avio_seek(out, count_pos, SEEK_SET); - avio_wb16(out, count); - avio_seek(out, curpos, SEEK_SET); - return count; -} - -int ff_mov_add_hinted_packet(AVFormatContext *s, AVPacket *pkt, - int track_index, int sample, - uint8_t *sample_data, int sample_size) -{ - MOVMuxContext *mov = s->priv_data; - MOVTrack *trk = &mov->tracks[track_index]; - AVFormatContext *rtp_ctx = trk->rtp_ctx; - uint8_t *buf = NULL; - int size; - AVIOContext *hintbuf = NULL; - AVPacket hint_pkt; - int ret = 0, count; - - if (!rtp_ctx) - return AVERROR(ENOENT); - if (!rtp_ctx->pb) - return AVERROR(ENOMEM); - - if (sample_data) - sample_queue_push(&trk->sample_queue, sample_data, sample_size, sample); - else - sample_queue_push(&trk->sample_queue, pkt->data, pkt->size, sample); - - /* Feed the packet to the RTP muxer */ - ff_write_chained(rtp_ctx, 0, pkt, s); - - /* Fetch the output from the RTP muxer, open a new output buffer - * for next time. */ - size = avio_close_dyn_buf(rtp_ctx->pb, &buf); - if ((ret = ffio_open_dyn_packet_buf(&rtp_ctx->pb, - RTP_MAX_PACKET_SIZE)) < 0) - goto done; - - if (size <= 0) - goto done; - - /* Open a buffer for writing the hint */ - if ((ret = avio_open_dyn_buf(&hintbuf)) < 0) - goto done; - av_init_packet(&hint_pkt); - count = write_hint_packets(hintbuf, buf, size, trk, &hint_pkt.dts); - av_freep(&buf); - - /* Write the hint data into the hint track */ - hint_pkt.size = size = avio_close_dyn_buf(hintbuf, &buf); - hint_pkt.data = buf; - hint_pkt.pts = hint_pkt.dts; - hint_pkt.stream_index = track_index; - if (pkt->flags & AV_PKT_FLAG_KEY) - hint_pkt.flags |= AV_PKT_FLAG_KEY; - if (count > 0) - ff_mov_write_packet(s, &hint_pkt); -done: - av_free(buf); - sample_queue_retain(&trk->sample_queue); - return ret; -} - -void ff_mov_close_hinting(MOVTrack *track) { - AVFormatContext* rtp_ctx = track->rtp_ctx; - uint8_t *ptr; - - av_freep(&track->enc); - sample_queue_free(&track->sample_queue); - if (!rtp_ctx) - return; - if (rtp_ctx->pb) { - av_write_trailer(rtp_ctx); - avio_close_dyn_buf(rtp_ctx->pb, &ptr); - av_free(ptr); - } - avformat_free_context(rtp_ctx); -} diff --git a/ffmpeg1/libavformat/mp3dec.c b/ffmpeg1/libavformat/mp3dec.c deleted file mode 100644 index 57e4ba3..0000000 --- a/ffmpeg1/libavformat/mp3dec.c +++ /dev/null @@ -1,329 +0,0 @@ -/* - * MP3 demuxer - * Copyright (c) 2003 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 "libavutil/avstring.h" -#include "libavutil/intreadwrite.h" -#include "libavutil/dict.h" -#include "libavutil/mathematics.h" -#include "avformat.h" -#include "internal.h" -#include "id3v2.h" -#include "id3v1.h" -#include "libavcodec/mpegaudiodecheader.h" - -#define XING_FLAG_FRAMES 0x01 -#define XING_FLAG_SIZE 0x02 -#define XING_FLAG_TOC 0x04 - -#define XING_TOC_COUNT 100 - -typedef struct { - int64_t filesize; - int xing_toc; - int start_pad; - int end_pad; -} MP3Context; - -/* mp3 read */ - -static int mp3_read_probe(AVProbeData *p) -{ - int max_frames, first_frames = 0; - int fsize, frames, sample_rate; - uint32_t header; - const uint8_t *buf, *buf0, *buf2, *end; - AVCodecContext avctx; - - buf0 = p->buf; - end = p->buf + p->buf_size - sizeof(uint32_t); - while(buf0 < end && !*buf0) - buf0++; - - max_frames = 0; - buf = buf0; - - for(; buf < end; buf= buf2+1) { - buf2 = buf; - - for(frames = 0; buf2 < end; frames++) { - header = AV_RB32(buf2); - fsize = avpriv_mpa_decode_header(&avctx, header, &sample_rate, &sample_rate, &sample_rate, &sample_rate); - if(fsize < 0) - break; - buf2 += fsize; - } - max_frames = FFMAX(max_frames, frames); - if(buf == buf0) - first_frames= frames; - } - // keep this in sync with ac3 probe, both need to avoid - // issues with MPEG-files! - if (first_frames>=4) return AVPROBE_SCORE_MAX/2+1; - else if(max_frames>200)return AVPROBE_SCORE_MAX/2; - else if(max_frames>=4) return AVPROBE_SCORE_MAX/4; - else if(ff_id3v2_match(buf0, ID3v2_DEFAULT_MAGIC) && 2*ff_id3v2_tag_len(buf0) >= p->buf_size) - return AVPROBE_SCORE_MAX/8; - else if(max_frames>=1) return 1; - else return 0; -//mpegps_mp3_unrecognized_format.mpg has max_frames=3 -} - -static void read_xing_toc(AVFormatContext *s, int64_t filesize, int64_t duration) -{ - int i; - MP3Context *mp3 = s->priv_data; - - if (!filesize && - !(filesize = avio_size(s->pb))) { - av_log(s, AV_LOG_WARNING, "Cannot determine file size, skipping TOC table.\n"); - return; - } - - for (i = 0; i < XING_TOC_COUNT; i++) { - uint8_t b = avio_r8(s->pb); - - av_add_index_entry(s->streams[0], - av_rescale(b, filesize, 256), - av_rescale(i, duration, XING_TOC_COUNT), - 0, 0, AVINDEX_KEYFRAME); - } - mp3->xing_toc = 1; -} - -/** - * Try to find Xing/Info/VBRI tags and compute duration from info therein - */ -static int mp3_parse_vbr_tags(AVFormatContext *s, AVStream *st, int64_t base) -{ - MP3Context *mp3 = s->priv_data; - uint32_t v, spf; - unsigned frames = 0; /* Total number of frames in file */ - unsigned size = 0; /* Total number of bytes in the stream */ - const int64_t xing_offtbl[2][2] = {{32, 17}, {17,9}}; - MPADecodeHeader c; - int vbrtag_size = 0; - int is_cbr; - - v = avio_rb32(s->pb); - if(ff_mpa_check_header(v) < 0) - return -1; - - if (avpriv_mpegaudio_decode_header(&c, v) == 0) - vbrtag_size = c.frame_size; - if(c.layer != 3) - return -1; - - spf = c.lsf ? 576 : 1152; /* Samples per frame, layer 3 */ - - /* Check for Xing / Info tag */ - avio_skip(s->pb, xing_offtbl[c.lsf == 1][c.nb_channels == 1]); - v = avio_rb32(s->pb); - is_cbr = v == MKBETAG('I', 'n', 'f', 'o'); - if (v == MKBETAG('X', 'i', 'n', 'g') || is_cbr) { - v = avio_rb32(s->pb); - if(v & XING_FLAG_FRAMES) - frames = avio_rb32(s->pb); - if(v & XING_FLAG_SIZE) - size = avio_rb32(s->pb); - if (v & XING_FLAG_TOC && frames) - read_xing_toc(s, size, av_rescale_q(frames, (AVRational){spf, c.sample_rate}, - st->time_base)); - if(v & 8) - avio_skip(s->pb, 4); - - v = avio_rb32(s->pb); - if(v == MKBETAG('L', 'A', 'M', 'E') || v == MKBETAG('L', 'a', 'v', 'f')) { - avio_skip(s->pb, 21-4); - v= avio_rb24(s->pb); - mp3->start_pad = v>>12; - mp3-> end_pad = v&4095; - st->skip_samples = mp3->start_pad + 528 + 1; - av_log(s, AV_LOG_DEBUG, "pad %d %d\n", mp3->start_pad, mp3-> end_pad); - } - } - - /* Check for VBRI tag (always 32 bytes after end of mpegaudio header) */ - avio_seek(s->pb, base + 4 + 32, SEEK_SET); - v = avio_rb32(s->pb); - if(v == MKBETAG('V', 'B', 'R', 'I')) { - /* Check tag version */ - if(avio_rb16(s->pb) == 1) { - /* skip delay and quality */ - avio_skip(s->pb, 4); - size = avio_rb32(s->pb); - frames = avio_rb32(s->pb); - } - } - - if(!frames && !size) - return -1; - - /* Skip the vbr tag frame */ - avio_seek(s->pb, base + vbrtag_size, SEEK_SET); - - if(frames) - st->duration = av_rescale_q(frames, (AVRational){spf, c.sample_rate}, - st->time_base); - if (size && frames && !is_cbr) - st->codec->bit_rate = av_rescale(size, 8 * c.sample_rate, frames * (int64_t)spf); - - return 0; -} - -static int mp3_read_header(AVFormatContext *s) -{ - MP3Context *mp3 = s->priv_data; - AVStream *st; - int64_t off; - - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = AV_CODEC_ID_MP3; - st->need_parsing = AVSTREAM_PARSE_FULL_RAW; - st->start_time = 0; - - // lcm of all mp3 sample rates - avpriv_set_pts_info(st, 64, 1, 14112000); - - s->pb->maxsize = -1; - off = avio_tell(s->pb); - - if (!av_dict_get(s->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX)) - ff_id3v1_read(s); - - if(s->pb->seekable) - mp3->filesize = avio_size(s->pb); - - if (mp3_parse_vbr_tags(s, st, off) < 0) - avio_seek(s->pb, off, SEEK_SET); - - /* the parameters will be extracted from the compressed bitstream */ - return 0; -} - -#define MP3_PACKET_SIZE 1024 - -static int mp3_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - MP3Context *mp3 = s->priv_data; - int ret, size; - int64_t pos; - - size= MP3_PACKET_SIZE; - pos = avio_tell(s->pb); - if(mp3->filesize > ID3v1_TAG_SIZE && pos < mp3->filesize) - size= FFMIN(size, mp3->filesize - pos); - - ret= av_get_packet(s->pb, pkt, size); - if (ret <= 0) { - if(ret<0) - return ret; - return AVERROR_EOF; - } - - pkt->flags &= ~AV_PKT_FLAG_CORRUPT; - pkt->stream_index = 0; - - if (ret >= ID3v1_TAG_SIZE && - memcmp(&pkt->data[ret - ID3v1_TAG_SIZE], "TAG", 3) == 0) - ret -= ID3v1_TAG_SIZE; - - /* note: we need to modify the packet size here to handle the last - packet */ - pkt->size = ret; - return ret; -} - -static int check(AVFormatContext *s, int64_t pos) -{ - int64_t ret = avio_seek(s->pb, pos, SEEK_SET); - unsigned header; - MPADecodeHeader sd; - if (ret < 0) - return ret; - header = avio_rb32(s->pb); - if (ff_mpa_check_header(header) < 0) - return -1; - if (avpriv_mpegaudio_decode_header(&sd, header) == 1) - return -1; - return sd.frame_size; -} - -static int mp3_seek(AVFormatContext *s, int stream_index, int64_t timestamp, - int flags) -{ - MP3Context *mp3 = s->priv_data; - AVIndexEntry *ie; - AVStream *st = s->streams[0]; - int64_t ret = av_index_search_timestamp(st, timestamp, flags); - int i, j; - - if (!mp3->xing_toc) { - st->skip_samples = timestamp <= 0 ? mp3->start_pad + 528 + 1 : 0; - - return -1; - } - - if (ret < 0) - return ret; - - ie = &st->index_entries[ret]; - ret = avio_seek(s->pb, ie->pos, SEEK_SET); - if (ret < 0) - return ret; - -#define MIN_VALID 3 - for(i=0; i<4096; i++) { - int64_t pos = ie->pos + i; - for(j=0; jpb, ie->pos + i, SEEK_SET); - if (ret < 0) - return ret; - ff_update_cur_dts(s, st, ie->timestamp); - st->skip_samples = ie->timestamp <= 0 ? mp3->start_pad + 528 + 1 : 0; - return 0; -} - -AVInputFormat ff_mp3_demuxer = { - .name = "mp3", - .long_name = NULL_IF_CONFIG_SMALL("MP2/3 (MPEG audio layer 2/3)"), - .priv_data_size = sizeof(MP3Context), - .read_probe = mp3_read_probe, - .read_header = mp3_read_header, - .read_packet = mp3_read_packet, - .read_seek = mp3_seek, - .flags = AVFMT_GENERIC_INDEX, - .extensions = "mp2,mp3,m2a", /* XXX: use probe */ -}; diff --git a/ffmpeg1/libavformat/mp3enc.c b/ffmpeg1/libavformat/mp3enc.c deleted file mode 100644 index ee0956e..0000000 --- a/ffmpeg1/libavformat/mp3enc.c +++ /dev/null @@ -1,522 +0,0 @@ -/* - * MP3 muxer - * Copyright (c) 2003 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 "avio_internal.h" -#include "id3v1.h" -#include "id3v2.h" -#include "rawenc.h" -#include "libavutil/avstring.h" -#include "libavcodec/mpegaudio.h" -#include "libavcodec/mpegaudiodata.h" -#include "libavcodec/mpegaudiodecheader.h" -#include "libavutil/intreadwrite.h" -#include "libavutil/opt.h" -#include "libavcodec/mpegaudio.h" -#include "libavcodec/mpegaudiodata.h" -#include "libavcodec/mpegaudiodecheader.h" -#include "libavformat/avio_internal.h" -#include "libavutil/dict.h" -#include "libavutil/avassert.h" - -static int id3v1_set_string(AVFormatContext *s, const char *key, - uint8_t *buf, int buf_size) -{ - AVDictionaryEntry *tag; - if ((tag = av_dict_get(s->metadata, key, NULL, 0))) - av_strlcpy(buf, tag->value, buf_size); - return !!tag; -} - -static int id3v1_create_tag(AVFormatContext *s, uint8_t *buf) -{ - AVDictionaryEntry *tag; - int i, count = 0; - - memset(buf, 0, ID3v1_TAG_SIZE); /* fail safe */ - buf[0] = 'T'; - buf[1] = 'A'; - buf[2] = 'G'; - /* we knowingly overspecify each tag length by one byte to compensate for the mandatory null byte added by av_strlcpy */ - count += id3v1_set_string(s, "TIT2", buf + 3, 30 + 1); //title - count += id3v1_set_string(s, "TPE1", buf + 33, 30 + 1); //author|artist - count += id3v1_set_string(s, "TALB", buf + 63, 30 + 1); //album - count += id3v1_set_string(s, "TDRL", buf + 93, 4 + 1); //date - count += id3v1_set_string(s, "comment", buf + 97, 30 + 1); - if ((tag = av_dict_get(s->metadata, "TRCK", NULL, 0))) { //track - buf[125] = 0; - buf[126] = atoi(tag->value); - count++; - } - buf[127] = 0xFF; /* default to unknown genre */ - if ((tag = av_dict_get(s->metadata, "TCON", NULL, 0))) { //genre - for(i = 0; i <= ID3v1_GENRE_MAX; i++) { - if (!av_strcasecmp(tag->value, ff_id3v1_genre_str[i])) { - buf[127] = i; - count++; - break; - } - } - } - return count; -} - -#define XING_NUM_BAGS 400 -#define XING_TOC_SIZE 100 -// maximum size of the xing frame: offset/Xing/flags/frames/size/TOC -#define XING_MAX_SIZE (32 + 4 + 4 + 4 + 4 + XING_TOC_SIZE) - -typedef struct MP3Context { - const AVClass *class; - ID3v2EncContext id3; - int id3v2_version; - int write_id3v1; - - /* xing header */ - int64_t xing_offset; - int32_t frames; - int32_t size; - uint32_t want; - uint32_t seen; - uint32_t pos; - uint64_t bag[XING_NUM_BAGS]; - int initial_bitrate; - int has_variable_bitrate; - - /* index of the audio stream */ - int audio_stream_idx; - /* number of attached pictures we still need to write */ - int pics_to_write; - - /* audio packets are queued here until we get all the attached pictures */ - AVPacketList *queue, *queue_end; -} MP3Context; - -static const uint8_t xing_offtbl[2][2] = {{32, 17}, {17, 9}}; - -/* - * Write an empty XING header and initialize respective data. - */ -static int mp3_write_xing(AVFormatContext *s) -{ - MP3Context *mp3 = s->priv_data; - AVCodecContext *codec = s->streams[mp3->audio_stream_idx]->codec; - int bitrate_idx; - int best_bitrate_idx = -1; - int best_bitrate_error= INT_MAX; - int xing_offset; - int32_t header, mask; - MPADecodeHeader c; - int srate_idx, ver = 0, i, channels; - int needed; - const char *vendor = (codec->flags & CODEC_FLAG_BITEXACT) ? "Lavf" : LIBAVFORMAT_IDENT; - - if (!s->pb->seekable) - return 0; - - for (i = 0; i < FF_ARRAY_ELEMS(avpriv_mpa_freq_tab); i++) { - const uint16_t base_freq = avpriv_mpa_freq_tab[i]; - - if (codec->sample_rate == base_freq) ver = 0x3; // MPEG 1 - else if (codec->sample_rate == base_freq / 2) ver = 0x2; // MPEG 2 - else if (codec->sample_rate == base_freq / 4) ver = 0x0; // MPEG 2.5 - else continue; - - srate_idx = i; - break; - } - if (i == FF_ARRAY_ELEMS(avpriv_mpa_freq_tab)) { - av_log(s, AV_LOG_WARNING, "Unsupported sample rate, not writing Xing header.\n"); - return -1; - } - - switch (codec->channels) { - case 1: channels = MPA_MONO; break; - case 2: channels = MPA_STEREO; break; - default: av_log(s, AV_LOG_WARNING, "Unsupported number of channels, " - "not writing Xing header.\n"); - return -1; - } - - /* dummy MPEG audio header */ - header = 0xffU << 24; // sync - header |= (0x7 << 5 | ver << 3 | 0x1 << 1 | 0x1) << 16; // sync/audio-version/layer 3/no crc*/ - header |= (srate_idx << 2) << 8; - header |= channels << 6; - - for (bitrate_idx=1; bitrate_idx<15; bitrate_idx++) { - int error; - avpriv_mpegaudio_decode_header(&c, header | (bitrate_idx << (4+8))); - error= FFABS(c.bit_rate - codec->bit_rate); - if(error < best_bitrate_error){ - best_bitrate_error= error; - best_bitrate_idx = bitrate_idx; - } - } - av_assert0(best_bitrate_idx >= 0); - - for (bitrate_idx= best_bitrate_idx;; bitrate_idx++) { - if (15 == bitrate_idx) - return -1; - mask = bitrate_idx << (4+8); - header |= mask; - avpriv_mpegaudio_decode_header(&c, header); - xing_offset=xing_offtbl[c.lsf == 1][c.nb_channels == 1]; - needed = 4 // header - + xing_offset - + 4 // xing tag - + 4 // frames/size/toc flags - + 4 // frames - + 4 // size - + XING_TOC_SIZE // toc - + 24 - ; - - if (needed <= c.frame_size) - break; - header &= ~mask; - } - - avio_wb32(s->pb, header); - - ffio_fill(s->pb, 0, xing_offset); - mp3->xing_offset = avio_tell(s->pb); - ffio_wfourcc(s->pb, "Xing"); - avio_wb32(s->pb, 0x01 | 0x02 | 0x04); // frames / size / TOC - - mp3->size = c.frame_size; - mp3->want=1; - mp3->seen=0; - mp3->pos=0; - - avio_wb32(s->pb, 0); // frames - avio_wb32(s->pb, 0); // size - - // toc - for (i = 0; i < XING_TOC_SIZE; ++i) - avio_w8(s->pb, (uint8_t)(255 * i / XING_TOC_SIZE)); - - for (i = 0; i < strlen(vendor); ++i) - avio_w8(s->pb, vendor[i]); - for (; i < 21; ++i) - avio_w8(s->pb, 0); - avio_wb24(s->pb, FFMAX(codec->delay - 528 - 1, 0)<<12); - - ffio_fill(s->pb, 0, c.frame_size - needed); - - return 0; -} - -/* - * Add a frame to XING data. - * Following lame's "VbrTag.c". - */ -static void mp3_xing_add_frame(MP3Context *mp3, AVPacket *pkt) -{ - int i; - - mp3->frames++; - mp3->seen++; - mp3->size += pkt->size; - - if (mp3->want == mp3->seen) { - mp3->bag[mp3->pos] = mp3->size; - - if (XING_NUM_BAGS == ++mp3->pos) { - /* shrink table to half size by throwing away each second bag. */ - for (i = 1; i < XING_NUM_BAGS; i += 2) - mp3->bag[i >> 1] = mp3->bag[i]; - - /* double wanted amount per bag. */ - mp3->want *= 2; - /* adjust current position to half of table size. */ - mp3->pos = XING_NUM_BAGS / 2; - } - - mp3->seen = 0; - } -} - -static int mp3_write_audio_packet(AVFormatContext *s, AVPacket *pkt) -{ - MP3Context *mp3 = s->priv_data; - - if (pkt->data && pkt->size >= 4) { - MPADecodeHeader c; - int av_unused base; - uint32_t head = AV_RB32(pkt->data); - - if (ff_mpa_check_header(head) < 0) { - av_log(s, AV_LOG_WARNING, "Audio packet of size %d (starting with %08X...) " - "is invalid, writing it anyway.\n", pkt->size, head); - return ff_raw_write_packet(s, pkt); - } - avpriv_mpegaudio_decode_header(&c, head); - - if (!mp3->initial_bitrate) - mp3->initial_bitrate = c.bit_rate; - if ((c.bit_rate == 0) || (mp3->initial_bitrate != c.bit_rate)) - mp3->has_variable_bitrate = 1; - -#ifdef FILTER_VBR_HEADERS - /* filter out XING and INFO headers. */ - base = 4 + xing_offtbl[c.lsf == 1][c.nb_channels == 1]; - - if (base + 4 <= pkt->size) { - uint32_t v = AV_RB32(pkt->data + base); - - if (MKBETAG('X','i','n','g') == v || MKBETAG('I','n','f','o') == v) - return 0; - } - - /* filter out VBRI headers. */ - base = 4 + 32; - - if (base + 4 <= pkt->size && MKBETAG('V','B','R','I') == AV_RB32(pkt->data + base)) - return 0; -#endif - - if (mp3->xing_offset) - mp3_xing_add_frame(mp3, pkt); - } - - return ff_raw_write_packet(s, pkt); -} - -static int mp3_queue_flush(AVFormatContext *s) -{ - MP3Context *mp3 = s->priv_data; - AVPacketList *pktl; - int ret = 0, write = 1; - - ff_id3v2_finish(&mp3->id3, s->pb); - mp3_write_xing(s); - - while ((pktl = mp3->queue)) { - if (write && (ret = mp3_write_audio_packet(s, &pktl->pkt)) < 0) - write = 0; - av_free_packet(&pktl->pkt); - mp3->queue = pktl->next; - av_freep(&pktl); - } - mp3->queue_end = NULL; - return ret; -} - -static void mp3_update_xing(AVFormatContext *s) -{ - MP3Context *mp3 = s->priv_data; - int i; - - /* replace "Xing" identification string with "Info" for CBR files. */ - if (!mp3->has_variable_bitrate) { - avio_seek(s->pb, mp3->xing_offset, SEEK_SET); - ffio_wfourcc(s->pb, "Info"); - } - - avio_seek(s->pb, mp3->xing_offset + 8, SEEK_SET); - avio_wb32(s->pb, mp3->frames); - avio_wb32(s->pb, mp3->size); - - avio_w8(s->pb, 0); // first toc entry has to be zero. - - for (i = 1; i < XING_TOC_SIZE; ++i) { - int j = i * mp3->pos / XING_TOC_SIZE; - int seek_point = 256LL * mp3->bag[j] / mp3->size; - avio_w8(s->pb, FFMIN(seek_point, 255)); - } - - avio_seek(s->pb, 0, SEEK_END); -} - -static int mp3_write_trailer(struct AVFormatContext *s) -{ - uint8_t buf[ID3v1_TAG_SIZE]; - MP3Context *mp3 = s->priv_data; - - if (mp3->pics_to_write) { - av_log(s, AV_LOG_WARNING, "No packets were sent for some of the " - "attached pictures.\n"); - mp3_queue_flush(s); - } - - /* write the id3v1 tag */ - if (mp3->write_id3v1 && id3v1_create_tag(s, buf) > 0) { - avio_write(s->pb, buf, ID3v1_TAG_SIZE); - } - - if (mp3->xing_offset) - mp3_update_xing(s); - - return 0; -} - -static int query_codec(enum AVCodecID id, int std_compliance) -{ - const CodecMime *cm= ff_id3v2_mime_tags; - while(cm->id != AV_CODEC_ID_NONE) { - if(id == cm->id) - return MKTAG('A', 'P', 'I', 'C'); - cm++; - } - return -1; -} - -#if CONFIG_MP2_MUXER -AVOutputFormat ff_mp2_muxer = { - .name = "mp2", - .long_name = NULL_IF_CONFIG_SMALL("MP2 (MPEG audio layer 2)"), - .mime_type = "audio/x-mpeg", - .extensions = "mp2,m2a", - .audio_codec = AV_CODEC_ID_MP2, - .video_codec = AV_CODEC_ID_NONE, - .write_packet = ff_raw_write_packet, - .flags = AVFMT_NOTIMESTAMPS, -}; -#endif - -#if CONFIG_MP3_MUXER - -static const AVOption options[] = { - { "id3v2_version", "Select ID3v2 version to write. Currently 3 and 4 are supported.", - offsetof(MP3Context, id3v2_version), AV_OPT_TYPE_INT, {.i64 = 4}, 3, 4, AV_OPT_FLAG_ENCODING_PARAM}, - { "write_id3v1", "Enable ID3v1 writing. ID3v1 tags are written in UTF-8 which may not be supported by most software.", - offsetof(MP3Context, write_id3v1), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM}, - { NULL }, -}; - -static const AVClass mp3_muxer_class = { - .class_name = "MP3 muxer", - .item_name = av_default_item_name, - .option = options, - .version = LIBAVUTIL_VERSION_INT, -}; - -static int mp3_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - MP3Context *mp3 = s->priv_data; - - if (pkt->stream_index == mp3->audio_stream_idx) { - if (mp3->pics_to_write) { - /* buffer audio packets until we get all the pictures */ - AVPacketList *pktl = av_mallocz(sizeof(*pktl)); - if (!pktl) - return AVERROR(ENOMEM); - - pktl->pkt = *pkt; - pktl->pkt.buf = av_buffer_ref(pkt->buf); - if (!pktl->pkt.buf) { - av_freep(&pktl); - return AVERROR(ENOMEM); - } - - if (mp3->queue_end) - mp3->queue_end->next = pktl; - else - mp3->queue = pktl; - mp3->queue_end = pktl; - } else - return mp3_write_audio_packet(s, pkt); - } else { - int ret; - - /* warn only once for each stream */ - if (s->streams[pkt->stream_index]->nb_frames == 1) { - av_log(s, AV_LOG_WARNING, "Got more than one picture in stream %d," - " ignoring.\n", pkt->stream_index); - } - if (!mp3->pics_to_write || s->streams[pkt->stream_index]->nb_frames >= 1) - return 0; - - if ((ret = ff_id3v2_write_apic(s, &mp3->id3, pkt)) < 0) - return ret; - mp3->pics_to_write--; - - /* flush the buffered audio packets */ - if (!mp3->pics_to_write && - (ret = mp3_queue_flush(s)) < 0) - return ret; - } - - return 0; -} - -/** - * Write an ID3v2 header at beginning of stream - */ - -static int mp3_write_header(struct AVFormatContext *s) -{ - MP3Context *mp3 = s->priv_data; - int ret, i; - - /* check the streams -- we want exactly one audio and arbitrary number of - * video (attached pictures) */ - mp3->audio_stream_idx = -1; - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - if (mp3->audio_stream_idx >= 0 || st->codec->codec_id != AV_CODEC_ID_MP3) { - av_log(s, AV_LOG_ERROR, "Invalid audio stream. Exactly one MP3 " - "audio stream is required.\n"); - return AVERROR(EINVAL); - } - mp3->audio_stream_idx = i; - } else if (st->codec->codec_type != AVMEDIA_TYPE_VIDEO) { - av_log(s, AV_LOG_ERROR, "Only audio streams and pictures are allowed in MP3.\n"); - return AVERROR(EINVAL); - } - } - if (mp3->audio_stream_idx < 0) { - av_log(s, AV_LOG_ERROR, "No audio stream present.\n"); - return AVERROR(EINVAL); - } - mp3->pics_to_write = s->nb_streams - 1; - - ff_id3v2_start(&mp3->id3, s->pb, mp3->id3v2_version, ID3v2_DEFAULT_MAGIC); - ret = ff_id3v2_write_metadata(s, &mp3->id3); - if (ret < 0) - return ret; - - if (!mp3->pics_to_write) { - ff_id3v2_finish(&mp3->id3, s->pb); - mp3_write_xing(s); - } - - return 0; -} - -AVOutputFormat ff_mp3_muxer = { - .name = "mp3", - .long_name = NULL_IF_CONFIG_SMALL("MP3 (MPEG audio layer 3)"), - .mime_type = "audio/x-mpeg", - .extensions = "mp3", - .priv_data_size = sizeof(MP3Context), - .audio_codec = AV_CODEC_ID_MP3, - .video_codec = AV_CODEC_ID_PNG, - .write_header = mp3_write_header, - .write_packet = mp3_write_packet, - .write_trailer = mp3_write_trailer, - .query_codec = query_codec, - .flags = AVFMT_NOTIMESTAMPS, - .priv_class = &mp3_muxer_class, -}; -#endif diff --git a/ffmpeg1/libavformat/mpc.c b/ffmpeg1/libavformat/mpc.c deleted file mode 100644 index b0f6f53..0000000 --- a/ffmpeg1/libavformat/mpc.c +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Musepack demuxer - * Copyright (c) 2006 Konstantin Shishkov - * - * 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 "libavutil/channel_layout.h" -#include "libavcodec/get_bits.h" -#include "avformat.h" -#include "internal.h" -#include "apetag.h" -#include "id3v1.h" -#include "libavutil/dict.h" - -#define MPC_FRAMESIZE 1152 -#define DELAY_FRAMES 32 - -static const int mpc_rate[4] = { 44100, 48000, 37800, 32000 }; -typedef struct { - int64_t pos; - int size, skip; -}MPCFrame; - -typedef struct { - int ver; - uint32_t curframe, lastframe; - uint32_t fcount; - MPCFrame *frames; - int curbits; - int frames_noted; -} MPCContext; - -static int mpc_probe(AVProbeData *p) -{ - const uint8_t *d = p->buf; - if (d[0] == 'M' && d[1] == 'P' && d[2] == '+' && (d[3] == 0x17 || d[3] == 0x7)) - return AVPROBE_SCORE_MAX; - return 0; -} - -static int mpc_read_header(AVFormatContext *s) -{ - MPCContext *c = s->priv_data; - AVStream *st; - - if(avio_rl24(s->pb) != MKTAG('M', 'P', '+', 0)){ - av_log(s, AV_LOG_ERROR, "Not a Musepack file\n"); - return AVERROR_INVALIDDATA; - } - c->ver = avio_r8(s->pb); - if(c->ver != 0x07 && c->ver != 0x17){ - av_log(s, AV_LOG_ERROR, "Can demux Musepack SV7, got version %02X\n", c->ver); - return AVERROR_INVALIDDATA; - } - c->fcount = avio_rl32(s->pb); - if((int64_t)c->fcount * sizeof(MPCFrame) >= UINT_MAX){ - av_log(s, AV_LOG_ERROR, "Too many frames, seeking is not possible\n"); - return AVERROR_INVALIDDATA; - } - if(c->fcount){ - c->frames = av_malloc(c->fcount * sizeof(MPCFrame)); - if(!c->frames){ - av_log(s, AV_LOG_ERROR, "Cannot allocate seektable\n"); - return AVERROR(ENOMEM); - } - }else{ - av_log(s, AV_LOG_WARNING, "Container reports no frames\n"); - } - c->curframe = 0; - c->lastframe = -1; - c->curbits = 8; - c->frames_noted = 0; - - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = AV_CODEC_ID_MUSEPACK7; - st->codec->channels = 2; - st->codec->channel_layout = AV_CH_LAYOUT_STEREO; - st->codec->bits_per_coded_sample = 16; - - st->codec->extradata_size = 16; - st->codec->extradata = av_mallocz(st->codec->extradata_size+FF_INPUT_BUFFER_PADDING_SIZE); - avio_read(s->pb, st->codec->extradata, 16); - st->codec->sample_rate = mpc_rate[st->codec->extradata[2] & 3]; - avpriv_set_pts_info(st, 32, MPC_FRAMESIZE, st->codec->sample_rate); - /* scan for seekpoints */ - st->start_time = 0; - st->duration = c->fcount; - - /* try to read APE tags */ - if (s->pb->seekable) { - int64_t pos = avio_tell(s->pb); - ff_ape_parse_tag(s); - if (!av_dict_get(s->metadata, "", NULL, AV_DICT_IGNORE_SUFFIX)) - ff_id3v1_read(s); - avio_seek(s->pb, pos, SEEK_SET); - } - - return 0; -} - -static int mpc_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - MPCContext *c = s->priv_data; - int ret, size, size2, curbits, cur = c->curframe; - unsigned tmp; - int64_t pos; - - if (c->curframe >= c->fcount && c->fcount) - return AVERROR_EOF; - - if(c->curframe != c->lastframe + 1){ - avio_seek(s->pb, c->frames[c->curframe].pos, SEEK_SET); - c->curbits = c->frames[c->curframe].skip; - } - c->lastframe = c->curframe; - c->curframe++; - curbits = c->curbits; - pos = avio_tell(s->pb); - tmp = avio_rl32(s->pb); - if(curbits <= 12){ - size2 = (tmp >> (12 - curbits)) & 0xFFFFF; - }else{ - size2 = (tmp << (curbits - 12) | avio_rl32(s->pb) >> (44 - curbits)) & 0xFFFFF; - } - curbits += 20; - avio_seek(s->pb, pos, SEEK_SET); - - size = ((size2 + curbits + 31) & ~31) >> 3; - if(cur == c->frames_noted && c->fcount){ - c->frames[cur].pos = pos; - c->frames[cur].size = size; - c->frames[cur].skip = curbits - 20; - av_add_index_entry(s->streams[0], cur, cur, size, 0, AVINDEX_KEYFRAME); - c->frames_noted++; - } - c->curbits = (curbits + size2) & 0x1F; - - if ((ret = av_new_packet(pkt, size)) < 0) - return ret; - - pkt->data[0] = curbits; - pkt->data[1] = (c->curframe > c->fcount) && c->fcount; - pkt->data[2] = 0; - pkt->data[3] = 0; - - pkt->stream_index = 0; - pkt->pts = cur; - ret = avio_read(s->pb, pkt->data + 4, size); - if(c->curbits) - avio_seek(s->pb, -4, SEEK_CUR); - if(ret < size){ - av_free_packet(pkt); - return ret < 0 ? ret : AVERROR(EIO); - } - pkt->size = ret + 4; - - return 0; -} - -static int mpc_read_close(AVFormatContext *s) -{ - MPCContext *c = s->priv_data; - - av_freep(&c->frames); - return 0; -} - -/** - * Seek to the given position - * If position is unknown but is within the limits of file - * then packets are skipped unless desired position is reached - * - * Also this function makes use of the fact that timestamp == frameno - */ -static int mpc_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) -{ - AVStream *st = s->streams[stream_index]; - MPCContext *c = s->priv_data; - AVPacket pkt1, *pkt = &pkt1; - int ret; - int index = av_index_search_timestamp(st, FFMAX(timestamp - DELAY_FRAMES, 0), flags); - uint32_t lastframe; - - /* if found, seek there */ - if (index >= 0 && st->index_entries[st->nb_index_entries-1].timestamp >= timestamp - DELAY_FRAMES){ - c->curframe = st->index_entries[index].pos; - return 0; - } - /* if timestamp is out of bounds, return error */ - if(timestamp < 0 || timestamp >= c->fcount) - return -1; - timestamp -= DELAY_FRAMES; - /* seek to the furthest known position and read packets until - we reach desired position */ - lastframe = c->curframe; - if(c->frames_noted) c->curframe = c->frames_noted - 1; - while(c->curframe < timestamp){ - ret = av_read_frame(s, pkt); - if (ret < 0){ - c->curframe = lastframe; - return ret; - } - av_free_packet(pkt); - } - return 0; -} - - -AVInputFormat ff_mpc_demuxer = { - .name = "mpc", - .long_name = NULL_IF_CONFIG_SMALL("Musepack"), - .priv_data_size = sizeof(MPCContext), - .read_probe = mpc_probe, - .read_header = mpc_read_header, - .read_packet = mpc_read_packet, - .read_close = mpc_read_close, - .read_seek = mpc_read_seek, - .extensions = "mpc", -}; diff --git a/ffmpeg1/libavformat/mpc8.c b/ffmpeg1/libavformat/mpc8.c deleted file mode 100644 index 73f8057..0000000 --- a/ffmpeg1/libavformat/mpc8.c +++ /dev/null @@ -1,317 +0,0 @@ -/* - * Musepack SV8 demuxer - * Copyright (c) 2007 Konstantin Shishkov - * - * 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 "libavcodec/get_bits.h" -#include "libavcodec/unary.h" -#include "apetag.h" -#include "avformat.h" -#include "internal.h" -#include "avio_internal.h" - -/// Two-byte MPC tag -#define MKMPCTAG(a, b) (a | (b << 8)) - -#define TAG_MPCK MKTAG('M','P','C','K') - -/// Reserved MPC tags -enum MPCPacketTags{ - TAG_STREAMHDR = MKMPCTAG('S','H'), - TAG_STREAMEND = MKMPCTAG('S','E'), - - TAG_AUDIOPACKET = MKMPCTAG('A','P'), - - TAG_SEEKTBLOFF = MKMPCTAG('S','O'), - TAG_SEEKTABLE = MKMPCTAG('S','T'), - - TAG_REPLAYGAIN = MKMPCTAG('R','G'), - TAG_ENCINFO = MKMPCTAG('E','I'), -}; - -static const int mpc8_rate[8] = { 44100, 48000, 37800, 32000, -1, -1, -1, -1 }; - -typedef struct { - int ver; - int64_t header_pos; - int64_t samples; - - int64_t apetag_start; -} MPCContext; - -static inline int64_t bs_get_v(const uint8_t **bs) -{ - int64_t v = 0; - int br = 0; - int c; - - do { - c = **bs; (*bs)++; - v <<= 7; - v |= c & 0x7F; - br++; - if (br > 10) - return -1; - } while (c & 0x80); - - return v - br; -} - -static int mpc8_probe(AVProbeData *p) -{ - const uint8_t *bs = p->buf + 4; - const uint8_t *bs_end = bs + p->buf_size; - int64_t size; - - if (p->buf_size < 16) - return 0; - if (AV_RL32(p->buf) != TAG_MPCK) - return 0; - while (bs < bs_end + 3) { - int header_found = (bs[0] == 'S' && bs[1] == 'H'); - if (bs[0] < 'A' || bs[0] > 'Z' || bs[1] < 'A' || bs[1] > 'Z') - return 0; - bs += 2; - size = bs_get_v(&bs); - if (size < 2) - return 0; - if (bs + size - 2 >= bs_end) - return AVPROBE_SCORE_MAX / 4 - 1; //seems to be valid MPC but no header yet - if (header_found) { - if (size < 11 || size > 28) - return 0; - if (!AV_RL32(bs)) //zero CRC is invalid - return 0; - return AVPROBE_SCORE_MAX; - } else { - bs += size - 2; - } - } - return 0; -} - -static inline int64_t gb_get_v(GetBitContext *gb) -{ - int64_t v = 0; - int bits = 0; - while(get_bits1(gb) && bits < 64-7){ - v <<= 7; - v |= get_bits(gb, 7); - bits += 7; - } - v <<= 7; - v |= get_bits(gb, 7); - - return v; -} - -static void mpc8_get_chunk_header(AVIOContext *pb, int *tag, int64_t *size) -{ - int64_t pos; - pos = avio_tell(pb); - *tag = avio_rl16(pb); - *size = ffio_read_varlen(pb); - *size -= avio_tell(pb) - pos; -} - -static void mpc8_parse_seektable(AVFormatContext *s, int64_t off) -{ - MPCContext *c = s->priv_data; - int tag; - int64_t size, pos, ppos[2]; - uint8_t *buf; - int i, t, seekd; - GetBitContext gb; - - if (s->nb_streams<=0) { - av_log(s, AV_LOG_ERROR, "cannot parse stream table before stream header\n"); - return; - } - - avio_seek(s->pb, off, SEEK_SET); - mpc8_get_chunk_header(s->pb, &tag, &size); - if(tag != TAG_SEEKTABLE){ - av_log(s, AV_LOG_ERROR, "No seek table at given position\n"); - return; - } - if (size > INT_MAX/10 || size<=0) { - av_log(s, AV_LOG_ERROR, "Seek table size is invalid\n"); - return; - } - if(!(buf = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE))) - return; - avio_read(s->pb, buf, size); - init_get_bits(&gb, buf, size * 8); - size = gb_get_v(&gb); - if(size > UINT_MAX/4 || size > c->samples/1152){ - av_log(s, AV_LOG_ERROR, "Seek table is too big\n"); - return; - } - seekd = get_bits(&gb, 4); - for(i = 0; i < 2; i++){ - pos = gb_get_v(&gb) + c->header_pos; - ppos[1 - i] = pos; - av_add_index_entry(s->streams[0], pos, i, 0, 0, AVINDEX_KEYFRAME); - } - for(; i < size; i++){ - t = get_unary(&gb, 1, 33) << 12; - t += get_bits(&gb, 12); - if(t & 1) - t = -(t & ~1); - pos = (t >> 1) + ppos[0]*2 - ppos[1]; - av_add_index_entry(s->streams[0], pos, i << seekd, 0, 0, AVINDEX_KEYFRAME); - ppos[1] = ppos[0]; - ppos[0] = pos; - } - av_free(buf); -} - -static void mpc8_handle_chunk(AVFormatContext *s, int tag, int64_t chunk_pos, int64_t size) -{ - AVIOContext *pb = s->pb; - int64_t pos, off; - - switch(tag){ - case TAG_SEEKTBLOFF: - pos = avio_tell(pb) + size; - off = ffio_read_varlen(pb); - mpc8_parse_seektable(s, chunk_pos + off); - avio_seek(pb, pos, SEEK_SET); - break; - default: - avio_skip(pb, size); - } -} - -static int mpc8_read_header(AVFormatContext *s) -{ - MPCContext *c = s->priv_data; - AVIOContext *pb = s->pb; - AVStream *st; - int tag = 0; - int64_t size, pos; - - c->header_pos = avio_tell(pb); - if(avio_rl32(pb) != TAG_MPCK){ - av_log(s, AV_LOG_ERROR, "Not a Musepack8 file\n"); - return AVERROR_INVALIDDATA; - } - - while(!url_feof(pb)){ - pos = avio_tell(pb); - mpc8_get_chunk_header(pb, &tag, &size); - if(tag == TAG_STREAMHDR) - break; - mpc8_handle_chunk(s, tag, pos, size); - } - if(tag != TAG_STREAMHDR){ - av_log(s, AV_LOG_ERROR, "Stream header not found\n"); - return AVERROR_INVALIDDATA; - } - pos = avio_tell(pb); - avio_skip(pb, 4); //CRC - c->ver = avio_r8(pb); - if(c->ver != 8){ - av_log(s, AV_LOG_ERROR, "Unknown stream version %d\n", c->ver); - return AVERROR_PATCHWELCOME; - } - c->samples = ffio_read_varlen(pb); - ffio_read_varlen(pb); //silence samples at the beginning - - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = AV_CODEC_ID_MUSEPACK8; - st->codec->bits_per_coded_sample = 16; - - st->codec->extradata_size = 2; - st->codec->extradata = av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); - avio_read(pb, st->codec->extradata, st->codec->extradata_size); - - st->codec->channels = (st->codec->extradata[1] >> 4) + 1; - st->codec->sample_rate = mpc8_rate[st->codec->extradata[0] >> 5]; - avpriv_set_pts_info(st, 32, 1152 << (st->codec->extradata[1]&3)*2, st->codec->sample_rate); - st->start_time = 0; - st->duration = c->samples / (1152 << (st->codec->extradata[1]&3)*2); - size -= avio_tell(pb) - pos; - if (size > 0) - avio_skip(pb, size); - - if (pb->seekable) { - int64_t pos = avio_tell(s->pb); - c->apetag_start = ff_ape_parse_tag(s); - avio_seek(s->pb, pos, SEEK_SET); - } - - return 0; -} - -static int mpc8_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - MPCContext *c = s->priv_data; - int tag; - int64_t pos, size; - - while(!url_feof(s->pb)){ - pos = avio_tell(s->pb); - - /* don't return bogus packets with the ape tag data */ - if (c->apetag_start && pos >= c->apetag_start) - return AVERROR_EOF; - - mpc8_get_chunk_header(s->pb, &tag, &size); - if (size < 0) - return -1; - if(tag == TAG_AUDIOPACKET){ - if(av_get_packet(s->pb, pkt, size) < 0) - return AVERROR(ENOMEM); - pkt->stream_index = 0; - pkt->duration = 1; - return 0; - } - if(tag == TAG_STREAMEND) - return AVERROR(EIO); - mpc8_handle_chunk(s, tag, pos, size); - } - return AVERROR_EOF; -} - -static int mpc8_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) -{ - AVStream *st = s->streams[stream_index]; - int index = av_index_search_timestamp(st, timestamp, flags); - - if(index < 0) return -1; - if (avio_seek(s->pb, st->index_entries[index].pos, SEEK_SET) < 0) - return -1; - ff_update_cur_dts(s, st, st->index_entries[index].timestamp); - return 0; -} - - -AVInputFormat ff_mpc8_demuxer = { - .name = "mpc8", - .long_name = NULL_IF_CONFIG_SMALL("Musepack SV8"), - .priv_data_size = sizeof(MPCContext), - .read_probe = mpc8_probe, - .read_header = mpc8_read_header, - .read_packet = mpc8_read_packet, - .read_seek = mpc8_read_seek, -}; diff --git a/ffmpeg1/libavformat/mpeg.c b/ffmpeg1/libavformat/mpeg.c deleted file mode 100644 index f36f0db..0000000 --- a/ffmpeg1/libavformat/mpeg.c +++ /dev/null @@ -1,912 +0,0 @@ -/* - * MPEG1/2 demuxer - * Copyright (c) 2000, 2001, 2002 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 "internal.h" -#include "mpeg.h" - -#if CONFIG_VOBSUB_DEMUXER -# include "subtitles.h" -# include "libavutil/bprint.h" -#endif - -#undef NDEBUG -#include -#include "libavutil/avassert.h" - -/*********************************************/ -/* demux code */ - -#define MAX_SYNC_SIZE 100000 - -static int check_pes(const uint8_t *p, const uint8_t *end){ - int pes1; - int pes2= (p[3] & 0xC0) == 0x80 - && (p[4] & 0xC0) != 0x40 - &&((p[4] & 0xC0) == 0x00 || (p[4]&0xC0)>>2 == (p[6]&0xF0)); - - for(p+=3; pbuf_size; i++){ - code = (code<<8) + p->buf[i]; - if ((code & 0xffffff00) == 0x100) { - int len= p->buf[i+1] << 8 | p->buf[i+2]; - int pes= check_pes(p->buf+i, p->buf+p->buf_size); - int pack = check_pack_header(p->buf+i); - - if(code == SYSTEM_HEADER_START_CODE) sys++; - else if(code == PACK_START_CODE && pack) pspack++; - else if((code & 0xf0) == VIDEO_ID && pes) vid++; - // skip pes payload to avoid start code emulation for private - // and audio streams - else if((code & 0xe0) == AUDIO_ID && pes) {audio++; i+=len;} - else if(code == PRIVATE_STREAM_1 && pes) {priv1++; i+=len;} - else if(code == 0x1fd && pes) vid++; //VC1 - - else if((code & 0xf0) == VIDEO_ID && !pes) invalid++; - else if((code & 0xe0) == AUDIO_ID && !pes) invalid++; - else if(code == PRIVATE_STREAM_1 && !pes) invalid++; - } - } - - if(vid+audio > invalid+1) /* invalid VDR files nd short PES streams */ - score= AVPROBE_SCORE_MAX/4; - - if(sys>invalid && sys*9 <= pspack*10) - return (audio > 12 || vid > 3 || pspack > 2) ? AVPROBE_SCORE_MAX/2+2 : AVPROBE_SCORE_MAX/4; // +1 for .mpg - if(pspack > invalid && (priv1+vid+audio)*10 >= pspack*9) - return pspack > 2 ? AVPROBE_SCORE_MAX/2+2 : AVPROBE_SCORE_MAX/4; // +1 for .mpg - if((!!vid ^ !!audio) && (audio > 4 || vid > 1) && !sys && !pspack && p->buf_size>2048 && vid + audio > invalid) /* PES stream */ - return (audio > 12 || vid > 3 + 2*invalid) ? AVPROBE_SCORE_MAX/2+2 : AVPROBE_SCORE_MAX/4; - - //02-Penguin.flac has sys:0 priv1:0 pspack:0 vid:0 audio:1 - //mp3_misidentified_2.mp3 has sys:0 priv1:0 pspack:0 vid:0 audio:6 - //Have\ Yourself\ a\ Merry\ Little\ Christmas.mp3 0 0 0 5 0 1 len:21618 - return score; -} - - -typedef struct MpegDemuxContext { - int32_t header_state; - unsigned char psm_es_type[256]; - int sofdec; - int dvd; -#if CONFIG_VOBSUB_DEMUXER - AVFormatContext *sub_ctx; - FFDemuxSubtitlesQueue q; -#endif -} MpegDemuxContext; - -static int mpegps_read_header(AVFormatContext *s) -{ - MpegDemuxContext *m = s->priv_data; - const char *sofdec = "Sofdec"; - int v, i = 0; - int64_t last_pos = avio_tell(s->pb); - - m->header_state = 0xff; - s->ctx_flags |= AVFMTCTX_NOHEADER; - - m->sofdec = -1; - do { - v = avio_r8(s->pb); - m->sofdec++; - } while (v == sofdec[i] && i++ < 6); - - m->sofdec = (m->sofdec == 6) ? 1 : 0; - - if (!m->sofdec) - avio_seek(s->pb, last_pos, SEEK_SET); - - /* no need to do more */ - return 0; -} - -static int64_t get_pts(AVIOContext *pb, int c) -{ - uint8_t buf[5]; - - buf[0] = c<0 ? avio_r8(pb) : c; - avio_read(pb, buf+1, 4); - - return ff_parse_pes_pts(buf); -} - -static int find_next_start_code(AVIOContext *pb, int *size_ptr, - int32_t *header_state) -{ - unsigned int state, v; - int val, n; - - state = *header_state; - n = *size_ptr; - while (n > 0) { - if (url_feof(pb)) - break; - v = avio_r8(pb); - n--; - if (state == 0x000001) { - state = ((state << 8) | v) & 0xffffff; - val = state; - goto found; - } - state = ((state << 8) | v) & 0xffffff; - } - val = -1; - found: - *header_state = state; - *size_ptr = n; - return val; -} - -/** - * Extract stream types from a program stream map - * According to ISO/IEC 13818-1 ('MPEG-2 Systems') table 2-35 - * - * @return number of bytes occupied by PSM in the bitstream - */ -static long mpegps_psm_parse(MpegDemuxContext *m, AVIOContext *pb) -{ - int psm_length, ps_info_length, es_map_length; - - psm_length = avio_rb16(pb); - avio_r8(pb); - avio_r8(pb); - ps_info_length = avio_rb16(pb); - - /* skip program_stream_info */ - avio_skip(pb, ps_info_length); - es_map_length = avio_rb16(pb); - - /* at least one es available? */ - while (es_map_length >= 4){ - unsigned char type = avio_r8(pb); - unsigned char es_id = avio_r8(pb); - uint16_t es_info_length = avio_rb16(pb); - /* remember mapping from stream id to stream type */ - m->psm_es_type[es_id] = type; - /* skip program_stream_info */ - avio_skip(pb, es_info_length); - es_map_length -= 4 + es_info_length; - } - avio_rb32(pb); /* crc32 */ - return 2 + psm_length; -} - -/* read the next PES header. Return its position in ppos - (if not NULL), and its start code, pts and dts. - */ -static int mpegps_read_pes_header(AVFormatContext *s, - int64_t *ppos, int *pstart_code, - int64_t *ppts, int64_t *pdts) -{ - MpegDemuxContext *m = s->priv_data; - int len, size, startcode, c, flags, header_len; - int pes_ext, ext2_len, id_ext, skip; - int64_t pts, dts; - int64_t last_sync= avio_tell(s->pb); - - error_redo: - avio_seek(s->pb, last_sync, SEEK_SET); - redo: - /* next start code (should be immediately after) */ - m->header_state = 0xff; - size = MAX_SYNC_SIZE; - startcode = find_next_start_code(s->pb, &size, &m->header_state); - last_sync = avio_tell(s->pb); - if (startcode < 0){ - if(url_feof(s->pb)) - return AVERROR_EOF; - //FIXME we should remember header_state - return AVERROR(EAGAIN); - } - - if (startcode == PACK_START_CODE) - goto redo; - if (startcode == SYSTEM_HEADER_START_CODE) - goto redo; - if (startcode == PADDING_STREAM) { - avio_skip(s->pb, avio_rb16(s->pb)); - goto redo; - } - if (startcode == PRIVATE_STREAM_2) { - if (!m->sofdec) { - /* Need to detect whether this from a DVD or a 'Sofdec' stream */ - int len = avio_rb16(s->pb); - int bytesread = 0; - uint8_t *ps2buf = av_malloc(len); - - if (ps2buf) { - bytesread = avio_read(s->pb, ps2buf, len); - - if (bytesread != len) { - avio_skip(s->pb, len - bytesread); - } else { - uint8_t *p = 0; - if (len >= 6) - p = memchr(ps2buf, 'S', len - 5); - - if (p) - m->sofdec = !memcmp(p+1, "ofdec", 5); - - m->sofdec -= !m->sofdec; - - if (m->sofdec < 0) { - if (len == 980 && ps2buf[0] == 0) { - /* PCI structure? */ - uint32_t startpts = AV_RB32(ps2buf + 0x0d); - uint32_t endpts = AV_RB32(ps2buf + 0x11); - uint8_t hours = ((ps2buf[0x19] >> 4) * 10) + (ps2buf[0x19] & 0x0f); - uint8_t mins = ((ps2buf[0x1a] >> 4) * 10) + (ps2buf[0x1a] & 0x0f); - uint8_t secs = ((ps2buf[0x1b] >> 4) * 10) + (ps2buf[0x1b] & 0x0f); - - m->dvd = (hours <= 23 && - mins <= 59 && - secs <= 59 && - (ps2buf[0x19] & 0x0f) < 10 && - (ps2buf[0x1a] & 0x0f) < 10 && - (ps2buf[0x1b] & 0x0f) < 10 && - endpts >= startpts); - } else if (len == 1018 && ps2buf[0] == 1) { - /* DSI structure? */ - uint8_t hours = ((ps2buf[0x1d] >> 4) * 10) + (ps2buf[0x1d] & 0x0f); - uint8_t mins = ((ps2buf[0x1e] >> 4) * 10) + (ps2buf[0x1e] & 0x0f); - uint8_t secs = ((ps2buf[0x1f] >> 4) * 10) + (ps2buf[0x1f] & 0x0f); - - m->dvd = (hours <= 23 && - mins <= 59 && - secs <= 59 && - (ps2buf[0x1d] & 0x0f) < 10 && - (ps2buf[0x1e] & 0x0f) < 10 && - (ps2buf[0x1f] & 0x0f) < 10); - } - } - } - - av_free(ps2buf); - - /* If this isn't a DVD packet or no memory - * could be allocated, just ignore it. - * If we did, move back to the start of the - * packet (plus 'length' field) */ - if (!m->dvd || avio_skip(s->pb, -(len + 2)) < 0) { - /* Skip back failed. - * This packet will be lost but that can't be helped - * if we can't skip back - */ - goto redo; - } - } else { - /* No memory */ - avio_skip(s->pb, len); - goto redo; - } - } else if (!m->dvd) { - int len = avio_rb16(s->pb); - avio_skip(s->pb, len); - goto redo; - } - } - if (startcode == PROGRAM_STREAM_MAP) { - mpegps_psm_parse(m, s->pb); - goto redo; - } - - /* find matching stream */ - if (!((startcode >= 0x1c0 && startcode <= 0x1df) || - (startcode >= 0x1e0 && startcode <= 0x1ef) || - (startcode == 0x1bd) || - (startcode == PRIVATE_STREAM_2) || - (startcode == 0x1fd))) - goto redo; - if (ppos) { - *ppos = avio_tell(s->pb) - 4; - } - len = avio_rb16(s->pb); - pts = - dts = AV_NOPTS_VALUE; - if (startcode != PRIVATE_STREAM_2) - { - /* stuffing */ - for(;;) { - if (len < 1) - goto error_redo; - c = avio_r8(s->pb); - len--; - /* XXX: for mpeg1, should test only bit 7 */ - if (c != 0xff) - break; - } - if ((c & 0xc0) == 0x40) { - /* buffer scale & size */ - avio_r8(s->pb); - c = avio_r8(s->pb); - len -= 2; - } - if ((c & 0xe0) == 0x20) { - dts = pts = get_pts(s->pb, c); - len -= 4; - if (c & 0x10){ - dts = get_pts(s->pb, -1); - len -= 5; - } - } else if ((c & 0xc0) == 0x80) { - /* mpeg 2 PES */ - flags = avio_r8(s->pb); - header_len = avio_r8(s->pb); - len -= 2; - if (header_len > len) - goto error_redo; - len -= header_len; - if (flags & 0x80) { - dts = pts = get_pts(s->pb, -1); - header_len -= 5; - if (flags & 0x40) { - dts = get_pts(s->pb, -1); - header_len -= 5; - } - } - if (flags & 0x3f && header_len == 0){ - flags &= 0xC0; - av_log(s, AV_LOG_WARNING, "Further flags set but no bytes left\n"); - } - if (flags & 0x01) { /* PES extension */ - pes_ext = avio_r8(s->pb); - header_len--; - /* Skip PES private data, program packet sequence counter and P-STD buffer */ - skip = (pes_ext >> 4) & 0xb; - skip += skip & 0x9; - if (pes_ext & 0x40 || skip > header_len){ - av_log(s, AV_LOG_WARNING, "pes_ext %X is invalid\n", pes_ext); - pes_ext=skip=0; - } - avio_skip(s->pb, skip); - header_len -= skip; - - if (pes_ext & 0x01) { /* PES extension 2 */ - ext2_len = avio_r8(s->pb); - header_len--; - if ((ext2_len & 0x7f) > 0) { - id_ext = avio_r8(s->pb); - if ((id_ext & 0x80) == 0) - startcode = ((startcode & 0xff) << 8) | id_ext; - header_len--; - } - } - } - if(header_len < 0) - goto error_redo; - avio_skip(s->pb, header_len); - } - else if( c!= 0xf ) - goto redo; - } - - if (startcode == PRIVATE_STREAM_1) { - startcode = avio_r8(s->pb); - len--; - } - if(len<0) - goto error_redo; - if(dts != AV_NOPTS_VALUE && ppos){ - int i; - for(i=0; inb_streams; i++){ - if(startcode == s->streams[i]->id && - s->pb->seekable /* index useless on streams anyway */) { - ff_reduce_index(s, i); - av_add_index_entry(s->streams[i], *ppos, dts, 0, 0, AVINDEX_KEYFRAME /* FIXME keyframe? */); - } - } - } - - *pstart_code = startcode; - *ppts = pts; - *pdts = dts; - return len; -} - -static int mpegps_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - MpegDemuxContext *m = s->priv_data; - AVStream *st; - int len, startcode, i, es_type, ret; - int lpcm_header_len = -1; //Init to supress warning - int request_probe= 0; - enum AVCodecID codec_id = AV_CODEC_ID_NONE; - enum AVMediaType type; - int64_t pts, dts, dummy_pos; //dummy_pos is needed for the index building to work - - redo: - len = mpegps_read_pes_header(s, &dummy_pos, &startcode, &pts, &dts); - if (len < 0) - return len; - - if (startcode >= 0x80 && startcode <= 0xcf) { - if(len < 4) - goto skip; - - /* audio: skip header */ - avio_r8(s->pb); - lpcm_header_len = avio_rb16(s->pb); - len -= 3; - if (startcode >= 0xb0 && startcode <= 0xbf) { - /* MLP/TrueHD audio has a 4-byte header */ - avio_r8(s->pb); - len--; - } - } - - /* now find stream */ - for(i=0;inb_streams;i++) { - st = s->streams[i]; - if (st->id == startcode) - goto found; - } - - es_type = m->psm_es_type[startcode & 0xff]; - if(es_type == STREAM_TYPE_VIDEO_MPEG1){ - codec_id = AV_CODEC_ID_MPEG2VIDEO; - type = AVMEDIA_TYPE_VIDEO; - } else if(es_type == STREAM_TYPE_VIDEO_MPEG2){ - codec_id = AV_CODEC_ID_MPEG2VIDEO; - type = AVMEDIA_TYPE_VIDEO; - } else if(es_type == STREAM_TYPE_AUDIO_MPEG1 || - es_type == STREAM_TYPE_AUDIO_MPEG2){ - codec_id = AV_CODEC_ID_MP3; - type = AVMEDIA_TYPE_AUDIO; - } else if(es_type == STREAM_TYPE_AUDIO_AAC){ - codec_id = AV_CODEC_ID_AAC; - type = AVMEDIA_TYPE_AUDIO; - } else if(es_type == STREAM_TYPE_VIDEO_MPEG4){ - codec_id = AV_CODEC_ID_MPEG4; - type = AVMEDIA_TYPE_VIDEO; - } else if(es_type == STREAM_TYPE_VIDEO_H264){ - codec_id = AV_CODEC_ID_H264; - type = AVMEDIA_TYPE_VIDEO; - } else if(es_type == STREAM_TYPE_AUDIO_AC3){ - codec_id = AV_CODEC_ID_AC3; - type = AVMEDIA_TYPE_AUDIO; - } else if (startcode >= 0x1e0 && startcode <= 0x1ef) { - static const unsigned char avs_seqh[4] = { 0, 0, 1, 0xb0 }; - unsigned char buf[8]; - avio_read(s->pb, buf, 8); - avio_seek(s->pb, -8, SEEK_CUR); - if(!memcmp(buf, avs_seqh, 4) && (buf[6] != 0 || buf[7] != 1)) - codec_id = AV_CODEC_ID_CAVS; - else - request_probe= 1; - type = AVMEDIA_TYPE_VIDEO; - } else if (startcode == PRIVATE_STREAM_2) { - type = AVMEDIA_TYPE_DATA; - codec_id = AV_CODEC_ID_DVD_NAV; - } else if (startcode >= 0x1c0 && startcode <= 0x1df) { - type = AVMEDIA_TYPE_AUDIO; - codec_id = m->sofdec > 0 ? AV_CODEC_ID_ADPCM_ADX : AV_CODEC_ID_MP2; - } else if (startcode >= 0x80 && startcode <= 0x87) { - type = AVMEDIA_TYPE_AUDIO; - codec_id = AV_CODEC_ID_AC3; - } else if ( ( startcode >= 0x88 && startcode <= 0x8f) - ||( startcode >= 0x98 && startcode <= 0x9f)) { - /* 0x90 - 0x97 is reserved for SDDS in DVD specs */ - type = AVMEDIA_TYPE_AUDIO; - codec_id = AV_CODEC_ID_DTS; - } else if (startcode >= 0xa0 && startcode <= 0xaf) { - type = AVMEDIA_TYPE_AUDIO; - if(lpcm_header_len == 6) { - codec_id = AV_CODEC_ID_MLP; - } else { - /* 16 bit form will be handled as AV_CODEC_ID_PCM_S16BE */ - codec_id = AV_CODEC_ID_PCM_DVD; - } - } else if (startcode >= 0xb0 && startcode <= 0xbf) { - type = AVMEDIA_TYPE_AUDIO; - codec_id = AV_CODEC_ID_TRUEHD; - } else if (startcode >= 0xc0 && startcode <= 0xcf) { - /* Used for both AC-3 and E-AC-3 in EVOB files */ - type = AVMEDIA_TYPE_AUDIO; - codec_id = AV_CODEC_ID_AC3; - } else if (startcode >= 0x20 && startcode <= 0x3f) { - type = AVMEDIA_TYPE_SUBTITLE; - codec_id = AV_CODEC_ID_DVD_SUBTITLE; - } else if (startcode >= 0xfd55 && startcode <= 0xfd5f) { - type = AVMEDIA_TYPE_VIDEO; - codec_id = AV_CODEC_ID_VC1; - } else { - skip: - /* skip packet */ - avio_skip(s->pb, len); - goto redo; - } - /* no stream found: add a new stream */ - st = avformat_new_stream(s, NULL); - if (!st) - goto skip; - st->id = startcode; - st->codec->codec_type = type; - st->codec->codec_id = codec_id; - st->request_probe = request_probe; - if (codec_id != AV_CODEC_ID_PCM_S16BE) - st->need_parsing = AVSTREAM_PARSE_FULL; - found: - if(st->discard >= AVDISCARD_ALL) - goto skip; - if (startcode >= 0xa0 && startcode <= 0xaf) { - if (lpcm_header_len == 6 && st->codec->codec_id == AV_CODEC_ID_MLP) { - if (len < 6) - goto skip; - avio_skip(s->pb, 6); - len -=6; - } else { - int b1, freq; - - /* for LPCM, we just skip the header and consider it is raw - audio data */ - if (len <= 3) - goto skip; - avio_r8(s->pb); /* emphasis (1), muse(1), reserved(1), frame number(5) */ - b1 = avio_r8(s->pb); /* quant (2), freq(2), reserved(1), channels(3) */ - avio_r8(s->pb); /* dynamic range control (0x80 = off) */ - len -= 3; - freq = (b1 >> 4) & 3; - st->codec->sample_rate = lpcm_freq_tab[freq]; - st->codec->channels = 1 + (b1 & 7); - st->codec->bits_per_coded_sample = 16 + ((b1 >> 6) & 3) * 4; - st->codec->bit_rate = st->codec->channels * - st->codec->sample_rate * - st->codec->bits_per_coded_sample; - if (st->codec->bits_per_coded_sample == 16) - st->codec->codec_id = AV_CODEC_ID_PCM_S16BE; - else if (st->codec->bits_per_coded_sample == 28) - return AVERROR(EINVAL); - } - } - ret = av_get_packet(s->pb, pkt, len); - pkt->pts = pts; - pkt->dts = dts; - pkt->pos = dummy_pos; - pkt->stream_index = st->index; - av_dlog(s, "%d: pts=%0.3f dts=%0.3f size=%d\n", - pkt->stream_index, pkt->pts / 90000.0, pkt->dts / 90000.0, - pkt->size); - - return (ret < 0) ? ret : 0; -} - -static int64_t mpegps_read_dts(AVFormatContext *s, int stream_index, - int64_t *ppos, int64_t pos_limit) -{ - int len, startcode; - int64_t pos, pts, dts; - - pos = *ppos; - if (avio_seek(s->pb, pos, SEEK_SET) < 0) - return AV_NOPTS_VALUE; - - for(;;) { - len = mpegps_read_pes_header(s, &pos, &startcode, &pts, &dts); - if (len < 0) { - av_dlog(s, "none (ret=%d)\n", len); - return AV_NOPTS_VALUE; - } - if (startcode == s->streams[stream_index]->id && - dts != AV_NOPTS_VALUE) { - break; - } - avio_skip(s->pb, len); - } - av_dlog(s, "pos=0x%"PRIx64" dts=0x%"PRIx64" %0.3f\n", - pos, dts, dts / 90000.0); - *ppos = pos; - return dts; -} - -AVInputFormat ff_mpegps_demuxer = { - .name = "mpeg", - .long_name = NULL_IF_CONFIG_SMALL("MPEG-PS (MPEG-2 Program Stream)"), - .priv_data_size = sizeof(MpegDemuxContext), - .read_probe = mpegps_probe, - .read_header = mpegps_read_header, - .read_packet = mpegps_read_packet, - .read_timestamp = mpegps_read_dts, - .flags = AVFMT_SHOW_IDS | AVFMT_TS_DISCONT, -}; - -#if CONFIG_VOBSUB_DEMUXER - -#define REF_STRING "# VobSub index file," - -static int vobsub_probe(AVProbeData *p) -{ - if (!strncmp(p->buf, REF_STRING, sizeof(REF_STRING) - 1)) - return AVPROBE_SCORE_MAX; - return 0; -} - -static int vobsub_read_header(AVFormatContext *s) -{ - int i, ret = 0, header_parsed = 0, langidx = 0; - MpegDemuxContext *vobsub = s->priv_data; - char *sub_name = NULL; - size_t fname_len; - char *ext, *header_str; - AVBPrint header; - int64_t delay = 0; - AVStream *st = NULL; - - sub_name = av_strdup(s->filename); - fname_len = strlen(sub_name); - ext = sub_name - 3 + fname_len; - if (fname_len < 4 || *(ext - 1) != '.') { - av_log(s, AV_LOG_ERROR, "The input index filename is too short " - "to guess the associated .SUB file\n"); - ret = AVERROR_INVALIDDATA; - goto end; - } - memcpy(ext, !strncmp(ext, "IDX", 3) ? "SUB" : "sub", 3); - av_log(s, AV_LOG_VERBOSE, "IDX/SUB: %s -> %s\n", s->filename, sub_name); - ret = avformat_open_input(&vobsub->sub_ctx, sub_name, &ff_mpegps_demuxer, NULL); - if (ret < 0) { - av_log(s, AV_LOG_ERROR, "Unable to open %s as MPEG subtitles\n", sub_name); - goto end; - } - - av_bprint_init(&header, 0, AV_BPRINT_SIZE_UNLIMITED); - while (!url_feof(s->pb)) { - char line[2048]; - int len = ff_get_line(s->pb, line, sizeof(line)); - - if (!len) - break; - - line[strcspn(line, "\r\n")] = 0; - - if (!strncmp(line, "id:", 3)) { - int n, stream_id = 0; - char id[64] = {0}; - - n = sscanf(line, "id: %63[^,], index: %u", id, &stream_id); - if (n != 2) { - av_log(s, AV_LOG_WARNING, "Unable to parse index line '%s', " - "assuming 'id: und, index: 0'\n", line); - strcpy(id, "und"); - stream_id = 0; - } - - st = avformat_new_stream(s, NULL); - if (!st) { - ret = AVERROR(ENOMEM); - goto end; - } - st->id = stream_id; - st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE; - st->codec->codec_id = AV_CODEC_ID_DVD_SUBTITLE; - av_dict_set(&st->metadata, "language", id, 0); - av_log(s, AV_LOG_DEBUG, "IDX stream[%d] id=%s\n", stream_id, id); - header_parsed = 1; - - } else if (st && !strncmp(line, "timestamp:", 10)) { - AVPacket *sub; - int hh, mm, ss, ms; - int64_t pos, timestamp; - const char *p = line + 10; - - if (sscanf(p, "%02d:%02d:%02d:%03d, filepos: %"PRIx64, - &hh, &mm, &ss, &ms, &pos) != 5) { - av_log(s, AV_LOG_ERROR, "Unable to parse timestamp line '%s', " - "abort parsing\n", line); - break; - } - timestamp = (hh*3600LL + mm*60LL + ss) * 1000LL + ms + delay; - timestamp = av_rescale_q(timestamp, (AVRational){1,1000}, st->time_base); - - sub = ff_subtitles_queue_insert(&vobsub->q, "", 0, 0); - if (!sub) { - ret = AVERROR(ENOMEM); - goto end; - } - sub->pos = pos; - sub->pts = timestamp; - sub->stream_index = s->nb_streams - 1; - - } else if (st && !strncmp(line, "alt:", 4)) { - const char *p = line + 4; - - while (*p == ' ') - p++; - av_dict_set(&st->metadata, "title", p, 0); - av_log(s, AV_LOG_DEBUG, "IDX stream[%d] name=%s\n", st->id, p); - header_parsed = 1; - - } else if (!strncmp(line, "delay:", 6)) { - int sign = 1, hh = 0, mm = 0, ss = 0, ms = 0; - const char *p = line + 6; - - while (*p == ' ') - p++; - if (*p == '-' || *p == '+') { - sign = *p == '-' ? -1 : 1; - p++; - } - sscanf(p, "%d:%d:%d:%d", &hh, &mm, &ss, &ms); - delay = ((hh*3600LL + mm*60LL + ss) * 1000LL + ms) * sign; - - } else if (!strncmp(line, "langidx:", 8)) { - const char *p = line + 8; - - if (sscanf(p, "%d", &langidx) != 1) - av_log(s, AV_LOG_ERROR, "Invalid langidx specified\n"); - - } else if (!header_parsed) { - if (line[0] && line[0] != '#') - av_bprintf(&header, "%s\n", line); - } - } - - if (langidx < s->nb_streams) - s->streams[langidx]->disposition |= AV_DISPOSITION_DEFAULT; - - ff_subtitles_queue_finalize(&vobsub->q); - - if (!av_bprint_is_complete(&header)) { - av_bprint_finalize(&header, NULL); - ret = AVERROR(ENOMEM); - goto end; - } - av_bprint_finalize(&header, &header_str); - for (i = 0; i < s->nb_streams; i++) { - AVStream *sub_st = s->streams[i]; - sub_st->codec->extradata = av_strdup(header_str); - sub_st->codec->extradata_size = header.len; - } - av_free(header_str); - -end: - av_free(sub_name); - return ret; -} - -#define FAIL(r) do { ret = r; goto fail; } while (0) - -static int vobsub_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - MpegDemuxContext *vobsub = s->priv_data; - FFDemuxSubtitlesQueue *q = &vobsub->q; - AVIOContext *pb = vobsub->sub_ctx->pb; - int ret, psize, len16 = -1; - AVPacket idx_pkt; - - ret = ff_subtitles_queue_read_packet(q, &idx_pkt); - if (ret < 0) - return ret; - - /* compute maximum packet size using the next packet position. This is - * useful when the len in the header is non-sense */ - if (q->current_sub_idx < q->nb_subs) { - psize = q->subs[q->current_sub_idx].pos - idx_pkt.pos; - } else { - int64_t fsize = avio_size(pb); - psize = fsize < 0 ? 0xffff : fsize - idx_pkt.pos; - } - - avio_seek(pb, idx_pkt.pos, SEEK_SET); - - av_init_packet(pkt); - pkt->size = 0; - pkt->data = NULL; - - do { - int n, to_read, startcode; - int64_t pts, dts; - - ret = mpegps_read_pes_header(vobsub->sub_ctx, NULL, &startcode, &pts, &dts); - if (ret < 0) - FAIL(ret); - to_read = ret & 0xffff; - - /* this prevents reads above the current packet */ - if (pkt->size + to_read > psize) - break; - - /* if the len is computed, we check for overread */ - if (len16 != -1 && pkt->size + to_read > len16) - break; - - /* the current chunk doesn't match the stream index (unlikely) */ - if ((startcode & 0x1f) != idx_pkt.stream_index) - break; - - ret = av_grow_packet(pkt, to_read); - if (ret < 0) - FAIL(ret); - - n = avio_read(pb, pkt->data + (pkt->size - to_read), to_read); - if (n < to_read) - pkt->size -= to_read - n; - - /* first chunk contains the total len of the packet to raise */ - if (len16 == -1 && n > 2) - len16 = AV_RB16(pkt->data); - } while (len16 != -1 && pkt->size != len16); - - pkt->pts = pkt->dts = idx_pkt.pts; - pkt->pos = idx_pkt.pos; - pkt->stream_index = idx_pkt.stream_index; - - av_free_packet(&idx_pkt); - return 0; - -fail: - av_free_packet(&idx_pkt); - return ret; -} - -static int vobsub_read_seek(AVFormatContext *s, int stream_index, - int64_t min_ts, int64_t ts, int64_t max_ts, int flags) -{ - MpegDemuxContext *vobsub = s->priv_data; - return ff_subtitles_queue_seek(&vobsub->q, s, stream_index, - min_ts, ts, max_ts, flags); -} - -static int vobsub_read_close(AVFormatContext *s) -{ - MpegDemuxContext *vobsub = s->priv_data; - ff_subtitles_queue_clean(&vobsub->q); - if (vobsub->sub_ctx) - avformat_close_input(&vobsub->sub_ctx); - return 0; -} - -AVInputFormat ff_vobsub_demuxer = { - .name = "vobsub", - .long_name = NULL_IF_CONFIG_SMALL("VobSub subtitle format"), - .priv_data_size = sizeof(MpegDemuxContext), - .read_probe = vobsub_probe, - .read_header = vobsub_read_header, - .read_packet = vobsub_read_packet, - .read_seek2 = vobsub_read_seek, - .read_close = vobsub_read_close, - .flags = AVFMT_SHOW_IDS, - .extensions = "idx", -}; -#endif diff --git a/ffmpeg1/libavformat/mpeg.h b/ffmpeg1/libavformat/mpeg.h deleted file mode 100644 index a1e8980..0000000 --- a/ffmpeg1/libavformat/mpeg.h +++ /dev/null @@ -1,73 +0,0 @@ -/* - * MPEG1/2 muxer and demuxer common defines - * Copyright (c) 2000, 2001, 2002 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 AVFORMAT_MPEG_H -#define AVFORMAT_MPEG_H - -#include -#include "libavutil/intreadwrite.h" - -#define PACK_START_CODE ((unsigned int)0x000001ba) -#define SYSTEM_HEADER_START_CODE ((unsigned int)0x000001bb) -#define SEQUENCE_END_CODE ((unsigned int)0x000001b7) -#define PACKET_START_CODE_MASK ((unsigned int)0xffffff00) -#define PACKET_START_CODE_PREFIX ((unsigned int)0x00000100) -#define ISO_11172_END_CODE ((unsigned int)0x000001b9) - -/* mpeg2 */ -#define PROGRAM_STREAM_MAP 0x1bc -#define PRIVATE_STREAM_1 0x1bd -#define PADDING_STREAM 0x1be -#define PRIVATE_STREAM_2 0x1bf - -#define AUDIO_ID 0xc0 -#define VIDEO_ID 0xe0 -#define AC3_ID 0x80 -#define DTS_ID 0x8a -#define LPCM_ID 0xa0 -#define SUB_ID 0x20 - -#define STREAM_TYPE_VIDEO_MPEG1 0x01 -#define STREAM_TYPE_VIDEO_MPEG2 0x02 -#define STREAM_TYPE_AUDIO_MPEG1 0x03 -#define STREAM_TYPE_AUDIO_MPEG2 0x04 -#define STREAM_TYPE_PRIVATE_SECTION 0x05 -#define STREAM_TYPE_PRIVATE_DATA 0x06 -#define STREAM_TYPE_AUDIO_AAC 0x0f -#define STREAM_TYPE_VIDEO_MPEG4 0x10 -#define STREAM_TYPE_VIDEO_H264 0x1b -#define STREAM_TYPE_VIDEO_CAVS 0x42 - -#define STREAM_TYPE_AUDIO_AC3 0x81 -#define STREAM_TYPE_AUDIO_DTS 0x8a - -static const int lpcm_freq_tab[4] = { 48000, 96000, 44100, 32000 }; - -/** - * Parse MPEG-PES five-byte timestamp - */ -static inline int64_t ff_parse_pes_pts(const uint8_t *buf) { - return (int64_t)(*buf & 0x0e) << 29 | - (AV_RB16(buf+1) >> 1) << 15 | - AV_RB16(buf+3) >> 1; -} - -#endif /* AVFORMAT_MPEG_H */ diff --git a/ffmpeg1/libavformat/mpegenc.c b/ffmpeg1/libavformat/mpegenc.c deleted file mode 100644 index b467bb5..0000000 --- a/ffmpeg1/libavformat/mpegenc.c +++ /dev/null @@ -1,1242 +0,0 @@ -/* - * MPEG1/2 muxer - * Copyright (c) 2000, 2001, 2002 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 "libavutil/fifo.h" -#include "libavutil/log.h" -#include "libavutil/mathematics.h" -#include "libavutil/opt.h" -#include "libavcodec/put_bits.h" -#include "avformat.h" -#include "internal.h" -#include "mpeg.h" - -#define MAX_PAYLOAD_SIZE 4096 - -#undef NDEBUG -#include - -typedef struct PacketDesc { - int64_t pts; - int64_t dts; - int size; - int unwritten_size; - int flags; - struct PacketDesc *next; -} PacketDesc; - -typedef struct { - AVFifoBuffer *fifo; - uint8_t id; - int max_buffer_size; /* in bytes */ - int buffer_index; - PacketDesc *predecode_packet; - PacketDesc *premux_packet; - PacketDesc **next_packet; - int packet_number; - uint8_t lpcm_header[3]; - int lpcm_align; - int bytes_to_iframe; - int align_iframe; - int64_t vobu_start_pts; -} StreamInfo; - -typedef struct { - const AVClass *class; - int packet_size; /* required packet size */ - int packet_number; - int pack_header_freq; /* frequency (in packets^-1) at which we send pack headers */ - int system_header_freq; - int system_header_size; - int user_mux_rate; /* bitrate in units of bits/s */ - int mux_rate; /* bitrate in units of 50 bytes/s */ - /* stream info */ - int audio_bound; - int video_bound; - int is_mpeg2; - int is_vcd; - int is_svcd; - int is_dvd; - int64_t last_scr; /* current system clock */ - - double vcd_padding_bitrate; //FIXME floats - int64_t vcd_padding_bytes_written; - - int preload; -} MpegMuxContext; - -extern AVOutputFormat ff_mpeg1vcd_muxer; -extern AVOutputFormat ff_mpeg2dvd_muxer; -extern AVOutputFormat ff_mpeg2svcd_muxer; -extern AVOutputFormat ff_mpeg2vob_muxer; - -static int put_pack_header(AVFormatContext *ctx, - uint8_t *buf, int64_t timestamp) -{ - MpegMuxContext *s = ctx->priv_data; - PutBitContext pb; - - init_put_bits(&pb, buf, 128); - - put_bits32(&pb, PACK_START_CODE); - if (s->is_mpeg2) { - put_bits(&pb, 2, 0x1); - } else { - put_bits(&pb, 4, 0x2); - } - put_bits(&pb, 3, (uint32_t)((timestamp >> 30) & 0x07)); - put_bits(&pb, 1, 1); - put_bits(&pb, 15, (uint32_t)((timestamp >> 15) & 0x7fff)); - put_bits(&pb, 1, 1); - put_bits(&pb, 15, (uint32_t)((timestamp ) & 0x7fff)); - put_bits(&pb, 1, 1); - if (s->is_mpeg2) { - /* clock extension */ - put_bits(&pb, 9, 0); - } - put_bits(&pb, 1, 1); - put_bits(&pb, 22, s->mux_rate); - put_bits(&pb, 1, 1); - if (s->is_mpeg2) { - put_bits(&pb, 1, 1); - put_bits(&pb, 5, 0x1f); /* reserved */ - put_bits(&pb, 3, 0); /* stuffing length */ - } - flush_put_bits(&pb); - return put_bits_ptr(&pb) - pb.buf; -} - -static int put_system_header(AVFormatContext *ctx, uint8_t *buf,int only_for_stream_id) -{ - MpegMuxContext *s = ctx->priv_data; - int size, i, private_stream_coded, id; - PutBitContext pb; - - init_put_bits(&pb, buf, 128); - - put_bits32(&pb, SYSTEM_HEADER_START_CODE); - put_bits(&pb, 16, 0); - put_bits(&pb, 1, 1); - - put_bits(&pb, 22, s->mux_rate); /* maximum bit rate of the multiplexed stream */ - put_bits(&pb, 1, 1); /* marker */ - if (s->is_vcd && only_for_stream_id==VIDEO_ID) { - /* This header applies only to the video stream (see VCD standard p. IV-7)*/ - put_bits(&pb, 6, 0); - } else - put_bits(&pb, 6, s->audio_bound); - - if (s->is_vcd) { - /* see VCD standard, p. IV-7*/ - put_bits(&pb, 1, 0); - put_bits(&pb, 1, 1); - } else { - put_bits(&pb, 1, 0); /* variable bitrate*/ - put_bits(&pb, 1, 0); /* non constrainted bit stream */ - } - - if (s->is_vcd || s->is_dvd) { - /* see VCD standard p IV-7 */ - put_bits(&pb, 1, 1); /* audio locked */ - put_bits(&pb, 1, 1); /* video locked */ - } else { - put_bits(&pb, 1, 0); /* audio locked */ - put_bits(&pb, 1, 0); /* video locked */ - } - - put_bits(&pb, 1, 1); /* marker */ - - if (s->is_vcd && (only_for_stream_id & 0xe0) == AUDIO_ID) { - /* This header applies only to the audio stream (see VCD standard p. IV-7)*/ - put_bits(&pb, 5, 0); - } else - put_bits(&pb, 5, s->video_bound); - - if (s->is_dvd) { - put_bits(&pb, 1, 0); /* packet_rate_restriction_flag */ - put_bits(&pb, 7, 0x7f); /* reserved byte */ - } else - put_bits(&pb, 8, 0xff); /* reserved byte */ - - /* DVD-Video Stream_bound entries - id (0xB9) video, maximum P-STD for stream 0xE0. (P-STD_buffer_bound_scale = 1) - id (0xB8) audio, maximum P-STD for any MPEG audio (0xC0 to 0xC7) streams. If there are none set to 4096 (32x128). (P-STD_buffer_bound_scale = 0) - id (0xBD) private stream 1 (audio other than MPEG and subpictures). (P-STD_buffer_bound_scale = 1) - id (0xBF) private stream 2, NAV packs, set to 2x1024. */ - if (s->is_dvd) { - - int P_STD_max_video = 0; - int P_STD_max_mpeg_audio = 0; - int P_STD_max_mpeg_PS1 = 0; - - for(i=0;inb_streams;i++) { - StreamInfo *stream = ctx->streams[i]->priv_data; - - id = stream->id; - if (id == 0xbd && stream->max_buffer_size > P_STD_max_mpeg_PS1) { - P_STD_max_mpeg_PS1 = stream->max_buffer_size; - } else if (id >= 0xc0 && id <= 0xc7 && stream->max_buffer_size > P_STD_max_mpeg_audio) { - P_STD_max_mpeg_audio = stream->max_buffer_size; - } else if (id == 0xe0 && stream->max_buffer_size > P_STD_max_video) { - P_STD_max_video = stream->max_buffer_size; - } - } - - /* video */ - put_bits(&pb, 8, 0xb9); /* stream ID */ - put_bits(&pb, 2, 3); - put_bits(&pb, 1, 1); - put_bits(&pb, 13, P_STD_max_video / 1024); - - /* audio */ - if (P_STD_max_mpeg_audio == 0) - P_STD_max_mpeg_audio = 4096; - put_bits(&pb, 8, 0xb8); /* stream ID */ - put_bits(&pb, 2, 3); - put_bits(&pb, 1, 0); - put_bits(&pb, 13, P_STD_max_mpeg_audio / 128); - - /* private stream 1 */ - put_bits(&pb, 8, 0xbd); /* stream ID */ - put_bits(&pb, 2, 3); - put_bits(&pb, 1, 0); - put_bits(&pb, 13, P_STD_max_mpeg_PS1 / 128); - - /* private stream 2 */ - put_bits(&pb, 8, 0xbf); /* stream ID */ - put_bits(&pb, 2, 3); - put_bits(&pb, 1, 1); - put_bits(&pb, 13, 2); - } - else { - /* audio stream info */ - private_stream_coded = 0; - for(i=0;inb_streams;i++) { - StreamInfo *stream = ctx->streams[i]->priv_data; - - - /* For VCDs, only include the stream info for the stream - that the pack which contains this system belongs to. - (see VCD standard p. IV-7) */ - if ( !s->is_vcd || stream->id==only_for_stream_id - || only_for_stream_id==0) { - - id = stream->id; - if (id < 0xc0) { - /* special case for private streams (AC-3 uses that) */ - if (private_stream_coded) - continue; - private_stream_coded = 1; - id = 0xbd; - } - put_bits(&pb, 8, id); /* stream ID */ - put_bits(&pb, 2, 3); - if (id < 0xe0) { - /* audio */ - put_bits(&pb, 1, 0); - put_bits(&pb, 13, stream->max_buffer_size / 128); - } else { - /* video */ - put_bits(&pb, 1, 1); - put_bits(&pb, 13, stream->max_buffer_size / 1024); - } - } - } - } - - flush_put_bits(&pb); - size = put_bits_ptr(&pb) - pb.buf; - /* patch packet size */ - buf[4] = (size - 6) >> 8; - buf[5] = (size - 6) & 0xff; - - return size; -} - -static int get_system_header_size(AVFormatContext *ctx) -{ - int buf_index, i, private_stream_coded; - StreamInfo *stream; - MpegMuxContext *s = ctx->priv_data; - - if (s->is_dvd) - return 18; // DVD-Video system headers are 18 bytes fixed length. - - buf_index = 12; - private_stream_coded = 0; - for(i=0;inb_streams;i++) { - stream = ctx->streams[i]->priv_data; - if (stream->id < 0xc0) { - if (private_stream_coded) - continue; - private_stream_coded = 1; - } - buf_index += 3; - } - return buf_index; -} - -static int mpeg_mux_init(AVFormatContext *ctx) -{ - MpegMuxContext *s = ctx->priv_data; - int bitrate, i, mpa_id, mpv_id, mps_id, ac3_id, dts_id, lpcm_id, j; - AVStream *st; - StreamInfo *stream; - int audio_bitrate; - int video_bitrate; - - s->packet_number = 0; - s->is_vcd = (CONFIG_MPEG1VCD_MUXER && ctx->oformat == &ff_mpeg1vcd_muxer); - s->is_svcd = (CONFIG_MPEG2SVCD_MUXER && ctx->oformat == &ff_mpeg2svcd_muxer); - s->is_mpeg2 = ((CONFIG_MPEG2VOB_MUXER && ctx->oformat == &ff_mpeg2vob_muxer) || - (CONFIG_MPEG2DVD_MUXER && ctx->oformat == &ff_mpeg2dvd_muxer) || - (CONFIG_MPEG2SVCD_MUXER && ctx->oformat == &ff_mpeg2svcd_muxer)); - s->is_dvd = (CONFIG_MPEG2DVD_MUXER && ctx->oformat == &ff_mpeg2dvd_muxer); - - if(ctx->packet_size) { - if (ctx->packet_size < 20 || ctx->packet_size > (1 << 23) + 10) { - av_log(ctx, AV_LOG_ERROR, "Invalid packet size %d\n", - ctx->packet_size); - goto fail; - } - s->packet_size = ctx->packet_size; - } else - s->packet_size = 2048; - if (ctx->max_delay < 0) /* Not set by the caller */ - ctx->max_delay = 0; - - s->vcd_padding_bytes_written = 0; - s->vcd_padding_bitrate=0; - - s->audio_bound = 0; - s->video_bound = 0; - mpa_id = AUDIO_ID; - ac3_id = AC3_ID; - dts_id = DTS_ID; - mpv_id = VIDEO_ID; - mps_id = SUB_ID; - lpcm_id = LPCM_ID; - for(i=0;inb_streams;i++) { - st = ctx->streams[i]; - stream = av_mallocz(sizeof(StreamInfo)); - if (!stream) - goto fail; - st->priv_data = stream; - - avpriv_set_pts_info(st, 64, 1, 90000); - - switch(st->codec->codec_type) { - case AVMEDIA_TYPE_AUDIO: - if (st->codec->codec_id == AV_CODEC_ID_AC3) { - stream->id = ac3_id++; - } else if (st->codec->codec_id == AV_CODEC_ID_DTS) { - stream->id = dts_id++; - } else if (st->codec->codec_id == AV_CODEC_ID_PCM_S16BE) { - stream->id = lpcm_id++; - for(j = 0; j < 4; j++) { - if (lpcm_freq_tab[j] == st->codec->sample_rate) - break; - } - if (j == 4) - goto fail; - if (st->codec->channels > 8) - return -1; - stream->lpcm_header[0] = 0x0c; - stream->lpcm_header[1] = (st->codec->channels - 1) | (j << 4); - stream->lpcm_header[2] = 0x80; - stream->lpcm_align = st->codec->channels * 2; - } else { - stream->id = mpa_id++; - } - - /* This value HAS to be used for VCD (see VCD standard, p. IV-7). - Right now it is also used for everything else.*/ - stream->max_buffer_size = 4 * 1024; - s->audio_bound++; - break; - case AVMEDIA_TYPE_VIDEO: - stream->id = mpv_id++; - if (st->codec->rc_buffer_size) - stream->max_buffer_size = 6*1024 + st->codec->rc_buffer_size/8; - else { - av_log(ctx, AV_LOG_WARNING, "VBV buffer size not set, muxing may fail\n"); - stream->max_buffer_size = 230*1024; //FIXME this is probably too small as default - } - s->video_bound++; - break; - case AVMEDIA_TYPE_SUBTITLE: - stream->id = mps_id++; - stream->max_buffer_size = 16 * 1024; - break; - default: - return -1; - } - stream->fifo= av_fifo_alloc(16); - if (!stream->fifo) - goto fail; - } - bitrate = 0; - audio_bitrate = 0; - video_bitrate = 0; - for(i=0;inb_streams;i++) { - int codec_rate; - st = ctx->streams[i]; - stream = (StreamInfo*) st->priv_data; - - if(st->codec->rc_max_rate || stream->id==VIDEO_ID) - codec_rate= st->codec->rc_max_rate; - else - codec_rate= st->codec->bit_rate; - - if(!codec_rate) - codec_rate= (1<<21)*8*50/ctx->nb_streams; - - bitrate += codec_rate; - - if ((stream->id & 0xe0) == AUDIO_ID) - audio_bitrate += codec_rate; - else if (stream->id==VIDEO_ID) - video_bitrate += codec_rate; - } - - if (s->user_mux_rate) { - s->mux_rate = (s->user_mux_rate + (8 * 50) - 1) / (8 * 50); - } else { - /* we increase slightly the bitrate to take into account the - headers. XXX: compute it exactly */ - bitrate += bitrate / 20; - bitrate += 10000; - s->mux_rate = (bitrate + (8 * 50) - 1) / (8 * 50); - } - - if (s->is_vcd) { - double overhead_rate; - - /* The VCD standard mandates that the mux_rate field is 3528 - (see standard p. IV-6). - The value is actually "wrong", i.e. if you calculate - it using the normal formula and the 75 sectors per second transfer - rate you get a different value because the real pack size is 2324, - not 2352. But the standard explicitly specifies that the mux_rate - field in the header must have this value.*/ -// s->mux_rate=2352 * 75 / 50; /* = 3528*/ - - /* The VCD standard states that the muxed stream must be - exactly 75 packs / second (the data rate of a single speed cdrom). - Since the video bitrate (probably 1150000 bits/sec) will be below - the theoretical maximum we have to add some padding packets - to make up for the lower data rate. - (cf. VCD standard p. IV-6 )*/ - - /* Add the header overhead to the data rate. - 2279 data bytes per audio pack, 2294 data bytes per video pack*/ - overhead_rate = ((audio_bitrate / 8.0) / 2279) * (2324 - 2279); - overhead_rate += ((video_bitrate / 8.0) / 2294) * (2324 - 2294); - overhead_rate *= 8; - - /* Add padding so that the full bitrate is 2324*75 bytes/sec */ - s->vcd_padding_bitrate = 2324 * 75 * 8 - (bitrate + overhead_rate); - } - - if (s->is_vcd || s->is_mpeg2) - /* every packet */ - s->pack_header_freq = 1; - else - /* every 2 seconds */ - s->pack_header_freq = 2 * bitrate / s->packet_size / 8; - - /* the above seems to make pack_header_freq zero sometimes */ - if (s->pack_header_freq == 0) - s->pack_header_freq = 1; - - if (s->is_mpeg2) - /* every 200 packets. Need to look at the spec. */ - s->system_header_freq = s->pack_header_freq * 40; - else if (s->is_vcd) - /* the standard mandates that there are only two system headers - in the whole file: one in the first packet of each stream. - (see standard p. IV-7 and IV-8) */ - s->system_header_freq = 0x7fffffff; - else - s->system_header_freq = s->pack_header_freq * 5; - - for(i=0;inb_streams;i++) { - stream = ctx->streams[i]->priv_data; - stream->packet_number = 0; - } - s->system_header_size = get_system_header_size(ctx); - s->last_scr = AV_NOPTS_VALUE; - return 0; - fail: - for(i=0;inb_streams;i++) { - av_free(ctx->streams[i]->priv_data); - } - return AVERROR(ENOMEM); -} - -static inline void put_timestamp(AVIOContext *pb, int id, int64_t timestamp) -{ - avio_w8(pb, - (id << 4) | - (((timestamp >> 30) & 0x07) << 1) | - 1); - avio_wb16(pb, (uint16_t)((((timestamp >> 15) & 0x7fff) << 1) | 1)); - avio_wb16(pb, (uint16_t)((((timestamp ) & 0x7fff) << 1) | 1)); -} - - -/* return the number of padding bytes that should be inserted into - the multiplexed stream.*/ -static int get_vcd_padding_size(AVFormatContext *ctx, int64_t pts) -{ - MpegMuxContext *s = ctx->priv_data; - int pad_bytes = 0; - - if (s->vcd_padding_bitrate > 0 && pts!=AV_NOPTS_VALUE) - { - int64_t full_pad_bytes; - - full_pad_bytes = (int64_t)((s->vcd_padding_bitrate * (pts / 90000.0)) / 8.0); //FIXME this is wrong - pad_bytes = (int) (full_pad_bytes - s->vcd_padding_bytes_written); - - if (pad_bytes<0) - /* might happen if we have already padded to a later timestamp. This - can occur if another stream has already advanced further.*/ - pad_bytes=0; - } - - return pad_bytes; -} - - -/* Write an MPEG padding packet header. */ -static void put_padding_packet(AVFormatContext *ctx, AVIOContext *pb,int packet_bytes) -{ - MpegMuxContext *s = ctx->priv_data; - int i; - - avio_wb32(pb, PADDING_STREAM); - avio_wb16(pb, packet_bytes - 6); - if (!s->is_mpeg2) { - avio_w8(pb, 0x0f); - packet_bytes -= 7; - } else - packet_bytes -= 6; - - for(i=0;ipremux_packet; - - while(len>0){ - if(pkt_desc->size == pkt_desc->unwritten_size) - nb_frames++; - len -= pkt_desc->unwritten_size; - pkt_desc= pkt_desc->next; - } - - return nb_frames; -} - -/* flush the packet on stream stream_index */ -static int flush_packet(AVFormatContext *ctx, int stream_index, - int64_t pts, int64_t dts, int64_t scr, int trailer_size) -{ - MpegMuxContext *s = ctx->priv_data; - StreamInfo *stream = ctx->streams[stream_index]->priv_data; - uint8_t *buf_ptr; - int size, payload_size, startcode, id, stuffing_size, i, header_len; - int packet_size; - uint8_t buffer[128]; - int zero_trail_bytes = 0; - int pad_packet_bytes = 0; - int pes_flags; - int general_pack = 0; /*"general" pack without data specific to one stream?*/ - int nb_frames; - - id = stream->id; - - av_dlog(ctx, "packet ID=%2x PTS=%0.3f\n", id, pts / 90000.0); - - buf_ptr = buffer; - - if ((s->packet_number % s->pack_header_freq) == 0 || s->last_scr != scr) { - /* output pack and systems header if needed */ - size = put_pack_header(ctx, buf_ptr, scr); - buf_ptr += size; - s->last_scr= scr; - - if (s->is_vcd) { - /* there is exactly one system header for each stream in a VCD MPEG, - One in the very first video packet and one in the very first - audio packet (see VCD standard p. IV-7 and IV-8).*/ - - if (stream->packet_number==0) { - size = put_system_header(ctx, buf_ptr, id); - buf_ptr += size; - } - } else if (s->is_dvd) { - if (stream->align_iframe || s->packet_number == 0){ - int PES_bytes_to_fill = s->packet_size - size - 10; - - if (pts != AV_NOPTS_VALUE) { - if (dts != pts) - PES_bytes_to_fill -= 5 + 5; - else - PES_bytes_to_fill -= 5; - } - - if (stream->bytes_to_iframe == 0 || s->packet_number == 0) { - size = put_system_header(ctx, buf_ptr, 0); - buf_ptr += size; - size = buf_ptr - buffer; - avio_write(ctx->pb, buffer, size); - - avio_wb32(ctx->pb, PRIVATE_STREAM_2); - avio_wb16(ctx->pb, 0x03d4); // length - avio_w8(ctx->pb, 0x00); // substream ID, 00=PCI - for (i = 0; i < 979; i++) - avio_w8(ctx->pb, 0x00); - - avio_wb32(ctx->pb, PRIVATE_STREAM_2); - avio_wb16(ctx->pb, 0x03fa); // length - avio_w8(ctx->pb, 0x01); // substream ID, 01=DSI - for (i = 0; i < 1017; i++) - avio_w8(ctx->pb, 0x00); - - memset(buffer, 0, 128); - buf_ptr = buffer; - s->packet_number++; - stream->align_iframe = 0; - scr += s->packet_size*90000LL / (s->mux_rate*50LL); //FIXME rounding and first few bytes of each packet - size = put_pack_header(ctx, buf_ptr, scr); - s->last_scr= scr; - buf_ptr += size; - /* GOP Start */ - } else if (stream->bytes_to_iframe < PES_bytes_to_fill) { - pad_packet_bytes = PES_bytes_to_fill - stream->bytes_to_iframe; - } - } - } else { - if ((s->packet_number % s->system_header_freq) == 0) { - size = put_system_header(ctx, buf_ptr, 0); - buf_ptr += size; - } - } - } - size = buf_ptr - buffer; - avio_write(ctx->pb, buffer, size); - - packet_size = s->packet_size - size; - - if (s->is_vcd && (id & 0xe0) == AUDIO_ID) - /* The VCD standard demands that 20 zero bytes follow - each audio pack (see standard p. IV-8).*/ - zero_trail_bytes += 20; - - if ((s->is_vcd && stream->packet_number==0) - || (s->is_svcd && s->packet_number==0)) { - /* for VCD the first pack of each stream contains only the pack header, - the system header and lots of padding (see VCD standard p. IV-6). - In the case of an audio pack, 20 zero bytes are also added at - the end.*/ - /* For SVCD we fill the very first pack to increase compatibility with - some DVD players. Not mandated by the standard.*/ - if (s->is_svcd) - general_pack = 1; /* the system header refers to both streams and no stream data*/ - pad_packet_bytes = packet_size - zero_trail_bytes; - } - - packet_size -= pad_packet_bytes + zero_trail_bytes; - - if (packet_size > 0) { - - /* packet header size */ - packet_size -= 6; - - /* packet header */ - if (s->is_mpeg2) { - header_len = 3; - if (stream->packet_number==0) - header_len += 3; /* PES extension */ - header_len += 1; /* obligatory stuffing byte */ - } else { - header_len = 0; - } - if (pts != AV_NOPTS_VALUE) { - if (dts != pts) - header_len += 5 + 5; - else - header_len += 5; - } else { - if (!s->is_mpeg2) - header_len++; - } - - payload_size = packet_size - header_len; - if (id < 0xc0) { - startcode = PRIVATE_STREAM_1; - payload_size -= 1; - if (id >= 0x40) { - payload_size -= 3; - if (id >= 0xa0) - payload_size -= 3; - } - } else { - startcode = 0x100 + id; - } - - stuffing_size = payload_size - av_fifo_size(stream->fifo); - - // first byte does not fit -> reset pts/dts + stuffing - if(payload_size <= trailer_size && pts != AV_NOPTS_VALUE){ - int timestamp_len=0; - if(dts != pts) - timestamp_len += 5; - if(pts != AV_NOPTS_VALUE) - timestamp_len += s->is_mpeg2 ? 5 : 4; - pts=dts= AV_NOPTS_VALUE; - header_len -= timestamp_len; - if (s->is_dvd && stream->align_iframe) { - pad_packet_bytes += timestamp_len; - packet_size -= timestamp_len; - } else { - payload_size += timestamp_len; - } - stuffing_size += timestamp_len; - if(payload_size > trailer_size) - stuffing_size += payload_size - trailer_size; - } - - if (pad_packet_bytes > 0 && pad_packet_bytes <= 7) { // can't use padding, so use stuffing - packet_size += pad_packet_bytes; - payload_size += pad_packet_bytes; // undo the previous adjustment - if (stuffing_size < 0) { - stuffing_size = pad_packet_bytes; - } else { - stuffing_size += pad_packet_bytes; - } - pad_packet_bytes = 0; - } - - if (stuffing_size < 0) - stuffing_size = 0; - - if (startcode == PRIVATE_STREAM_1 && id >= 0xa0) { - if (payload_size < av_fifo_size(stream->fifo)) - stuffing_size += payload_size % stream->lpcm_align; - } - - if (stuffing_size > 16) { /*<=16 for MPEG-1, <=32 for MPEG-2*/ - pad_packet_bytes += stuffing_size; - packet_size -= stuffing_size; - payload_size -= stuffing_size; - stuffing_size = 0; - } - - nb_frames= get_nb_frames(ctx, stream, payload_size - stuffing_size); - - avio_wb32(ctx->pb, startcode); - - avio_wb16(ctx->pb, packet_size); - - if (!s->is_mpeg2) - for(i=0;ipb, 0xff); - - if (s->is_mpeg2) { - avio_w8(ctx->pb, 0x80); /* mpeg2 id */ - - pes_flags=0; - - if (pts != AV_NOPTS_VALUE) { - pes_flags |= 0x80; - if (dts != pts) - pes_flags |= 0x40; - } - - /* Both the MPEG-2 and the SVCD standards demand that the - P-STD_buffer_size field be included in the first packet of - every stream. (see SVCD standard p. 26 V.2.3.1 and V.2.3.2 - and MPEG-2 standard 2.7.7) */ - if (stream->packet_number == 0) - pes_flags |= 0x01; - - avio_w8(ctx->pb, pes_flags); /* flags */ - avio_w8(ctx->pb, header_len - 3 + stuffing_size); - - if (pes_flags & 0x80) /*write pts*/ - put_timestamp(ctx->pb, (pes_flags & 0x40) ? 0x03 : 0x02, pts); - if (pes_flags & 0x40) /*write dts*/ - put_timestamp(ctx->pb, 0x01, dts); - - if (pes_flags & 0x01) { /*write pes extension*/ - avio_w8(ctx->pb, 0x10); /* flags */ - - /* P-STD buffer info */ - if ((id & 0xe0) == AUDIO_ID) - avio_wb16(ctx->pb, 0x4000 | stream->max_buffer_size/ 128); - else - avio_wb16(ctx->pb, 0x6000 | stream->max_buffer_size/1024); - } - - } else { - if (pts != AV_NOPTS_VALUE) { - if (dts != pts) { - put_timestamp(ctx->pb, 0x03, pts); - put_timestamp(ctx->pb, 0x01, dts); - } else { - put_timestamp(ctx->pb, 0x02, pts); - } - } else { - avio_w8(ctx->pb, 0x0f); - } - } - - if (s->is_mpeg2) { - /* special stuffing byte that is always written - to prevent accidental generation of start codes. */ - avio_w8(ctx->pb, 0xff); - - for(i=0;ipb, 0xff); - } - - if (startcode == PRIVATE_STREAM_1) { - avio_w8(ctx->pb, id); - if (id >= 0xa0) { - /* LPCM (XXX: check nb_frames) */ - avio_w8(ctx->pb, 7); - avio_wb16(ctx->pb, 4); /* skip 3 header bytes */ - avio_w8(ctx->pb, stream->lpcm_header[0]); - avio_w8(ctx->pb, stream->lpcm_header[1]); - avio_w8(ctx->pb, stream->lpcm_header[2]); - } else if (id >= 0x40) { - /* AC-3 */ - avio_w8(ctx->pb, nb_frames); - avio_wb16(ctx->pb, trailer_size+1); - } - } - - /* output data */ - assert(payload_size - stuffing_size <= av_fifo_size(stream->fifo)); - av_fifo_generic_read(stream->fifo, ctx->pb, payload_size - stuffing_size, (void*)avio_write); - stream->bytes_to_iframe -= payload_size - stuffing_size; - }else{ - payload_size= - stuffing_size= 0; - } - - if (pad_packet_bytes > 0) - put_padding_packet(ctx,ctx->pb, pad_packet_bytes); - - for(i=0;ipb, 0x00); - - avio_flush(ctx->pb); - - s->packet_number++; - - /* only increase the stream packet number if this pack actually contains - something that is specific to this stream! I.e. a dedicated header - or some data.*/ - if (!general_pack) - stream->packet_number++; - - return payload_size - stuffing_size; -} - -static void put_vcd_padding_sector(AVFormatContext *ctx) -{ - /* There are two ways to do this padding: writing a sector/pack - of 0 values, or writing an MPEG padding pack. Both seem to - work with most decoders, BUT the VCD standard only allows a 0-sector - (see standard p. IV-4, IV-5). - So a 0-sector it is...*/ - - MpegMuxContext *s = ctx->priv_data; - int i; - - for(i=0;ipacket_size;i++) - avio_w8(ctx->pb, 0); - - s->vcd_padding_bytes_written += s->packet_size; - - avio_flush(ctx->pb); - - /* increasing the packet number is correct. The SCR of the following packs - is calculated from the packet_number and it has to include the padding - sector (it represents the sector index, not the MPEG pack index) - (see VCD standard p. IV-6)*/ - s->packet_number++; -} - -static int remove_decoded_packets(AVFormatContext *ctx, int64_t scr){ -// MpegMuxContext *s = ctx->priv_data; - int i; - - for(i=0; inb_streams; i++){ - AVStream *st = ctx->streams[i]; - StreamInfo *stream = st->priv_data; - PacketDesc *pkt_desc; - - while((pkt_desc= stream->predecode_packet) - && scr > pkt_desc->dts){ //FIXME > vs >= - if(stream->buffer_index < pkt_desc->size || - stream->predecode_packet == stream->premux_packet){ - av_log(ctx, AV_LOG_ERROR, - "buffer underflow i=%d bufi=%d size=%d\n", - i, stream->buffer_index, pkt_desc->size); - break; - } - stream->buffer_index -= pkt_desc->size; - - stream->predecode_packet= pkt_desc->next; - av_freep(&pkt_desc); - } - } - - return 0; -} - -static int output_packet(AVFormatContext *ctx, int flush){ - MpegMuxContext *s = ctx->priv_data; - AVStream *st; - StreamInfo *stream; - int i, avail_space=0, es_size, trailer_size; - int best_i= -1; - int best_score= INT_MIN; - int ignore_constraints=0; - int64_t scr= s->last_scr; - PacketDesc *timestamp_packet; - const int64_t max_delay= av_rescale(ctx->max_delay, 90000, AV_TIME_BASE); - -retry: - for(i=0; inb_streams; i++){ - AVStream *st = ctx->streams[i]; - StreamInfo *stream = st->priv_data; - const int avail_data= av_fifo_size(stream->fifo); - const int space= stream->max_buffer_size - stream->buffer_index; - int rel_space= 1024LL*space / stream->max_buffer_size; - PacketDesc *next_pkt= stream->premux_packet; - - /* for subtitle, a single PES packet must be generated, - so we flush after every single subtitle packet */ - if(s->packet_size > avail_data && !flush - && st->codec->codec_type != AVMEDIA_TYPE_SUBTITLE) - return 0; - if(avail_data==0) - continue; - assert(avail_data>0); - - if(space < s->packet_size && !ignore_constraints) - continue; - - if(next_pkt && next_pkt->dts - scr > max_delay) - continue; - - if(rel_space > best_score){ - best_score= rel_space; - best_i = i; - avail_space= space; - } - } - - if(best_i < 0){ - int64_t best_dts= INT64_MAX; - - for(i=0; inb_streams; i++){ - AVStream *st = ctx->streams[i]; - StreamInfo *stream = st->priv_data; - PacketDesc *pkt_desc= stream->predecode_packet; - if(pkt_desc && pkt_desc->dts < best_dts) - best_dts= pkt_desc->dts; - } - - av_dlog(ctx, "bumping scr, scr:%f, dts:%f\n", - scr / 90000.0, best_dts / 90000.0); - if(best_dts == INT64_MAX) - return 0; - - if(scr >= best_dts+1 && !ignore_constraints){ - av_log(ctx, AV_LOG_ERROR, "packet too large, ignoring buffer limits to mux it\n"); - ignore_constraints= 1; - } - scr= FFMAX(best_dts+1, scr); - if(remove_decoded_packets(ctx, scr) < 0) - return -1; - goto retry; - } - - assert(best_i >= 0); - - st = ctx->streams[best_i]; - stream = st->priv_data; - - assert(av_fifo_size(stream->fifo) > 0); - - assert(avail_space >= s->packet_size || ignore_constraints); - - timestamp_packet= stream->premux_packet; - if(timestamp_packet->unwritten_size == timestamp_packet->size){ - trailer_size= 0; - }else{ - trailer_size= timestamp_packet->unwritten_size; - timestamp_packet= timestamp_packet->next; - } - - if(timestamp_packet){ - av_dlog(ctx, "dts:%f pts:%f scr:%f stream:%d\n", - timestamp_packet->dts / 90000.0, - timestamp_packet->pts / 90000.0, - scr / 90000.0, best_i); - es_size= flush_packet(ctx, best_i, timestamp_packet->pts, timestamp_packet->dts, scr, trailer_size); - }else{ - assert(av_fifo_size(stream->fifo) == trailer_size); - es_size= flush_packet(ctx, best_i, AV_NOPTS_VALUE, AV_NOPTS_VALUE, scr, trailer_size); - } - - if (s->is_vcd) { - /* Write one or more padding sectors, if necessary, to reach - the constant overall bitrate.*/ - int vcd_pad_bytes; - - while((vcd_pad_bytes = get_vcd_padding_size(ctx,stream->premux_packet->pts) ) >= s->packet_size){ //FIXME pts cannot be correct here - put_vcd_padding_sector(ctx); - s->last_scr += s->packet_size*90000LL / (s->mux_rate*50LL); //FIXME rounding and first few bytes of each packet - } - } - - stream->buffer_index += es_size; - s->last_scr += s->packet_size*90000LL / (s->mux_rate*50LL); //FIXME rounding and first few bytes of each packet - - while(stream->premux_packet && stream->premux_packet->unwritten_size <= es_size){ - es_size -= stream->premux_packet->unwritten_size; - stream->premux_packet= stream->premux_packet->next; - } - if(es_size) - stream->premux_packet->unwritten_size -= es_size; - - if(remove_decoded_packets(ctx, s->last_scr) < 0) - return -1; - - return 1; -} - -static int mpeg_mux_write_packet(AVFormatContext *ctx, AVPacket *pkt) -{ - MpegMuxContext *s = ctx->priv_data; - int stream_index= pkt->stream_index; - int size= pkt->size; - uint8_t *buf= pkt->data; - AVStream *st = ctx->streams[stream_index]; - StreamInfo *stream = st->priv_data; - int64_t pts, dts; - PacketDesc *pkt_desc; - int preload; - const int is_iframe = st->codec->codec_type == AVMEDIA_TYPE_VIDEO && (pkt->flags & AV_PKT_FLAG_KEY); - - preload = av_rescale(s->preload, 90000, AV_TIME_BASE); - - pts= pkt->pts; - dts= pkt->dts; - - if (s->last_scr == AV_NOPTS_VALUE) { - if (dts == AV_NOPTS_VALUE || (dts < preload && ctx->avoid_negative_ts) || s->is_dvd) { - if (dts != AV_NOPTS_VALUE) - s->preload += av_rescale(-dts, AV_TIME_BASE, 90000); - s->last_scr = 0; - } else { - s->last_scr = dts - preload; - s->preload = 0; - } - preload = av_rescale(s->preload, 90000, AV_TIME_BASE); - av_log(ctx, AV_LOG_DEBUG, "First SCR: %"PRId64" First DTS: %"PRId64"\n", s->last_scr, dts + preload); - } - - if (dts != AV_NOPTS_VALUE) dts += preload; - if (pts != AV_NOPTS_VALUE) pts += preload; - - av_dlog(ctx, "dts:%f pts:%f flags:%d stream:%d nopts:%d\n", - dts / 90000.0, pts / 90000.0, pkt->flags, - pkt->stream_index, pts != AV_NOPTS_VALUE); - if (!stream->premux_packet) - stream->next_packet = &stream->premux_packet; - *stream->next_packet= - pkt_desc= av_mallocz(sizeof(PacketDesc)); - pkt_desc->pts= pts; - pkt_desc->dts= dts; - pkt_desc->unwritten_size= - pkt_desc->size= size; - if(!stream->predecode_packet) - stream->predecode_packet= pkt_desc; - stream->next_packet= &pkt_desc->next; - - if (av_fifo_realloc2(stream->fifo, av_fifo_size(stream->fifo) + size) < 0) - return -1; - - if (s->is_dvd){ - if (is_iframe && (s->packet_number == 0 || (pts - stream->vobu_start_pts >= 36000))) { // min VOBU length 0.4 seconds (mpucoder) - stream->bytes_to_iframe = av_fifo_size(stream->fifo); - stream->align_iframe = 1; - stream->vobu_start_pts = pts; - } - } - - av_fifo_generic_write(stream->fifo, buf, size, NULL); - - for(;;){ - int ret= output_packet(ctx, 0); - if(ret<=0) - return ret; - } -} - -static int mpeg_mux_end(AVFormatContext *ctx) -{ -// MpegMuxContext *s = ctx->priv_data; - StreamInfo *stream; - int i; - - for(;;){ - int ret= output_packet(ctx, 1); - if(ret<0) - return ret; - else if(ret==0) - break; - } - - /* End header according to MPEG1 systems standard. We do not write - it as it is usually not needed by decoders and because it - complicates MPEG stream concatenation. */ - //avio_wb32(ctx->pb, ISO_11172_END_CODE); - //avio_flush(ctx->pb); - - for(i=0;inb_streams;i++) { - stream = ctx->streams[i]->priv_data; - - assert(av_fifo_size(stream->fifo) == 0); - av_fifo_free(stream->fifo); - } - return 0; -} - -#define OFFSET(x) offsetof(MpegMuxContext, x) -#define E AV_OPT_FLAG_ENCODING_PARAM -static const AVOption options[] = { - { "muxrate", NULL, OFFSET(user_mux_rate), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, E }, - { "preload", "Initial demux-decode delay in microseconds.", OFFSET(preload), AV_OPT_TYPE_INT, {.i64 = 500000}, 0, INT_MAX, E}, - { NULL }, -}; - -#define MPEGENC_CLASS(flavor)\ -static const AVClass flavor ## _class = {\ - .class_name = #flavor " muxer",\ - .item_name = av_default_item_name,\ - .version = LIBAVUTIL_VERSION_INT,\ - .option = options,\ -}; - -#if CONFIG_MPEG1SYSTEM_MUXER -MPEGENC_CLASS(mpeg) -AVOutputFormat ff_mpeg1system_muxer = { - .name = "mpeg", - .long_name = NULL_IF_CONFIG_SMALL("MPEG-1 Systems / MPEG program stream"), - .mime_type = "video/mpeg", - .extensions = "mpg,mpeg", - .priv_data_size = sizeof(MpegMuxContext), - .audio_codec = AV_CODEC_ID_MP2, - .video_codec = AV_CODEC_ID_MPEG1VIDEO, - .write_header = mpeg_mux_init, - .write_packet = mpeg_mux_write_packet, - .write_trailer = mpeg_mux_end, - .priv_class = &mpeg_class, -}; -#endif -#if CONFIG_MPEG1VCD_MUXER -MPEGENC_CLASS(vcd) -AVOutputFormat ff_mpeg1vcd_muxer = { - .name = "vcd", - .long_name = NULL_IF_CONFIG_SMALL("MPEG-1 Systems / MPEG program stream (VCD)"), - .mime_type = "video/mpeg", - .priv_data_size = sizeof(MpegMuxContext), - .audio_codec = AV_CODEC_ID_MP2, - .video_codec = AV_CODEC_ID_MPEG1VIDEO, - .write_header = mpeg_mux_init, - .write_packet = mpeg_mux_write_packet, - .write_trailer = mpeg_mux_end, - .priv_class = &vcd_class, -}; -#endif -#if CONFIG_MPEG2VOB_MUXER -MPEGENC_CLASS(vob) -AVOutputFormat ff_mpeg2vob_muxer = { - .name = "vob", - .long_name = NULL_IF_CONFIG_SMALL("MPEG-2 PS (VOB)"), - .mime_type = "video/mpeg", - .extensions = "vob", - .priv_data_size = sizeof(MpegMuxContext), - .audio_codec = AV_CODEC_ID_MP2, - .video_codec = AV_CODEC_ID_MPEG2VIDEO, - .write_header = mpeg_mux_init, - .write_packet = mpeg_mux_write_packet, - .write_trailer = mpeg_mux_end, - .priv_class = &vob_class, -}; -#endif - -/* Same as mpeg2vob_mux except that the pack size is 2324 */ -#if CONFIG_MPEG2SVCD_MUXER -MPEGENC_CLASS(svcd) -AVOutputFormat ff_mpeg2svcd_muxer = { - .name = "svcd", - .long_name = NULL_IF_CONFIG_SMALL("MPEG-2 PS (SVCD)"), - .mime_type = "video/mpeg", - .extensions = "vob", - .priv_data_size = sizeof(MpegMuxContext), - .audio_codec = AV_CODEC_ID_MP2, - .video_codec = AV_CODEC_ID_MPEG2VIDEO, - .write_header = mpeg_mux_init, - .write_packet = mpeg_mux_write_packet, - .write_trailer = mpeg_mux_end, - .priv_class = &svcd_class, -}; -#endif - -/* Same as mpeg2vob_mux except the 'is_dvd' flag is set to produce NAV pkts */ -#if CONFIG_MPEG2DVD_MUXER -MPEGENC_CLASS(dvd) -AVOutputFormat ff_mpeg2dvd_muxer = { - .name = "dvd", - .long_name = NULL_IF_CONFIG_SMALL("MPEG-2 PS (DVD VOB)"), - .mime_type = "video/mpeg", - .extensions = "dvd", - .priv_data_size = sizeof(MpegMuxContext), - .audio_codec = AV_CODEC_ID_MP2, - .video_codec = AV_CODEC_ID_MPEG2VIDEO, - .write_header = mpeg_mux_init, - .write_packet = mpeg_mux_write_packet, - .write_trailer = mpeg_mux_end, - .priv_class = &dvd_class, -}; -#endif diff --git a/ffmpeg1/libavformat/mpegts.c b/ffmpeg1/libavformat/mpegts.c deleted file mode 100644 index 85b5146..0000000 --- a/ffmpeg1/libavformat/mpegts.c +++ /dev/null @@ -1,2313 +0,0 @@ -/* - * MPEG2 transport stream (aka DVB) demuxer - * Copyright (c) 2002-2003 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 "libavutil/buffer.h" -#include "libavutil/crc.h" -#include "libavutil/intreadwrite.h" -#include "libavutil/log.h" -#include "libavutil/dict.h" -#include "libavutil/mathematics.h" -#include "libavutil/opt.h" -#include "libavutil/avassert.h" -#include "libavcodec/bytestream.h" -#include "libavcodec/get_bits.h" -#include "avformat.h" -#include "mpegts.h" -#include "internal.h" -#include "avio_internal.h" -#include "seek.h" -#include "mpeg.h" -#include "isom.h" - -/* maximum size in which we look for synchronisation if - synchronisation is lost */ -#define MAX_RESYNC_SIZE 65536 - -#define MAX_PES_PAYLOAD 200*1024 - -#define MAX_MP4_DESCR_COUNT 16 - -enum MpegTSFilterType { - MPEGTS_PES, - MPEGTS_SECTION, -}; - -typedef struct MpegTSFilter MpegTSFilter; - -typedef int PESCallback(MpegTSFilter *f, const uint8_t *buf, int len, int is_start, int64_t pos); - -typedef struct MpegTSPESFilter { - PESCallback *pes_cb; - void *opaque; -} MpegTSPESFilter; - -typedef void SectionCallback(MpegTSFilter *f, const uint8_t *buf, int len); - -typedef void SetServiceCallback(void *opaque, int ret); - -typedef struct MpegTSSectionFilter { - int section_index; - int section_h_size; - uint8_t *section_buf; - unsigned int check_crc:1; - unsigned int end_of_section_reached:1; - SectionCallback *section_cb; - void *opaque; -} MpegTSSectionFilter; - -struct MpegTSFilter { - int pid; - int es_id; - int last_cc; /* last cc code (-1 if first packet) */ - enum MpegTSFilterType type; - union { - MpegTSPESFilter pes_filter; - MpegTSSectionFilter section_filter; - } u; -}; - -#define MAX_PIDS_PER_PROGRAM 64 -struct Program { - unsigned int id; //program id/service id - unsigned int nb_pids; - unsigned int pids[MAX_PIDS_PER_PROGRAM]; -}; - -struct MpegTSContext { - const AVClass *class; - /* user data */ - AVFormatContext *stream; - /** raw packet size, including FEC if present */ - int raw_packet_size; - - int pos47; - - /** if true, all pids are analyzed to find streams */ - int auto_guess; - - /** compute exact PCR for each transport stream packet */ - int mpeg2ts_compute_pcr; - - int64_t cur_pcr; /**< used to estimate the exact PCR */ - int pcr_incr; /**< used to estimate the exact PCR */ - - /* data needed to handle file based ts */ - /** stop parsing loop */ - int stop_parse; - /** packet containing Audio/Video data */ - AVPacket *pkt; - /** to detect seek */ - int64_t last_pos; - - /******************************************/ - /* private mpegts data */ - /* scan context */ - /** structure to keep track of Program->pids mapping */ - unsigned int nb_prg; - struct Program *prg; - - int8_t crc_validity[NB_PID_MAX]; - - /** filters for various streams specified by PMT + for the PAT and PMT */ - MpegTSFilter *pids[NB_PID_MAX]; - int current_pid; -}; - -static const AVOption options[] = { - {"compute_pcr", "Compute exact PCR for each transport stream packet.", offsetof(MpegTSContext, mpeg2ts_compute_pcr), AV_OPT_TYPE_INT, - {.i64 = 0}, 0, 1, AV_OPT_FLAG_DECODING_PARAM }, - { NULL }, -}; - -static const AVClass mpegtsraw_class = { - .class_name = "mpegtsraw demuxer", - .item_name = av_default_item_name, - .option = options, - .version = LIBAVUTIL_VERSION_INT, -}; - -/* TS stream handling */ - -enum MpegTSState { - MPEGTS_HEADER = 0, - MPEGTS_PESHEADER, - MPEGTS_PESHEADER_FILL, - MPEGTS_PAYLOAD, - MPEGTS_SKIP, -}; - -/* enough for PES header + length */ -#define PES_START_SIZE 6 -#define PES_HEADER_SIZE 9 -#define MAX_PES_HEADER_SIZE (9 + 255) - -typedef struct PESContext { - int pid; - int pcr_pid; /**< if -1 then all packets containing PCR are considered */ - int stream_type; - MpegTSContext *ts; - AVFormatContext *stream; - AVStream *st; - AVStream *sub_st; /**< stream for the embedded AC3 stream in HDMV TrueHD */ - enum MpegTSState state; - /* used to get the format */ - int data_index; - int flags; /**< copied to the AVPacket flags */ - int total_size; - int pes_header_size; - int extended_stream_id; - int64_t pts, dts; - int64_t ts_packet_pos; /**< position of first TS packet of this PES packet */ - uint8_t header[MAX_PES_HEADER_SIZE]; - AVBufferRef *buffer; - SLConfigDescr sl; -} PESContext; - -extern AVInputFormat ff_mpegts_demuxer; - -static void clear_avprogram(MpegTSContext *ts, unsigned int programid) -{ - AVProgram *prg = NULL; - int i; - for(i=0; istream->nb_programs; i++) - if(ts->stream->programs[i]->id == programid){ - prg = ts->stream->programs[i]; - break; - } - if (!prg) - return; - prg->nb_stream_indexes = 0; -} - -static void clear_program(MpegTSContext *ts, unsigned int programid) -{ - int i; - - clear_avprogram(ts, programid); - for(i=0; inb_prg; i++) - if(ts->prg[i].id == programid) - ts->prg[i].nb_pids = 0; -} - -static void clear_programs(MpegTSContext *ts) -{ - av_freep(&ts->prg); - ts->nb_prg=0; -} - -static void add_pat_entry(MpegTSContext *ts, unsigned int programid) -{ - struct Program *p; - void *tmp = av_realloc(ts->prg, (ts->nb_prg+1)*sizeof(struct Program)); - if(!tmp) - return; - ts->prg = tmp; - p = &ts->prg[ts->nb_prg]; - p->id = programid; - p->nb_pids = 0; - ts->nb_prg++; -} - -static void add_pid_to_pmt(MpegTSContext *ts, unsigned int programid, unsigned int pid) -{ - int i; - struct Program *p = NULL; - for(i=0; inb_prg; i++) { - if(ts->prg[i].id == programid) { - p = &ts->prg[i]; - break; - } - } - if(!p) - return; - - if(p->nb_pids >= MAX_PIDS_PER_PROGRAM) - return; - p->pids[p->nb_pids++] = pid; -} - -static void set_pcr_pid(AVFormatContext *s, unsigned int programid, unsigned int pid) -{ - int i; - for(i=0; inb_programs; i++) { - if(s->programs[i]->id == programid) { - s->programs[i]->pcr_pid = pid; - break; - } - } -} - -/** - * @brief discard_pid() decides if the pid is to be discarded according - * to caller's programs selection - * @param ts : - TS context - * @param pid : - pid - * @return 1 if the pid is only comprised in programs that have .discard=AVDISCARD_ALL - * 0 otherwise - */ -static int discard_pid(MpegTSContext *ts, unsigned int pid) -{ - int i, j, k; - int used = 0, discarded = 0; - struct Program *p; - for(i=0; inb_prg; i++) { - p = &ts->prg[i]; - for(j=0; jnb_pids; j++) { - if(p->pids[j] != pid) - continue; - //is program with id p->id set to be discarded? - for(k=0; kstream->nb_programs; k++) { - if(ts->stream->programs[k]->id == p->id) { - if(ts->stream->programs[k]->discard == AVDISCARD_ALL) - discarded++; - else - used++; - } - } - } - } - - return !used && discarded; -} - -/** - * Assemble PES packets out of TS packets, and then call the "section_cb" - * function when they are complete. - */ -static void write_section_data(AVFormatContext *s, MpegTSFilter *tss1, - const uint8_t *buf, int buf_size, int is_start) -{ - MpegTSContext *ts = s->priv_data; - MpegTSSectionFilter *tss = &tss1->u.section_filter; - int len; - - if (is_start) { - memcpy(tss->section_buf, buf, buf_size); - tss->section_index = buf_size; - tss->section_h_size = -1; - tss->end_of_section_reached = 0; - } else { - if (tss->end_of_section_reached) - return; - len = 4096 - tss->section_index; - if (buf_size < len) - len = buf_size; - memcpy(tss->section_buf + tss->section_index, buf, len); - tss->section_index += len; - } - - /* compute section length if possible */ - if (tss->section_h_size == -1 && tss->section_index >= 3) { - len = (AV_RB16(tss->section_buf + 1) & 0xfff) + 3; - if (len > 4096) - return; - tss->section_h_size = len; - } - - if (tss->section_h_size != -1 && tss->section_index >= tss->section_h_size) { - int crc_valid = 1; - tss->end_of_section_reached = 1; - - if (tss->check_crc){ - crc_valid = !av_crc(av_crc_get_table(AV_CRC_32_IEEE), -1, tss->section_buf, tss->section_h_size); - if (crc_valid){ - ts->crc_validity[ tss1->pid ] = 100; - }else if(ts->crc_validity[ tss1->pid ] > -10){ - ts->crc_validity[ tss1->pid ]--; - }else - crc_valid = 2; - } - if (crc_valid) - tss->section_cb(tss1, tss->section_buf, tss->section_h_size); - } -} - -static MpegTSFilter *mpegts_open_section_filter(MpegTSContext *ts, unsigned int pid, - SectionCallback *section_cb, void *opaque, - int check_crc) - -{ - MpegTSFilter *filter; - MpegTSSectionFilter *sec; - - av_dlog(ts->stream, "Filter: pid=0x%x\n", pid); - - if (pid >= NB_PID_MAX || ts->pids[pid]) - return NULL; - filter = av_mallocz(sizeof(MpegTSFilter)); - if (!filter) - return NULL; - ts->pids[pid] = filter; - filter->type = MPEGTS_SECTION; - filter->pid = pid; - filter->es_id = -1; - filter->last_cc = -1; - sec = &filter->u.section_filter; - sec->section_cb = section_cb; - sec->opaque = opaque; - sec->section_buf = av_malloc(MAX_SECTION_SIZE); - sec->check_crc = check_crc; - if (!sec->section_buf) { - av_free(filter); - return NULL; - } - return filter; -} - -static MpegTSFilter *mpegts_open_pes_filter(MpegTSContext *ts, unsigned int pid, - PESCallback *pes_cb, - void *opaque) -{ - MpegTSFilter *filter; - MpegTSPESFilter *pes; - - if (pid >= NB_PID_MAX || ts->pids[pid]) - return NULL; - filter = av_mallocz(sizeof(MpegTSFilter)); - if (!filter) - return NULL; - ts->pids[pid] = filter; - filter->type = MPEGTS_PES; - filter->pid = pid; - filter->es_id = -1; - filter->last_cc = -1; - pes = &filter->u.pes_filter; - pes->pes_cb = pes_cb; - pes->opaque = opaque; - return filter; -} - -static void mpegts_close_filter(MpegTSContext *ts, MpegTSFilter *filter) -{ - int pid; - - pid = filter->pid; - if (filter->type == MPEGTS_SECTION) - av_freep(&filter->u.section_filter.section_buf); - else if (filter->type == MPEGTS_PES) { - PESContext *pes = filter->u.pes_filter.opaque; - av_buffer_unref(&pes->buffer); - /* referenced private data will be freed later in - * avformat_close_input */ - if (!((PESContext *)filter->u.pes_filter.opaque)->st) { - av_freep(&filter->u.pes_filter.opaque); - } - } - - av_free(filter); - ts->pids[pid] = NULL; -} - -static int analyze(const uint8_t *buf, int size, int packet_size, int *index){ - int stat[TS_MAX_PACKET_SIZE]; - int i; - int x=0; - int best_score=0; - - memset(stat, 0, packet_size*sizeof(int)); - - for(x=i=0; i best_score){ - best_score= stat[x]; - if(index) *index= x; - } - } - - x++; - if(x == packet_size) x= 0; - } - - return best_score; -} - -/* autodetect fec presence. Must have at least 1024 bytes */ -static int get_packet_size(const uint8_t *buf, int size) -{ - int score, fec_score, dvhs_score; - - if (size < (TS_FEC_PACKET_SIZE * 5 + 1)) - return -1; - - score = analyze(buf, size, TS_PACKET_SIZE, NULL); - dvhs_score = analyze(buf, size, TS_DVHS_PACKET_SIZE, NULL); - fec_score= analyze(buf, size, TS_FEC_PACKET_SIZE, NULL); - av_dlog(NULL, "score: %d, dvhs_score: %d, fec_score: %d \n", - score, dvhs_score, fec_score); - - if (score > fec_score && score > dvhs_score) return TS_PACKET_SIZE; - else if(dvhs_score > score && dvhs_score > fec_score) return TS_DVHS_PACKET_SIZE; - else if(score < fec_score && dvhs_score < fec_score) return TS_FEC_PACKET_SIZE; - else return -1; -} - -typedef struct SectionHeader { - uint8_t tid; - uint16_t id; - uint8_t version; - uint8_t sec_num; - uint8_t last_sec_num; -} SectionHeader; - -static inline int get8(const uint8_t **pp, const uint8_t *p_end) -{ - const uint8_t *p; - int c; - - p = *pp; - if (p >= p_end) - return -1; - c = *p++; - *pp = p; - return c; -} - -static inline int get16(const uint8_t **pp, const uint8_t *p_end) -{ - const uint8_t *p; - int c; - - p = *pp; - if ((p + 1) >= p_end) - return -1; - c = AV_RB16(p); - p += 2; - *pp = p; - return c; -} - -/* read and allocate a DVB string preceded by its length */ -static char *getstr8(const uint8_t **pp, const uint8_t *p_end) -{ - int len; - const uint8_t *p; - char *str; - - p = *pp; - len = get8(&p, p_end); - if (len < 0) - return NULL; - if ((p + len) > p_end) - return NULL; - str = av_malloc(len + 1); - if (!str) - return NULL; - memcpy(str, p, len); - str[len] = '\0'; - p += len; - *pp = p; - return str; -} - -static int parse_section_header(SectionHeader *h, - const uint8_t **pp, const uint8_t *p_end) -{ - int val; - - val = get8(pp, p_end); - if (val < 0) - return -1; - h->tid = val; - *pp += 2; - val = get16(pp, p_end); - if (val < 0) - return -1; - h->id = val; - val = get8(pp, p_end); - if (val < 0) - return -1; - h->version = (val >> 1) & 0x1f; - val = get8(pp, p_end); - if (val < 0) - return -1; - h->sec_num = val; - val = get8(pp, p_end); - if (val < 0) - return -1; - h->last_sec_num = val; - return 0; -} - -typedef struct { - uint32_t stream_type; - enum AVMediaType codec_type; - enum AVCodecID codec_id; -} StreamType; - -static const StreamType ISO_types[] = { - { 0x01, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_MPEG2VIDEO }, - { 0x02, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_MPEG2VIDEO }, - { 0x03, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_MP3 }, - { 0x04, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_MP3 }, - { 0x0f, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AAC }, - { 0x10, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_MPEG4 }, - /* Makito encoder sets stream type 0x11 for AAC, - * so auto-detect LOAS/LATM instead of hardcoding it. */ -#if !CONFIG_LOAS_DEMUXER - { 0x11, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AAC_LATM }, /* LATM syntax */ -#endif - { 0x1b, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_H264 }, - { 0x42, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_CAVS }, - { 0xd1, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_DIRAC }, - { 0xea, AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_VC1 }, - { 0 }, -}; - -static const StreamType HDMV_types[] = { - { 0x80, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_PCM_BLURAY }, - { 0x81, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AC3 }, - { 0x82, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_DTS }, - { 0x83, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_TRUEHD }, - { 0x84, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_EAC3 }, - { 0x85, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_DTS }, /* DTS HD */ - { 0x86, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_DTS }, /* DTS HD MASTER*/ - { 0xa1, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_EAC3 }, /* E-AC3 Secondary Audio */ - { 0xa2, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_DTS }, /* DTS Express Secondary Audio */ - { 0x90, AVMEDIA_TYPE_SUBTITLE, AV_CODEC_ID_HDMV_PGS_SUBTITLE }, - { 0 }, -}; - -/* ATSC ? */ -static const StreamType MISC_types[] = { - { 0x81, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AC3 }, - { 0x8a, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_DTS }, - { 0 }, -}; - -static const StreamType REGD_types[] = { - { MKTAG('d','r','a','c'), AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_DIRAC }, - { MKTAG('A','C','-','3'), AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AC3 }, - { MKTAG('B','S','S','D'), AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_S302M }, - { MKTAG('D','T','S','1'), AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_DTS }, - { MKTAG('D','T','S','2'), AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_DTS }, - { MKTAG('D','T','S','3'), AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_DTS }, - { MKTAG('K','L','V','A'), AVMEDIA_TYPE_DATA, AV_CODEC_ID_SMPTE_KLV }, - { MKTAG('V','C','-','1'), AVMEDIA_TYPE_VIDEO, AV_CODEC_ID_VC1 }, - { 0 }, -}; - -/* descriptor present */ -static const StreamType DESC_types[] = { - { 0x6a, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_AC3 }, /* AC-3 descriptor */ - { 0x7a, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_EAC3 }, /* E-AC-3 descriptor */ - { 0x7b, AVMEDIA_TYPE_AUDIO, AV_CODEC_ID_DTS }, - { 0x56, AVMEDIA_TYPE_SUBTITLE, AV_CODEC_ID_DVB_TELETEXT }, - { 0x59, AVMEDIA_TYPE_SUBTITLE, AV_CODEC_ID_DVB_SUBTITLE }, /* subtitling descriptor */ - { 0 }, -}; - -static void mpegts_find_stream_type(AVStream *st, - uint32_t stream_type, const StreamType *types) -{ - if (avcodec_is_open(st->codec)) { - av_log(NULL, AV_LOG_DEBUG, "cannot set stream info, codec is open\n"); - return; - } - - for (; types->stream_type; types++) { - if (stream_type == types->stream_type) { - st->codec->codec_type = types->codec_type; - st->codec->codec_id = types->codec_id; - st->request_probe = 0; - return; - } - } -} - -static int mpegts_set_stream_info(AVStream *st, PESContext *pes, - uint32_t stream_type, uint32_t prog_reg_desc) -{ - int old_codec_type= st->codec->codec_type; - int old_codec_id = st->codec->codec_id; - - if (avcodec_is_open(st->codec)) { - av_log(pes->stream, AV_LOG_DEBUG, "cannot set stream info, codec is open\n"); - return 0; - } - - avpriv_set_pts_info(st, 33, 1, 90000); - st->priv_data = pes; - st->codec->codec_type = AVMEDIA_TYPE_DATA; - st->codec->codec_id = AV_CODEC_ID_NONE; - st->need_parsing = AVSTREAM_PARSE_FULL; - pes->st = st; - pes->stream_type = stream_type; - - av_log(pes->stream, AV_LOG_DEBUG, - "stream=%d stream_type=%x pid=%x prog_reg_desc=%.4s\n", - st->index, pes->stream_type, pes->pid, (char*)&prog_reg_desc); - - st->codec->codec_tag = pes->stream_type; - - mpegts_find_stream_type(st, pes->stream_type, ISO_types); - if ((prog_reg_desc == AV_RL32("HDMV") || - prog_reg_desc == AV_RL32("HDPR")) && - st->codec->codec_id == AV_CODEC_ID_NONE) { - mpegts_find_stream_type(st, pes->stream_type, HDMV_types); - if (pes->stream_type == 0x83) { - // HDMV TrueHD streams also contain an AC3 coded version of the - // audio track - add a second stream for this - AVStream *sub_st; - // priv_data cannot be shared between streams - PESContext *sub_pes = av_malloc(sizeof(*sub_pes)); - if (!sub_pes) - return AVERROR(ENOMEM); - memcpy(sub_pes, pes, sizeof(*sub_pes)); - - sub_st = avformat_new_stream(pes->stream, NULL); - if (!sub_st) { - av_free(sub_pes); - return AVERROR(ENOMEM); - } - - sub_st->id = pes->pid; - avpriv_set_pts_info(sub_st, 33, 1, 90000); - sub_st->priv_data = sub_pes; - sub_st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - sub_st->codec->codec_id = AV_CODEC_ID_AC3; - sub_st->need_parsing = AVSTREAM_PARSE_FULL; - sub_pes->sub_st = pes->sub_st = sub_st; - } - } - if (st->codec->codec_id == AV_CODEC_ID_NONE) - mpegts_find_stream_type(st, pes->stream_type, MISC_types); - if (st->codec->codec_id == AV_CODEC_ID_NONE){ - st->codec->codec_id = old_codec_id; - st->codec->codec_type= old_codec_type; - } - - return 0; -} - -static void new_pes_packet(PESContext *pes, AVPacket *pkt) -{ - av_init_packet(pkt); - - pkt->buf = pes->buffer; - pkt->data = pes->buffer->data; - pkt->size = pes->data_index; - - if(pes->total_size != MAX_PES_PAYLOAD && - pes->pes_header_size + pes->data_index != pes->total_size + PES_START_SIZE) { - av_log(pes->stream, AV_LOG_WARNING, "PES packet size mismatch\n"); - pes->flags |= AV_PKT_FLAG_CORRUPT; - } - memset(pkt->data+pkt->size, 0, FF_INPUT_BUFFER_PADDING_SIZE); - - // Separate out the AC3 substream from an HDMV combined TrueHD/AC3 PID - if (pes->sub_st && pes->stream_type == 0x83 && pes->extended_stream_id == 0x76) - pkt->stream_index = pes->sub_st->index; - else - pkt->stream_index = pes->st->index; - pkt->pts = pes->pts; - pkt->dts = pes->dts; - /* store position of first TS packet of this PES packet */ - pkt->pos = pes->ts_packet_pos; - pkt->flags = pes->flags; - - /* reset pts values */ - pes->pts = AV_NOPTS_VALUE; - pes->dts = AV_NOPTS_VALUE; - pes->buffer = NULL; - pes->data_index = 0; - pes->flags = 0; -} - -static uint64_t get_ts64(GetBitContext *gb, int bits) -{ - if (get_bits_left(gb) < bits) - return AV_NOPTS_VALUE; - return get_bits64(gb, bits); -} - -static int read_sl_header(PESContext *pes, SLConfigDescr *sl, const uint8_t *buf, int buf_size) -{ - GetBitContext gb; - int au_start_flag = 0, au_end_flag = 0, ocr_flag = 0, idle_flag = 0; - int padding_flag = 0, padding_bits = 0, inst_bitrate_flag = 0; - int dts_flag = -1, cts_flag = -1; - int64_t dts = AV_NOPTS_VALUE, cts = AV_NOPTS_VALUE; - - init_get_bits(&gb, buf, buf_size*8); - - if (sl->use_au_start) - au_start_flag = get_bits1(&gb); - if (sl->use_au_end) - au_end_flag = get_bits1(&gb); - if (!sl->use_au_start && !sl->use_au_end) - au_start_flag = au_end_flag = 1; - if (sl->ocr_len > 0) - ocr_flag = get_bits1(&gb); - if (sl->use_idle) - idle_flag = get_bits1(&gb); - if (sl->use_padding) - padding_flag = get_bits1(&gb); - if (padding_flag) - padding_bits = get_bits(&gb, 3); - - if (!idle_flag && (!padding_flag || padding_bits != 0)) { - if (sl->packet_seq_num_len) - skip_bits_long(&gb, sl->packet_seq_num_len); - if (sl->degr_prior_len) - if (get_bits1(&gb)) - skip_bits(&gb, sl->degr_prior_len); - if (ocr_flag) - skip_bits_long(&gb, sl->ocr_len); - if (au_start_flag) { - if (sl->use_rand_acc_pt) - get_bits1(&gb); - if (sl->au_seq_num_len > 0) - skip_bits_long(&gb, sl->au_seq_num_len); - if (sl->use_timestamps) { - dts_flag = get_bits1(&gb); - cts_flag = get_bits1(&gb); - } - } - if (sl->inst_bitrate_len) - inst_bitrate_flag = get_bits1(&gb); - if (dts_flag == 1) - dts = get_ts64(&gb, sl->timestamp_len); - if (cts_flag == 1) - cts = get_ts64(&gb, sl->timestamp_len); - if (sl->au_len > 0) - skip_bits_long(&gb, sl->au_len); - if (inst_bitrate_flag) - skip_bits_long(&gb, sl->inst_bitrate_len); - } - - if (dts != AV_NOPTS_VALUE) - pes->dts = dts; - if (cts != AV_NOPTS_VALUE) - pes->pts = cts; - - if (sl->timestamp_len && sl->timestamp_res) - avpriv_set_pts_info(pes->st, sl->timestamp_len, 1, sl->timestamp_res); - - return (get_bits_count(&gb) + 7) >> 3; -} - -/* return non zero if a packet could be constructed */ -static int mpegts_push_data(MpegTSFilter *filter, - const uint8_t *buf, int buf_size, int is_start, - int64_t pos) -{ - PESContext *pes = filter->u.pes_filter.opaque; - MpegTSContext *ts = pes->ts; - const uint8_t *p; - int len, code; - - if(!ts->pkt) - return 0; - - if (is_start) { - if (pes->state == MPEGTS_PAYLOAD && pes->data_index > 0) { - new_pes_packet(pes, ts->pkt); - ts->stop_parse = 1; - } - pes->state = MPEGTS_HEADER; - pes->data_index = 0; - pes->ts_packet_pos = pos; - } - p = buf; - while (buf_size > 0) { - switch(pes->state) { - case MPEGTS_HEADER: - len = PES_START_SIZE - pes->data_index; - if (len > buf_size) - len = buf_size; - memcpy(pes->header + pes->data_index, p, len); - pes->data_index += len; - p += len; - buf_size -= len; - if (pes->data_index == PES_START_SIZE) { - /* we got all the PES or section header. We can now - decide */ - if (pes->header[0] == 0x00 && pes->header[1] == 0x00 && - pes->header[2] == 0x01) { - /* it must be an mpeg2 PES stream */ - code = pes->header[3] | 0x100; - av_dlog(pes->stream, "pid=%x pes_code=%#x\n", pes->pid, code); - - if ((pes->st && pes->st->discard == AVDISCARD_ALL && - (!pes->sub_st || pes->sub_st->discard == AVDISCARD_ALL)) || - code == 0x1be) /* padding_stream */ - goto skip; - - /* stream not present in PMT */ - if (!pes->st) { - pes->st = avformat_new_stream(ts->stream, NULL); - if (!pes->st) - return AVERROR(ENOMEM); - pes->st->id = pes->pid; - mpegts_set_stream_info(pes->st, pes, 0, 0); - } - - pes->total_size = AV_RB16(pes->header + 4); - /* NOTE: a zero total size means the PES size is - unbounded */ - if (!pes->total_size) - pes->total_size = MAX_PES_PAYLOAD; - - /* allocate pes buffer */ - pes->buffer = av_buffer_alloc(pes->total_size + - FF_INPUT_BUFFER_PADDING_SIZE); - if (!pes->buffer) - return AVERROR(ENOMEM); - - if (code != 0x1bc && code != 0x1bf && /* program_stream_map, private_stream_2 */ - code != 0x1f0 && code != 0x1f1 && /* ECM, EMM */ - code != 0x1ff && code != 0x1f2 && /* program_stream_directory, DSMCC_stream */ - code != 0x1f8) { /* ITU-T Rec. H.222.1 type E stream */ - pes->state = MPEGTS_PESHEADER; - if (pes->st->codec->codec_id == AV_CODEC_ID_NONE && !pes->st->request_probe) { - av_dlog(pes->stream, "pid=%x stream_type=%x probing\n", - pes->pid, pes->stream_type); - pes->st->request_probe= 1; - } - } else { - pes->state = MPEGTS_PAYLOAD; - pes->data_index = 0; - } - } else { - /* otherwise, it should be a table */ - /* skip packet */ - skip: - pes->state = MPEGTS_SKIP; - continue; - } - } - break; - /**********************************************/ - /* PES packing parsing */ - case MPEGTS_PESHEADER: - len = PES_HEADER_SIZE - pes->data_index; - if (len < 0) - return -1; - if (len > buf_size) - len = buf_size; - memcpy(pes->header + pes->data_index, p, len); - pes->data_index += len; - p += len; - buf_size -= len; - if (pes->data_index == PES_HEADER_SIZE) { - pes->pes_header_size = pes->header[8] + 9; - pes->state = MPEGTS_PESHEADER_FILL; - } - break; - case MPEGTS_PESHEADER_FILL: - len = pes->pes_header_size - pes->data_index; - if (len < 0) - return -1; - if (len > buf_size) - len = buf_size; - memcpy(pes->header + pes->data_index, p, len); - pes->data_index += len; - p += len; - buf_size -= len; - if (pes->data_index == pes->pes_header_size) { - const uint8_t *r; - unsigned int flags, pes_ext, skip; - - flags = pes->header[7]; - r = pes->header + 9; - pes->pts = AV_NOPTS_VALUE; - pes->dts = AV_NOPTS_VALUE; - if ((flags & 0xc0) == 0x80) { - pes->dts = pes->pts = ff_parse_pes_pts(r); - r += 5; - } else if ((flags & 0xc0) == 0xc0) { - pes->pts = ff_parse_pes_pts(r); - r += 5; - pes->dts = ff_parse_pes_pts(r); - r += 5; - } - pes->extended_stream_id = -1; - if (flags & 0x01) { /* PES extension */ - pes_ext = *r++; - /* Skip PES private data, program packet sequence counter and P-STD buffer */ - skip = (pes_ext >> 4) & 0xb; - skip += skip & 0x9; - r += skip; - if ((pes_ext & 0x41) == 0x01 && - (r + 2) <= (pes->header + pes->pes_header_size)) { - /* PES extension 2 */ - if ((r[0] & 0x7f) > 0 && (r[1] & 0x80) == 0) - pes->extended_stream_id = r[1]; - } - } - - /* we got the full header. We parse it and get the payload */ - pes->state = MPEGTS_PAYLOAD; - pes->data_index = 0; - if (pes->stream_type == 0x12 && buf_size > 0) { - int sl_header_bytes = read_sl_header(pes, &pes->sl, p, buf_size); - pes->pes_header_size += sl_header_bytes; - p += sl_header_bytes; - buf_size -= sl_header_bytes; - } - } - break; - case MPEGTS_PAYLOAD: - if (buf_size > 0 && pes->buffer) { - if (pes->data_index > 0 && pes->data_index+buf_size > pes->total_size) { - new_pes_packet(pes, ts->pkt); - pes->total_size = MAX_PES_PAYLOAD; - pes->buffer = av_buffer_alloc(pes->total_size + FF_INPUT_BUFFER_PADDING_SIZE); - if (!pes->buffer) - return AVERROR(ENOMEM); - ts->stop_parse = 1; - } else if (pes->data_index == 0 && buf_size > pes->total_size) { - // pes packet size is < ts size packet and pes data is padded with 0xff - // not sure if this is legal in ts but see issue #2392 - buf_size = pes->total_size; - } - memcpy(pes->buffer->data + pes->data_index, p, buf_size); - pes->data_index += buf_size; - } - buf_size = 0; - /* emit complete packets with known packet size - * decreases demuxer delay for infrequent packets like subtitles from - * a couple of seconds to milliseconds for properly muxed files. - * total_size is the number of bytes following pes_packet_length - * in the pes header, i.e. not counting the first PES_START_SIZE bytes */ - if (!ts->stop_parse && pes->total_size < MAX_PES_PAYLOAD && - pes->pes_header_size + pes->data_index == pes->total_size + PES_START_SIZE) { - ts->stop_parse = 1; - new_pes_packet(pes, ts->pkt); - } - break; - case MPEGTS_SKIP: - buf_size = 0; - break; - } - } - - return 0; -} - -static PESContext *add_pes_stream(MpegTSContext *ts, int pid, int pcr_pid) -{ - MpegTSFilter *tss; - PESContext *pes; - - /* if no pid found, then add a pid context */ - pes = av_mallocz(sizeof(PESContext)); - if (!pes) - return 0; - pes->ts = ts; - pes->stream = ts->stream; - pes->pid = pid; - pes->pcr_pid = pcr_pid; - pes->state = MPEGTS_SKIP; - pes->pts = AV_NOPTS_VALUE; - pes->dts = AV_NOPTS_VALUE; - tss = mpegts_open_pes_filter(ts, pid, mpegts_push_data, pes); - if (!tss) { - av_free(pes); - return 0; - } - return pes; -} - -#define MAX_LEVEL 4 -typedef struct { - AVFormatContext *s; - AVIOContext pb; - Mp4Descr *descr; - Mp4Descr *active_descr; - int descr_count; - int max_descr_count; - int level; -} MP4DescrParseContext; - -static int init_MP4DescrParseContext( - MP4DescrParseContext *d, AVFormatContext *s, const uint8_t *buf, - unsigned size, Mp4Descr *descr, int max_descr_count) -{ - int ret; - if (size > (1<<30)) - return AVERROR_INVALIDDATA; - - if ((ret = ffio_init_context(&d->pb, (unsigned char*)buf, size, 0, - NULL, NULL, NULL, NULL)) < 0) - return ret; - - d->s = s; - d->level = 0; - d->descr_count = 0; - d->descr = descr; - d->active_descr = NULL; - d->max_descr_count = max_descr_count; - - return 0; -} - -static void update_offsets(AVIOContext *pb, int64_t *off, int *len) { - int64_t new_off = avio_tell(pb); - (*len) -= new_off - *off; - *off = new_off; -} - -static int parse_mp4_descr(MP4DescrParseContext *d, int64_t off, int len, - int target_tag); - -static int parse_mp4_descr_arr(MP4DescrParseContext *d, int64_t off, int len) -{ - while (len > 0) { - if (parse_mp4_descr(d, off, len, 0) < 0) - return -1; - update_offsets(&d->pb, &off, &len); - } - return 0; -} - -static int parse_MP4IODescrTag(MP4DescrParseContext *d, int64_t off, int len) -{ - avio_rb16(&d->pb); // ID - avio_r8(&d->pb); - avio_r8(&d->pb); - avio_r8(&d->pb); - avio_r8(&d->pb); - avio_r8(&d->pb); - update_offsets(&d->pb, &off, &len); - return parse_mp4_descr_arr(d, off, len); -} - -static int parse_MP4ODescrTag(MP4DescrParseContext *d, int64_t off, int len) -{ - int id_flags; - if (len < 2) - return 0; - id_flags = avio_rb16(&d->pb); - if (!(id_flags & 0x0020)) { //URL_Flag - update_offsets(&d->pb, &off, &len); - return parse_mp4_descr_arr(d, off, len); //ES_Descriptor[] - } else { - return 0; - } -} - -static int parse_MP4ESDescrTag(MP4DescrParseContext *d, int64_t off, int len) -{ - int es_id = 0; - if (d->descr_count >= d->max_descr_count) - return -1; - ff_mp4_parse_es_descr(&d->pb, &es_id); - d->active_descr = d->descr + (d->descr_count++); - - d->active_descr->es_id = es_id; - update_offsets(&d->pb, &off, &len); - parse_mp4_descr(d, off, len, MP4DecConfigDescrTag); - update_offsets(&d->pb, &off, &len); - if (len > 0) - parse_mp4_descr(d, off, len, MP4SLDescrTag); - d->active_descr = NULL; - return 0; -} - -static int parse_MP4DecConfigDescrTag(MP4DescrParseContext *d, int64_t off, int len) -{ - Mp4Descr *descr = d->active_descr; - if (!descr) - return -1; - d->active_descr->dec_config_descr = av_malloc(len); - if (!descr->dec_config_descr) - return AVERROR(ENOMEM); - descr->dec_config_descr_len = len; - avio_read(&d->pb, descr->dec_config_descr, len); - return 0; -} - -static int parse_MP4SLDescrTag(MP4DescrParseContext *d, int64_t off, int len) -{ - Mp4Descr *descr = d->active_descr; - int predefined; - if (!descr) - return -1; - - predefined = avio_r8(&d->pb); - if (!predefined) { - int lengths; - int flags = avio_r8(&d->pb); - descr->sl.use_au_start = !!(flags & 0x80); - descr->sl.use_au_end = !!(flags & 0x40); - descr->sl.use_rand_acc_pt = !!(flags & 0x20); - descr->sl.use_padding = !!(flags & 0x08); - descr->sl.use_timestamps = !!(flags & 0x04); - descr->sl.use_idle = !!(flags & 0x02); - descr->sl.timestamp_res = avio_rb32(&d->pb); - avio_rb32(&d->pb); - descr->sl.timestamp_len = avio_r8(&d->pb); - descr->sl.ocr_len = avio_r8(&d->pb); - descr->sl.au_len = avio_r8(&d->pb); - descr->sl.inst_bitrate_len = avio_r8(&d->pb); - lengths = avio_rb16(&d->pb); - descr->sl.degr_prior_len = lengths >> 12; - descr->sl.au_seq_num_len = (lengths >> 7) & 0x1f; - descr->sl.packet_seq_num_len = (lengths >> 2) & 0x1f; - } else { - avpriv_report_missing_feature(d->s, "Predefined SLConfigDescriptor"); - } - return 0; -} - -static int parse_mp4_descr(MP4DescrParseContext *d, int64_t off, int len, - int target_tag) { - int tag; - int len1 = ff_mp4_read_descr(d->s, &d->pb, &tag); - update_offsets(&d->pb, &off, &len); - if (len < 0 || len1 > len || len1 <= 0) { - av_log(d->s, AV_LOG_ERROR, "Tag %x length violation new length %d bytes remaining %d\n", tag, len1, len); - return -1; - } - - if (d->level++ >= MAX_LEVEL) { - av_log(d->s, AV_LOG_ERROR, "Maximum MP4 descriptor level exceeded\n"); - goto done; - } - - if (target_tag && tag != target_tag) { - av_log(d->s, AV_LOG_ERROR, "Found tag %x expected %x\n", tag, target_tag); - goto done; - } - - switch (tag) { - case MP4IODescrTag: - parse_MP4IODescrTag(d, off, len1); - break; - case MP4ODescrTag: - parse_MP4ODescrTag(d, off, len1); - break; - case MP4ESDescrTag: - parse_MP4ESDescrTag(d, off, len1); - break; - case MP4DecConfigDescrTag: - parse_MP4DecConfigDescrTag(d, off, len1); - break; - case MP4SLDescrTag: - parse_MP4SLDescrTag(d, off, len1); - break; - } - -done: - d->level--; - avio_seek(&d->pb, off + len1, SEEK_SET); - return 0; -} - -static int mp4_read_iods(AVFormatContext *s, const uint8_t *buf, unsigned size, - Mp4Descr *descr, int *descr_count, int max_descr_count) -{ - MP4DescrParseContext d; - if (init_MP4DescrParseContext(&d, s, buf, size, descr, max_descr_count) < 0) - return -1; - - parse_mp4_descr(&d, avio_tell(&d.pb), size, MP4IODescrTag); - - *descr_count = d.descr_count; - return 0; -} - -static int mp4_read_od(AVFormatContext *s, const uint8_t *buf, unsigned size, - Mp4Descr *descr, int *descr_count, int max_descr_count) -{ - MP4DescrParseContext d; - if (init_MP4DescrParseContext(&d, s, buf, size, descr, max_descr_count) < 0) - return -1; - - parse_mp4_descr_arr(&d, avio_tell(&d.pb), size); - - *descr_count = d.descr_count; - return 0; -} - -static void m4sl_cb(MpegTSFilter *filter, const uint8_t *section, int section_len) -{ - MpegTSContext *ts = filter->u.section_filter.opaque; - SectionHeader h; - const uint8_t *p, *p_end; - AVIOContext pb; - Mp4Descr mp4_descr[MAX_MP4_DESCR_COUNT] = {{ 0 }}; - int mp4_descr_count = 0; - int i, pid; - AVFormatContext *s = ts->stream; - - p_end = section + section_len - 4; - p = section; - if (parse_section_header(&h, &p, p_end) < 0) - return; - if (h.tid != M4OD_TID) - return; - - mp4_read_od(s, p, (unsigned)(p_end - p), mp4_descr, &mp4_descr_count, MAX_MP4_DESCR_COUNT); - - for (pid = 0; pid < NB_PID_MAX; pid++) { - if (!ts->pids[pid]) - continue; - for (i = 0; i < mp4_descr_count; i++) { - PESContext *pes; - AVStream *st; - if (ts->pids[pid]->es_id != mp4_descr[i].es_id) - continue; - if (!(ts->pids[pid] && ts->pids[pid]->type == MPEGTS_PES)) { - av_log(s, AV_LOG_ERROR, "pid %x is not PES\n", pid); - continue; - } - pes = ts->pids[pid]->u.pes_filter.opaque; - st = pes->st; - if (!st) { - continue; - } - - pes->sl = mp4_descr[i].sl; - - ffio_init_context(&pb, mp4_descr[i].dec_config_descr, - mp4_descr[i].dec_config_descr_len, 0, NULL, NULL, NULL, NULL); - ff_mp4_read_dec_config_descr(s, st, &pb); - if (st->codec->codec_id == AV_CODEC_ID_AAC && - st->codec->extradata_size > 0) - st->need_parsing = 0; - if (st->codec->codec_id == AV_CODEC_ID_H264 && - st->codec->extradata_size > 0) - st->need_parsing = 0; - - if (st->codec->codec_id <= AV_CODEC_ID_NONE) { - } else if (st->codec->codec_id < AV_CODEC_ID_FIRST_AUDIO) { - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - } else if (st->codec->codec_id < AV_CODEC_ID_FIRST_SUBTITLE) { - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - } else if (st->codec->codec_id < AV_CODEC_ID_FIRST_UNKNOWN) { - st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE; - } - } - } - for (i = 0; i < mp4_descr_count; i++) - av_free(mp4_descr[i].dec_config_descr); -} - -int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type, - const uint8_t **pp, const uint8_t *desc_list_end, - Mp4Descr *mp4_descr, int mp4_descr_count, int pid, - MpegTSContext *ts) -{ - const uint8_t *desc_end; - int desc_len, desc_tag, desc_es_id; - char language[252]; - int i; - - desc_tag = get8(pp, desc_list_end); - if (desc_tag < 0) - return -1; - desc_len = get8(pp, desc_list_end); - if (desc_len < 0) - return -1; - desc_end = *pp + desc_len; - if (desc_end > desc_list_end) - return -1; - - av_dlog(fc, "tag: 0x%02x len=%d\n", desc_tag, desc_len); - - if (st->codec->codec_id == AV_CODEC_ID_NONE && - stream_type == STREAM_TYPE_PRIVATE_DATA) - mpegts_find_stream_type(st, desc_tag, DESC_types); - - switch(desc_tag) { - case 0x1E: /* SL descriptor */ - desc_es_id = get16(pp, desc_end); - if (ts && ts->pids[pid]) - ts->pids[pid]->es_id = desc_es_id; - for (i = 0; i < mp4_descr_count; i++) - if (mp4_descr[i].dec_config_descr_len && - mp4_descr[i].es_id == desc_es_id) { - AVIOContext pb; - ffio_init_context(&pb, mp4_descr[i].dec_config_descr, - mp4_descr[i].dec_config_descr_len, 0, NULL, NULL, NULL, NULL); - ff_mp4_read_dec_config_descr(fc, st, &pb); - if (st->codec->codec_id == AV_CODEC_ID_AAC && - st->codec->extradata_size > 0) - st->need_parsing = 0; - if (st->codec->codec_id == AV_CODEC_ID_MPEG4SYSTEMS) - mpegts_open_section_filter(ts, pid, m4sl_cb, ts, 1); - } - break; - case 0x1F: /* FMC descriptor */ - get16(pp, desc_end); - if (mp4_descr_count > 0 && (st->codec->codec_id == AV_CODEC_ID_AAC_LATM || st->request_probe>0) && - mp4_descr->dec_config_descr_len && mp4_descr->es_id == pid) { - AVIOContext pb; - ffio_init_context(&pb, mp4_descr->dec_config_descr, - mp4_descr->dec_config_descr_len, 0, NULL, NULL, NULL, NULL); - ff_mp4_read_dec_config_descr(fc, st, &pb); - if (st->codec->codec_id == AV_CODEC_ID_AAC && - st->codec->extradata_size > 0){ - st->request_probe= st->need_parsing = 0; - st->codec->codec_type= AVMEDIA_TYPE_AUDIO; - } - } - break; - case 0x56: /* DVB teletext descriptor */ - language[0] = get8(pp, desc_end); - language[1] = get8(pp, desc_end); - language[2] = get8(pp, desc_end); - language[3] = 0; - av_dict_set(&st->metadata, "language", language, 0); - break; - case 0x59: /* subtitling descriptor */ - language[0] = get8(pp, desc_end); - language[1] = get8(pp, desc_end); - language[2] = get8(pp, desc_end); - language[3] = 0; - /* hearing impaired subtitles detection */ - switch(get8(pp, desc_end)) { - case 0x20: /* DVB subtitles (for the hard of hearing) with no monitor aspect ratio criticality */ - case 0x21: /* DVB subtitles (for the hard of hearing) for display on 4:3 aspect ratio monitor */ - case 0x22: /* DVB subtitles (for the hard of hearing) for display on 16:9 aspect ratio monitor */ - case 0x23: /* DVB subtitles (for the hard of hearing) for display on 2.21:1 aspect ratio monitor */ - case 0x24: /* DVB subtitles (for the hard of hearing) for display on a high definition monitor */ - case 0x25: /* DVB subtitles (for the hard of hearing) with plano-stereoscopic disparity for display on a high definition monitor */ - st->disposition |= AV_DISPOSITION_HEARING_IMPAIRED; - break; - } - if (st->codec->extradata) { - if (st->codec->extradata_size == 4 && memcmp(st->codec->extradata, *pp, 4)) - avpriv_request_sample(fc, "DVB sub with multiple IDs"); - } else { - st->codec->extradata = av_malloc(4 + FF_INPUT_BUFFER_PADDING_SIZE); - if (st->codec->extradata) { - st->codec->extradata_size = 4; - memcpy(st->codec->extradata, *pp, 4); - } - } - *pp += 4; - av_dict_set(&st->metadata, "language", language, 0); - break; - case 0x0a: /* ISO 639 language descriptor */ - for (i = 0; i + 4 <= desc_len; i += 4) { - language[i + 0] = get8(pp, desc_end); - language[i + 1] = get8(pp, desc_end); - language[i + 2] = get8(pp, desc_end); - language[i + 3] = ','; - switch (get8(pp, desc_end)) { - case 0x01: st->disposition |= AV_DISPOSITION_CLEAN_EFFECTS; break; - case 0x02: st->disposition |= AV_DISPOSITION_HEARING_IMPAIRED; break; - case 0x03: st->disposition |= AV_DISPOSITION_VISUAL_IMPAIRED; break; - } - } - if (i) { - language[i - 1] = 0; - av_dict_set(&st->metadata, "language", language, 0); - } - break; - case 0x05: /* registration descriptor */ - st->codec->codec_tag = bytestream_get_le32(pp); - av_dlog(fc, "reg_desc=%.4s\n", (char*)&st->codec->codec_tag); - if (st->codec->codec_id == AV_CODEC_ID_NONE) - mpegts_find_stream_type(st, st->codec->codec_tag, REGD_types); - break; - case 0x52: /* stream identifier descriptor */ - st->stream_identifier = 1 + get8(pp, desc_end); - break; - default: - break; - } - *pp = desc_end; - return 0; -} - -static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len) -{ - MpegTSContext *ts = filter->u.section_filter.opaque; - SectionHeader h1, *h = &h1; - PESContext *pes; - AVStream *st; - const uint8_t *p, *p_end, *desc_list_end; - int program_info_length, pcr_pid, pid, stream_type; - int desc_list_len; - uint32_t prog_reg_desc = 0; /* registration descriptor */ - - Mp4Descr mp4_descr[MAX_MP4_DESCR_COUNT] = {{ 0 }}; - int mp4_descr_count = 0; - int i; - - av_dlog(ts->stream, "PMT: len %i\n", section_len); - hex_dump_debug(ts->stream, section, section_len); - - p_end = section + section_len - 4; - p = section; - if (parse_section_header(h, &p, p_end) < 0) - return; - - av_dlog(ts->stream, "sid=0x%x sec_num=%d/%d\n", - h->id, h->sec_num, h->last_sec_num); - - if (h->tid != PMT_TID) - return; - - clear_program(ts, h->id); - pcr_pid = get16(&p, p_end); - if (pcr_pid < 0) - return; - pcr_pid &= 0x1fff; - add_pid_to_pmt(ts, h->id, pcr_pid); - set_pcr_pid(ts->stream, h->id, pcr_pid); - - av_dlog(ts->stream, "pcr_pid=0x%x\n", pcr_pid); - - program_info_length = get16(&p, p_end); - if (program_info_length < 0) - return; - program_info_length &= 0xfff; - while(program_info_length >= 2) { - uint8_t tag, len; - tag = get8(&p, p_end); - len = get8(&p, p_end); - - av_dlog(ts->stream, "program tag: 0x%02x len=%d\n", tag, len); - - if(len > program_info_length - 2) - //something else is broken, exit the program_descriptors_loop - break; - program_info_length -= len + 2; - if (tag == 0x1d) { // IOD descriptor - get8(&p, p_end); // scope - get8(&p, p_end); // label - len -= 2; - mp4_read_iods(ts->stream, p, len, mp4_descr + mp4_descr_count, - &mp4_descr_count, MAX_MP4_DESCR_COUNT); - } else if (tag == 0x05 && len >= 4) { // registration descriptor - prog_reg_desc = bytestream_get_le32(&p); - len -= 4; - } - p += len; - } - p += program_info_length; - if (p >= p_end) - goto out; - - // stop parsing after pmt, we found header - if (!ts->stream->nb_streams) - ts->stop_parse = 2; - - for(;;) { - st = 0; - pes = NULL; - stream_type = get8(&p, p_end); - if (stream_type < 0) - break; - pid = get16(&p, p_end); - if (pid < 0) - break; - pid &= 0x1fff; - if (pid == ts->current_pid) - break; - - /* now create stream */ - if (ts->pids[pid] && ts->pids[pid]->type == MPEGTS_PES) { - pes = ts->pids[pid]->u.pes_filter.opaque; - if (!pes->st) { - pes->st = avformat_new_stream(pes->stream, NULL); - if (!pes->st) - goto out; - pes->st->id = pes->pid; - } - st = pes->st; - } else if (stream_type != 0x13) { - if (ts->pids[pid]) mpegts_close_filter(ts, ts->pids[pid]); //wrongly added sdt filter probably - pes = add_pes_stream(ts, pid, pcr_pid); - if (pes) { - st = avformat_new_stream(pes->stream, NULL); - if (!st) - goto out; - st->id = pes->pid; - } - } else { - int idx = ff_find_stream_index(ts->stream, pid); - if (idx >= 0) { - st = ts->stream->streams[idx]; - } else { - st = avformat_new_stream(ts->stream, NULL); - if (!st) - goto out; - st->id = pid; - st->codec->codec_type = AVMEDIA_TYPE_DATA; - } - } - - if (!st) - goto out; - - if (pes && !pes->stream_type) - mpegts_set_stream_info(st, pes, stream_type, prog_reg_desc); - - add_pid_to_pmt(ts, h->id, pid); - - ff_program_add_stream_index(ts->stream, h->id, st->index); - - desc_list_len = get16(&p, p_end); - if (desc_list_len < 0) - break; - desc_list_len &= 0xfff; - desc_list_end = p + desc_list_len; - if (desc_list_end > p_end) - break; - for(;;) { - if (ff_parse_mpeg2_descriptor(ts->stream, st, stream_type, &p, desc_list_end, - mp4_descr, mp4_descr_count, pid, ts) < 0) - break; - - if (pes && prog_reg_desc == AV_RL32("HDMV") && stream_type == 0x83 && pes->sub_st) { - ff_program_add_stream_index(ts->stream, h->id, pes->sub_st->index); - pes->sub_st->codec->codec_tag = st->codec->codec_tag; - } - } - p = desc_list_end; - } - - out: - for (i = 0; i < mp4_descr_count; i++) - av_free(mp4_descr[i].dec_config_descr); -} - -static void pat_cb(MpegTSFilter *filter, const uint8_t *section, int section_len) -{ - MpegTSContext *ts = filter->u.section_filter.opaque; - SectionHeader h1, *h = &h1; - const uint8_t *p, *p_end; - int sid, pmt_pid; - AVProgram *program; - - av_dlog(ts->stream, "PAT:\n"); - hex_dump_debug(ts->stream, section, section_len); - - p_end = section + section_len - 4; - p = section; - if (parse_section_header(h, &p, p_end) < 0) - return; - if (h->tid != PAT_TID) - return; - - ts->stream->ts_id = h->id; - - clear_programs(ts); - for(;;) { - sid = get16(&p, p_end); - if (sid < 0) - break; - pmt_pid = get16(&p, p_end); - if (pmt_pid < 0) - break; - pmt_pid &= 0x1fff; - - if (pmt_pid == ts->current_pid) - break; - - av_dlog(ts->stream, "sid=0x%x pid=0x%x\n", sid, pmt_pid); - - if (sid == 0x0000) { - /* NIT info */ - } else { - program = av_new_program(ts->stream, sid); - program->program_num = sid; - program->pmt_pid = pmt_pid; - if (ts->pids[pmt_pid]) - mpegts_close_filter(ts, ts->pids[pmt_pid]); - mpegts_open_section_filter(ts, pmt_pid, pmt_cb, ts, 1); - add_pat_entry(ts, sid); - add_pid_to_pmt(ts, sid, 0); //add pat pid to program - add_pid_to_pmt(ts, sid, pmt_pid); - } - } - - if (sid < 0) { - int i,j; - for (j=0; jstream->nb_programs; j++) { - for (i=0; inb_prg; i++) - if (ts->prg[i].id == ts->stream->programs[j]->id) - break; - if (i==ts->nb_prg) - clear_avprogram(ts, ts->stream->programs[j]->id); - } - } -} - -static void sdt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len) -{ - MpegTSContext *ts = filter->u.section_filter.opaque; - SectionHeader h1, *h = &h1; - const uint8_t *p, *p_end, *desc_list_end, *desc_end; - int onid, val, sid, desc_list_len, desc_tag, desc_len, service_type; - char *name, *provider_name; - - av_dlog(ts->stream, "SDT:\n"); - hex_dump_debug(ts->stream, section, section_len); - - p_end = section + section_len - 4; - p = section; - if (parse_section_header(h, &p, p_end) < 0) - return; - if (h->tid != SDT_TID) - return; - onid = get16(&p, p_end); - if (onid < 0) - return; - val = get8(&p, p_end); - if (val < 0) - return; - for(;;) { - sid = get16(&p, p_end); - if (sid < 0) - break; - val = get8(&p, p_end); - if (val < 0) - break; - desc_list_len = get16(&p, p_end); - if (desc_list_len < 0) - break; - desc_list_len &= 0xfff; - desc_list_end = p + desc_list_len; - if (desc_list_end > p_end) - break; - for(;;) { - desc_tag = get8(&p, desc_list_end); - if (desc_tag < 0) - break; - desc_len = get8(&p, desc_list_end); - desc_end = p + desc_len; - if (desc_end > desc_list_end) - break; - - av_dlog(ts->stream, "tag: 0x%02x len=%d\n", - desc_tag, desc_len); - - switch(desc_tag) { - case 0x48: - service_type = get8(&p, p_end); - if (service_type < 0) - break; - provider_name = getstr8(&p, p_end); - if (!provider_name) - break; - name = getstr8(&p, p_end); - if (name) { - AVProgram *program = av_new_program(ts->stream, sid); - if(program) { - av_dict_set(&program->metadata, "service_name", name, 0); - av_dict_set(&program->metadata, "service_provider", provider_name, 0); - } - } - av_free(name); - av_free(provider_name); - break; - default: - break; - } - p = desc_end; - } - p = desc_list_end; - } -} - -/* handle one TS packet */ -static int handle_packet(MpegTSContext *ts, const uint8_t *packet) -{ - AVFormatContext *s = ts->stream; - MpegTSFilter *tss; - int len, pid, cc, expected_cc, cc_ok, afc, is_start, is_discontinuity, - has_adaptation, has_payload; - const uint8_t *p, *p_end; - int64_t pos; - - pid = AV_RB16(packet + 1) & 0x1fff; - if(pid && discard_pid(ts, pid)) - return 0; - is_start = packet[1] & 0x40; - tss = ts->pids[pid]; - if (ts->auto_guess && tss == NULL && is_start) { - add_pes_stream(ts, pid, -1); - tss = ts->pids[pid]; - } - if (!tss) - return 0; - ts->current_pid = pid; - - afc = (packet[3] >> 4) & 3; - if (afc == 0) /* reserved value */ - return 0; - has_adaptation = afc & 2; - has_payload = afc & 1; - is_discontinuity = has_adaptation - && packet[4] != 0 /* with length > 0 */ - && (packet[5] & 0x80); /* and discontinuity indicated */ - - /* continuity check (currently not used) */ - cc = (packet[3] & 0xf); - expected_cc = has_payload ? (tss->last_cc + 1) & 0x0f : tss->last_cc; - cc_ok = pid == 0x1FFF // null packet PID - || is_discontinuity - || tss->last_cc < 0 - || expected_cc == cc; - - tss->last_cc = cc; - if (!cc_ok) { - av_log(ts->stream, AV_LOG_DEBUG, - "Continuity check failed for pid %d expected %d got %d\n", - pid, expected_cc, cc); - if(tss->type == MPEGTS_PES) { - PESContext *pc = tss->u.pes_filter.opaque; - pc->flags |= AV_PKT_FLAG_CORRUPT; - } - } - - if (!has_payload) - return 0; - p = packet + 4; - if (has_adaptation) { - /* skip adaptation field */ - p += p[0] + 1; - } - /* if past the end of packet, ignore */ - p_end = packet + TS_PACKET_SIZE; - if (p >= p_end) - return 0; - - pos = avio_tell(ts->stream->pb); - ts->pos47= pos % ts->raw_packet_size; - - if (tss->type == MPEGTS_SECTION) { - if (is_start) { - /* pointer field present */ - len = *p++; - if (p + len > p_end) - return 0; - if (len && cc_ok) { - /* write remaining section bytes */ - write_section_data(s, tss, - p, len, 0); - /* check whether filter has been closed */ - if (!ts->pids[pid]) - return 0; - } - p += len; - if (p < p_end) { - write_section_data(s, tss, - p, p_end - p, 1); - } - } else { - if (cc_ok) { - write_section_data(s, tss, - p, p_end - p, 0); - } - } - } else { - int ret; - // Note: The position here points actually behind the current packet. - if ((ret = tss->u.pes_filter.pes_cb(tss, p, p_end - p, is_start, - pos - ts->raw_packet_size)) < 0) - return ret; - } - - return 0; -} - -/* XXX: try to find a better synchro over several packets (use - get_packet_size() ?) */ -static int mpegts_resync(AVFormatContext *s) -{ - AVIOContext *pb = s->pb; - int c, i; - - for(i = 0;i < MAX_RESYNC_SIZE; i++) { - c = avio_r8(pb); - if (url_feof(pb)) - return -1; - if (c == 0x47) { - avio_seek(pb, -1, SEEK_CUR); - return 0; - } - } - av_log(s, AV_LOG_ERROR, "max resync size reached, could not find sync byte\n"); - /* no sync found */ - return -1; -} - -/* return -1 if error or EOF. Return 0 if OK. */ -static int read_packet(AVFormatContext *s, uint8_t *buf, int raw_packet_size) -{ - AVIOContext *pb = s->pb; - int skip, len; - - for(;;) { - len = avio_read(pb, buf, TS_PACKET_SIZE); - if (len != TS_PACKET_SIZE) - return len < 0 ? len : AVERROR_EOF; - /* check packet sync byte */ - if (buf[0] != 0x47) { - /* find a new packet start */ - avio_seek(pb, -TS_PACKET_SIZE, SEEK_CUR); - if (mpegts_resync(s) < 0) - return AVERROR(EAGAIN); - else - continue; - } else { - skip = raw_packet_size - TS_PACKET_SIZE; - if (skip > 0) - avio_skip(pb, skip); - break; - } - } - return 0; -} - -static int handle_packets(MpegTSContext *ts, int nb_packets) -{ - AVFormatContext *s = ts->stream; - uint8_t packet[TS_PACKET_SIZE + FF_INPUT_BUFFER_PADDING_SIZE]; - int packet_num, ret = 0; - - if (avio_tell(s->pb) != ts->last_pos) { - int i; - av_dlog(ts->stream, "Skipping after seek\n"); - /* seek detected, flush pes buffer */ - for (i = 0; i < NB_PID_MAX; i++) { - if (ts->pids[i]) { - if (ts->pids[i]->type == MPEGTS_PES) { - PESContext *pes = ts->pids[i]->u.pes_filter.opaque; - av_buffer_unref(&pes->buffer); - pes->data_index = 0; - pes->state = MPEGTS_SKIP; /* skip until pes header */ - } - ts->pids[i]->last_cc = -1; - } - } - } - - ts->stop_parse = 0; - packet_num = 0; - memset(packet + TS_PACKET_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE); - for(;;) { - packet_num++; - if (nb_packets != 0 && packet_num >= nb_packets || - ts->stop_parse > 1) { - ret = AVERROR(EAGAIN); - break; - } - if (ts->stop_parse > 0) - break; - - ret = read_packet(s, packet, ts->raw_packet_size); - if (ret != 0) - break; - ret = handle_packet(ts, packet); - if (ret != 0) - break; - } - ts->last_pos = avio_tell(s->pb); - return ret; -} - -static int mpegts_probe(AVProbeData *p) -{ - const int size= p->buf_size; - int maxscore=0; - int sumscore=0; - int i; - int check_count= size / TS_FEC_PACKET_SIZE; -#define CHECK_COUNT 10 -#define CHECK_BLOCK 100 - - if (check_count < CHECK_COUNT) - return -1; - - for (i=0; ibuf + TS_PACKET_SIZE *i, TS_PACKET_SIZE *left, TS_PACKET_SIZE , NULL); - int dvhs_score= analyze(p->buf + TS_DVHS_PACKET_SIZE*i, TS_DVHS_PACKET_SIZE*left, TS_DVHS_PACKET_SIZE, NULL); - int fec_score = analyze(p->buf + TS_FEC_PACKET_SIZE *i, TS_FEC_PACKET_SIZE *left, TS_FEC_PACKET_SIZE , NULL); - score = FFMAX3(score, dvhs_score, fec_score); - sumscore += score; - maxscore = FFMAX(maxscore, score); - } - - sumscore = sumscore*CHECK_COUNT/check_count; - maxscore = maxscore*CHECK_COUNT/CHECK_BLOCK; - - av_dlog(0, "TS score: %d %d\n", sumscore, maxscore); - - if (sumscore > 6) return AVPROBE_SCORE_MAX + sumscore - CHECK_COUNT; - else if (maxscore > 6) return AVPROBE_SCORE_MAX/2 + sumscore - CHECK_COUNT; - else return -1; -} - -/* return the 90kHz PCR and the extension for the 27MHz PCR. return - (-1) if not available */ -static int parse_pcr(int64_t *ppcr_high, int *ppcr_low, - const uint8_t *packet) -{ - int afc, len, flags; - const uint8_t *p; - unsigned int v; - - afc = (packet[3] >> 4) & 3; - if (afc <= 1) - return -1; - p = packet + 4; - len = p[0]; - p++; - if (len == 0) - return -1; - flags = *p++; - len--; - if (!(flags & 0x10)) - return -1; - if (len < 6) - return -1; - v = AV_RB32(p); - *ppcr_high = ((int64_t)v << 1) | (p[4] >> 7); - *ppcr_low = ((p[4] & 1) << 8) | p[5]; - return 0; -} - -static int mpegts_read_header(AVFormatContext *s) -{ - MpegTSContext *ts = s->priv_data; - AVIOContext *pb = s->pb; - uint8_t buf[8*1024]={0}; - int len; - int64_t pos; - - /* read the first 8192 bytes to get packet size */ - pos = avio_tell(pb); - len = avio_read(pb, buf, sizeof(buf)); - ts->raw_packet_size = get_packet_size(buf, len); - if (ts->raw_packet_size <= 0) { - av_log(s, AV_LOG_WARNING, "Could not detect TS packet size, defaulting to non-FEC/DVHS\n"); - ts->raw_packet_size = TS_PACKET_SIZE; - } - ts->stream = s; - ts->auto_guess = 0; - - if (s->iformat == &ff_mpegts_demuxer) { - /* normal demux */ - - /* first do a scan to get all the services */ - /* NOTE: We attempt to seek on non-seekable files as well, as the - * probe buffer usually is big enough. Only warn if the seek failed - * on files where the seek should work. */ - if (avio_seek(pb, pos, SEEK_SET) < 0) - av_log(s, pb->seekable ? AV_LOG_ERROR : AV_LOG_INFO, "Unable to seek back to the start\n"); - - mpegts_open_section_filter(ts, SDT_PID, sdt_cb, ts, 1); - - mpegts_open_section_filter(ts, PAT_PID, pat_cb, ts, 1); - - handle_packets(ts, s->probesize / ts->raw_packet_size); - /* if could not find service, enable auto_guess */ - - ts->auto_guess = 1; - - av_dlog(ts->stream, "tuning done\n"); - - s->ctx_flags |= AVFMTCTX_NOHEADER; - } else { - AVStream *st; - int pcr_pid, pid, nb_packets, nb_pcrs, ret, pcr_l; - int64_t pcrs[2], pcr_h; - int packet_count[2]; - uint8_t packet[TS_PACKET_SIZE]; - - /* only read packets */ - - st = avformat_new_stream(s, NULL); - if (!st) - goto fail; - avpriv_set_pts_info(st, 60, 1, 27000000); - st->codec->codec_type = AVMEDIA_TYPE_DATA; - st->codec->codec_id = AV_CODEC_ID_MPEG2TS; - - /* we iterate until we find two PCRs to estimate the bitrate */ - pcr_pid = -1; - nb_pcrs = 0; - nb_packets = 0; - for(;;) { - ret = read_packet(s, packet, ts->raw_packet_size); - if (ret < 0) - return -1; - pid = AV_RB16(packet + 1) & 0x1fff; - if ((pcr_pid == -1 || pcr_pid == pid) && - parse_pcr(&pcr_h, &pcr_l, packet) == 0) { - pcr_pid = pid; - packet_count[nb_pcrs] = nb_packets; - pcrs[nb_pcrs] = pcr_h * 300 + pcr_l; - nb_pcrs++; - if (nb_pcrs >= 2) - break; - } - nb_packets++; - } - - /* NOTE1: the bitrate is computed without the FEC */ - /* NOTE2: it is only the bitrate of the start of the stream */ - ts->pcr_incr = (pcrs[1] - pcrs[0]) / (packet_count[1] - packet_count[0]); - ts->cur_pcr = pcrs[0] - ts->pcr_incr * packet_count[0]; - s->bit_rate = (TS_PACKET_SIZE * 8) * 27e6 / ts->pcr_incr; - st->codec->bit_rate = s->bit_rate; - st->start_time = ts->cur_pcr; - av_dlog(ts->stream, "start=%0.3f pcr=%0.3f incr=%d\n", - st->start_time / 1000000.0, pcrs[0] / 27e6, ts->pcr_incr); - } - - avio_seek(pb, pos, SEEK_SET); - return 0; - fail: - return -1; -} - -#define MAX_PACKET_READAHEAD ((128 * 1024) / 188) - -static int mpegts_raw_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - MpegTSContext *ts = s->priv_data; - int ret, i; - int64_t pcr_h, next_pcr_h, pos; - int pcr_l, next_pcr_l; - uint8_t pcr_buf[12]; - - if (av_new_packet(pkt, TS_PACKET_SIZE) < 0) - return AVERROR(ENOMEM); - pkt->pos= avio_tell(s->pb); - ret = read_packet(s, pkt->data, ts->raw_packet_size); - if (ret < 0) { - av_free_packet(pkt); - return ret; - } - if (ts->mpeg2ts_compute_pcr) { - /* compute exact PCR for each packet */ - if (parse_pcr(&pcr_h, &pcr_l, pkt->data) == 0) { - /* we read the next PCR (XXX: optimize it by using a bigger buffer */ - pos = avio_tell(s->pb); - for(i = 0; i < MAX_PACKET_READAHEAD; i++) { - avio_seek(s->pb, pos + i * ts->raw_packet_size, SEEK_SET); - avio_read(s->pb, pcr_buf, 12); - if (parse_pcr(&next_pcr_h, &next_pcr_l, pcr_buf) == 0) { - /* XXX: not precise enough */ - ts->pcr_incr = ((next_pcr_h - pcr_h) * 300 + (next_pcr_l - pcr_l)) / - (i + 1); - break; - } - } - avio_seek(s->pb, pos, SEEK_SET); - /* no next PCR found: we use previous increment */ - ts->cur_pcr = pcr_h * 300 + pcr_l; - } - pkt->pts = ts->cur_pcr; - pkt->duration = ts->pcr_incr; - ts->cur_pcr += ts->pcr_incr; - } - pkt->stream_index = 0; - return 0; -} - -static int mpegts_read_packet(AVFormatContext *s, - AVPacket *pkt) -{ - MpegTSContext *ts = s->priv_data; - int ret, i; - - pkt->size = -1; - ts->pkt = pkt; - ret = handle_packets(ts, 0); - if (ret < 0) { - av_free_packet(ts->pkt); - /* flush pes data left */ - for (i = 0; i < NB_PID_MAX; i++) { - if (ts->pids[i] && ts->pids[i]->type == MPEGTS_PES) { - PESContext *pes = ts->pids[i]->u.pes_filter.opaque; - if (pes->state == MPEGTS_PAYLOAD && pes->data_index > 0) { - new_pes_packet(pes, pkt); - pes->state = MPEGTS_SKIP; - ret = 0; - break; - } - } - } - } - - if (!ret && pkt->size < 0) - ret = AVERROR(EINTR); - return ret; -} - -static void mpegts_free(MpegTSContext *ts) -{ - int i; - - clear_programs(ts); - - for(i=0;ipids[i]) mpegts_close_filter(ts, ts->pids[i]); -} - -static int mpegts_read_close(AVFormatContext *s) -{ - MpegTSContext *ts = s->priv_data; - mpegts_free(ts); - return 0; -} - -static av_unused int64_t mpegts_get_pcr(AVFormatContext *s, int stream_index, - int64_t *ppos, int64_t pos_limit) -{ - MpegTSContext *ts = s->priv_data; - int64_t pos, timestamp; - uint8_t buf[TS_PACKET_SIZE]; - int pcr_l, pcr_pid = ((PESContext*)s->streams[stream_index]->priv_data)->pcr_pid; - pos = ((*ppos + ts->raw_packet_size - 1 - ts->pos47) / ts->raw_packet_size) * ts->raw_packet_size + ts->pos47; - while(pos < pos_limit) { - if (avio_seek(s->pb, pos, SEEK_SET) < 0) - return AV_NOPTS_VALUE; - if (avio_read(s->pb, buf, TS_PACKET_SIZE) != TS_PACKET_SIZE) - return AV_NOPTS_VALUE; - if (buf[0] != 0x47) { - if (mpegts_resync(s) < 0) - return AV_NOPTS_VALUE; - pos = avio_tell(s->pb); - continue; - } - if ((pcr_pid < 0 || (AV_RB16(buf + 1) & 0x1fff) == pcr_pid) && - parse_pcr(×tamp, &pcr_l, buf) == 0) { - *ppos = pos; - return timestamp; - } - pos += ts->raw_packet_size; - } - - return AV_NOPTS_VALUE; -} - -static int64_t mpegts_get_dts(AVFormatContext *s, int stream_index, - int64_t *ppos, int64_t pos_limit) -{ - MpegTSContext *ts = s->priv_data; - int64_t pos; - pos = ((*ppos + ts->raw_packet_size - 1 - ts->pos47) / ts->raw_packet_size) * ts->raw_packet_size + ts->pos47; - ff_read_frame_flush(s); - if (avio_seek(s->pb, pos, SEEK_SET) < 0) - return AV_NOPTS_VALUE; - while(pos < pos_limit) { - int ret; - AVPacket pkt; - av_init_packet(&pkt); - ret= av_read_frame(s, &pkt); - if(ret < 0) - return AV_NOPTS_VALUE; - av_free_packet(&pkt); - if(pkt.dts != AV_NOPTS_VALUE && pkt.pos >= 0){ - ff_reduce_index(s, pkt.stream_index); - av_add_index_entry(s->streams[pkt.stream_index], pkt.pos, pkt.dts, 0, 0, AVINDEX_KEYFRAME /* FIXME keyframe? */); - if(pkt.stream_index == stream_index){ - *ppos= pkt.pos; - return pkt.dts; - } - } - pos = pkt.pos; - } - - return AV_NOPTS_VALUE; -} - -/**************************************************************/ -/* parsing functions - called from other demuxers such as RTP */ - -MpegTSContext *ff_mpegts_parse_open(AVFormatContext *s) -{ - MpegTSContext *ts; - - ts = av_mallocz(sizeof(MpegTSContext)); - if (!ts) - return NULL; - /* no stream case, currently used by RTP */ - ts->raw_packet_size = TS_PACKET_SIZE; - ts->stream = s; - ts->auto_guess = 1; - mpegts_open_section_filter(ts, SDT_PID, sdt_cb, ts, 1); - mpegts_open_section_filter(ts, PAT_PID, pat_cb, ts, 1); - - return ts; -} - -/* return the consumed length if a packet was output, or -1 if no - packet is output */ -int ff_mpegts_parse_packet(MpegTSContext *ts, AVPacket *pkt, - const uint8_t *buf, int len) -{ - int len1; - - len1 = len; - ts->pkt = pkt; - for(;;) { - ts->stop_parse = 0; - if (len < TS_PACKET_SIZE) - return -1; - if (buf[0] != 0x47) { - buf++; - len--; - } else { - handle_packet(ts, buf); - buf += TS_PACKET_SIZE; - len -= TS_PACKET_SIZE; - if (ts->stop_parse == 1) - break; - } - } - return len1 - len; -} - -void ff_mpegts_parse_close(MpegTSContext *ts) -{ - mpegts_free(ts); - av_free(ts); -} - -AVInputFormat ff_mpegts_demuxer = { - .name = "mpegts", - .long_name = NULL_IF_CONFIG_SMALL("MPEG-TS (MPEG-2 Transport Stream)"), - .priv_data_size = sizeof(MpegTSContext), - .read_probe = mpegts_probe, - .read_header = mpegts_read_header, - .read_packet = mpegts_read_packet, - .read_close = mpegts_read_close, - .read_timestamp = mpegts_get_dts, - .flags = AVFMT_SHOW_IDS | AVFMT_TS_DISCONT, -}; - -AVInputFormat ff_mpegtsraw_demuxer = { - .name = "mpegtsraw", - .long_name = NULL_IF_CONFIG_SMALL("raw MPEG-TS (MPEG-2 Transport Stream)"), - .priv_data_size = sizeof(MpegTSContext), - .read_header = mpegts_read_header, - .read_packet = mpegts_raw_read_packet, - .read_close = mpegts_read_close, - .read_timestamp = mpegts_get_dts, - .flags = AVFMT_SHOW_IDS | AVFMT_TS_DISCONT, - .priv_class = &mpegtsraw_class, -}; diff --git a/ffmpeg1/libavformat/mpegts.h b/ffmpeg1/libavformat/mpegts.h deleted file mode 100644 index 269c23b..0000000 --- a/ffmpeg1/libavformat/mpegts.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * MPEG2 transport stream defines - * Copyright (c) 2003 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 AVFORMAT_MPEGTS_H -#define AVFORMAT_MPEGTS_H - -#include "avformat.h" - -#define TS_FEC_PACKET_SIZE 204 -#define TS_DVHS_PACKET_SIZE 192 -#define TS_PACKET_SIZE 188 -#define TS_MAX_PACKET_SIZE 204 - -#define NB_PID_MAX 8192 -#define MAX_SECTION_SIZE 4096 - -/* pids */ -#define PAT_PID 0x0000 -#define SDT_PID 0x0011 - -/* table ids */ -#define PAT_TID 0x00 -#define PMT_TID 0x02 -#define M4OD_TID 0x05 -#define SDT_TID 0x42 - -#define STREAM_TYPE_VIDEO_MPEG1 0x01 -#define STREAM_TYPE_VIDEO_MPEG2 0x02 -#define STREAM_TYPE_AUDIO_MPEG1 0x03 -#define STREAM_TYPE_AUDIO_MPEG2 0x04 -#define STREAM_TYPE_PRIVATE_SECTION 0x05 -#define STREAM_TYPE_PRIVATE_DATA 0x06 -#define STREAM_TYPE_AUDIO_AAC 0x0f -#define STREAM_TYPE_AUDIO_AAC_LATM 0x11 -#define STREAM_TYPE_VIDEO_MPEG4 0x10 -#define STREAM_TYPE_VIDEO_H264 0x1b -#define STREAM_TYPE_VIDEO_CAVS 0x42 -#define STREAM_TYPE_VIDEO_VC1 0xea -#define STREAM_TYPE_VIDEO_DIRAC 0xd1 - -#define STREAM_TYPE_AUDIO_AC3 0x81 -#define STREAM_TYPE_AUDIO_DTS 0x8a - -typedef struct MpegTSContext MpegTSContext; - -MpegTSContext *ff_mpegts_parse_open(AVFormatContext *s); -int ff_mpegts_parse_packet(MpegTSContext *ts, AVPacket *pkt, - const uint8_t *buf, int len); -void ff_mpegts_parse_close(MpegTSContext *ts); - -typedef struct SLConfigDescr { - int use_au_start; - int use_au_end; - int use_rand_acc_pt; - int use_padding; - int use_timestamps; - int use_idle; - int timestamp_res; - int timestamp_len; - int ocr_len; - int au_len; - int inst_bitrate_len; - int degr_prior_len; - int au_seq_num_len; - int packet_seq_num_len; -} SLConfigDescr; - -typedef struct Mp4Descr { - int es_id; - int dec_config_descr_len; - uint8_t *dec_config_descr; - SLConfigDescr sl; -} Mp4Descr; - -/** - * Parse an MPEG-2 descriptor - * @param[in] fc Format context (used for logging only) - * @param st Stream - * @param stream_type STREAM_TYPE_xxx - * @param pp Descriptor buffer pointer - * @param desc_list_end End of buffer - * @return <0 to stop processing - */ -int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type, - const uint8_t **pp, const uint8_t *desc_list_end, - Mp4Descr *mp4_descr, int mp4_descr_count, int pid, - MpegTSContext *ts); - -#endif /* AVFORMAT_MPEGTS_H */ diff --git a/ffmpeg1/libavformat/mpegtsenc.c b/ffmpeg1/libavformat/mpegtsenc.c deleted file mode 100644 index 7016774..0000000 --- a/ffmpeg1/libavformat/mpegtsenc.c +++ /dev/null @@ -1,1268 +0,0 @@ -/* - * MPEG2 transport stream (aka DVB) muxer - * Copyright (c) 2003 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 "libavutil/bswap.h" -#include "libavutil/crc.h" -#include "libavutil/dict.h" -#include "libavutil/mathematics.h" -#include "libavutil/opt.h" -#include "libavutil/avassert.h" -#include "libavcodec/mpegvideo.h" -#include "avformat.h" -#include "internal.h" -#include "mpegts.h" - -#define PCR_TIME_BASE 27000000 - -/* write DVB SI sections */ - -/*********************************************/ -/* mpegts section writer */ - -typedef struct MpegTSSection { - int pid; - int cc; - void (*write_packet)(struct MpegTSSection *s, const uint8_t *packet); - void *opaque; -} MpegTSSection; - -typedef struct MpegTSService { - MpegTSSection pmt; /* MPEG2 pmt table context */ - int sid; /* service ID */ - char *name; - char *provider_name; - int pcr_pid; - int pcr_packet_count; - int pcr_packet_period; -} MpegTSService; - -typedef struct MpegTSWrite { - const AVClass *av_class; - MpegTSSection pat; /* MPEG2 pat table */ - MpegTSSection sdt; /* MPEG2 sdt table context */ - MpegTSService **services; - int sdt_packet_count; - int sdt_packet_period; - int pat_packet_count; - int pat_packet_period; - int nb_services; - int onid; - int tsid; - int64_t first_pcr; - int mux_rate; ///< set to 1 when VBR - int pes_payload_size; - - int transport_stream_id; - int original_network_id; - int service_id; - - int pmt_start_pid; - int start_pid; - int m2ts_mode; - - int reemit_pat_pmt; // backward compatibility - -#define MPEGTS_FLAG_REEMIT_PAT_PMT 0x01 -#define MPEGTS_FLAG_AAC_LATM 0x02 - int flags; - int copyts; -} MpegTSWrite; - -/* a PES packet header is generated every DEFAULT_PES_HEADER_FREQ packets */ -#define DEFAULT_PES_HEADER_FREQ 16 -#define DEFAULT_PES_PAYLOAD_SIZE ((DEFAULT_PES_HEADER_FREQ - 1) * 184 + 170) - -static const AVOption options[] = { - { "mpegts_transport_stream_id", "Set transport_stream_id field.", - offsetof(MpegTSWrite, transport_stream_id), AV_OPT_TYPE_INT, {.i64 = 0x0001 }, 0x0001, 0xffff, AV_OPT_FLAG_ENCODING_PARAM}, - { "mpegts_original_network_id", "Set original_network_id field.", - offsetof(MpegTSWrite, original_network_id), AV_OPT_TYPE_INT, {.i64 = 0x0001 }, 0x0001, 0xffff, AV_OPT_FLAG_ENCODING_PARAM}, - { "mpegts_service_id", "Set service_id field.", - offsetof(MpegTSWrite, service_id), AV_OPT_TYPE_INT, {.i64 = 0x0001 }, 0x0001, 0xffff, AV_OPT_FLAG_ENCODING_PARAM}, - { "mpegts_pmt_start_pid", "Set the first pid of the PMT.", - offsetof(MpegTSWrite, pmt_start_pid), AV_OPT_TYPE_INT, {.i64 = 0x1000 }, 0x0010, 0x1f00, AV_OPT_FLAG_ENCODING_PARAM}, - { "mpegts_start_pid", "Set the first pid.", - offsetof(MpegTSWrite, start_pid), AV_OPT_TYPE_INT, {.i64 = 0x0100 }, 0x0100, 0x0f00, AV_OPT_FLAG_ENCODING_PARAM}, - {"mpegts_m2ts_mode", "Enable m2ts mode.", - offsetof(MpegTSWrite, m2ts_mode), AV_OPT_TYPE_INT, {.i64 = -1 }, - -1,1, AV_OPT_FLAG_ENCODING_PARAM}, - { "muxrate", NULL, offsetof(MpegTSWrite, mux_rate), AV_OPT_TYPE_INT, {.i64 = 1}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM}, - { "pes_payload_size", "Minimum PES packet payload in bytes", - offsetof(MpegTSWrite, pes_payload_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT_PES_PAYLOAD_SIZE}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM}, - { "mpegts_flags", "MPEG-TS muxing flags", offsetof(MpegTSWrite, flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, 0, INT_MAX, - AV_OPT_FLAG_ENCODING_PARAM, "mpegts_flags" }, - { "resend_headers", "Reemit PAT/PMT before writing the next packet", - 0, AV_OPT_TYPE_CONST, {.i64 = MPEGTS_FLAG_REEMIT_PAT_PMT}, 0, INT_MAX, - AV_OPT_FLAG_ENCODING_PARAM, "mpegts_flags"}, - { "latm", "Use LATM packetization for AAC", - 0, AV_OPT_TYPE_CONST, {.i64 = MPEGTS_FLAG_AAC_LATM}, 0, INT_MAX, - AV_OPT_FLAG_ENCODING_PARAM, "mpegts_flags"}, - // backward compatibility - { "resend_headers", "Reemit PAT/PMT before writing the next packet", - offsetof(MpegTSWrite, reemit_pat_pmt), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM}, - { "mpegts_copyts", "dont offset dts/pts", - offsetof(MpegTSWrite, copyts), AV_OPT_TYPE_INT, {.i64=-1}, -1, 1, AV_OPT_FLAG_ENCODING_PARAM}, - { NULL }, -}; - -static const AVClass mpegts_muxer_class = { - .class_name = "MPEGTS muxer", - .item_name = av_default_item_name, - .option = options, - .version = LIBAVUTIL_VERSION_INT, -}; - -/* NOTE: 4 bytes must be left at the end for the crc32 */ -static void mpegts_write_section(MpegTSSection *s, uint8_t *buf, int len) -{ - unsigned int crc; - unsigned char packet[TS_PACKET_SIZE]; - const unsigned char *buf_ptr; - unsigned char *q; - int first, b, len1, left; - - crc = av_bswap32(av_crc(av_crc_get_table(AV_CRC_32_IEEE), -1, buf, len - 4)); - buf[len - 4] = (crc >> 24) & 0xff; - buf[len - 3] = (crc >> 16) & 0xff; - buf[len - 2] = (crc >> 8) & 0xff; - buf[len - 1] = (crc) & 0xff; - - /* send each packet */ - buf_ptr = buf; - while (len > 0) { - first = (buf == buf_ptr); - q = packet; - *q++ = 0x47; - b = (s->pid >> 8); - if (first) - b |= 0x40; - *q++ = b; - *q++ = s->pid; - s->cc = (s->cc + 1) & 0xf; - *q++ = 0x10 | s->cc; - if (first) - *q++ = 0; /* 0 offset */ - len1 = TS_PACKET_SIZE - (q - packet); - if (len1 > len) - len1 = len; - memcpy(q, buf_ptr, len1); - q += len1; - /* add known padding data */ - left = TS_PACKET_SIZE - (q - packet); - if (left > 0) - memset(q, 0xff, left); - - s->write_packet(s, packet); - - buf_ptr += len1; - len -= len1; - } -} - -static inline void put16(uint8_t **q_ptr, int val) -{ - uint8_t *q; - q = *q_ptr; - *q++ = val >> 8; - *q++ = val; - *q_ptr = q; -} - -static int mpegts_write_section1(MpegTSSection *s, int tid, int id, - int version, int sec_num, int last_sec_num, - uint8_t *buf, int len) -{ - uint8_t section[1024], *q; - unsigned int tot_len; - /* reserved_future_use field must be set to 1 for SDT */ - unsigned int flags = tid == SDT_TID ? 0xf000 : 0xb000; - - tot_len = 3 + 5 + len + 4; - /* check if not too big */ - if (tot_len > 1024) - return AVERROR_INVALIDDATA; - - q = section; - *q++ = tid; - put16(&q, flags | (len + 5 + 4)); /* 5 byte header + 4 byte CRC */ - put16(&q, id); - *q++ = 0xc1 | (version << 1); /* current_next_indicator = 1 */ - *q++ = sec_num; - *q++ = last_sec_num; - memcpy(q, buf, len); - - mpegts_write_section(s, section, tot_len); - return 0; -} - -/*********************************************/ -/* mpegts writer */ - -#define DEFAULT_PROVIDER_NAME "FFmpeg" -#define DEFAULT_SERVICE_NAME "Service01" - -/* we retransmit the SI info at this rate */ -#define SDT_RETRANS_TIME 500 -#define PAT_RETRANS_TIME 100 -#define PCR_RETRANS_TIME 20 - -typedef struct MpegTSWriteStream { - struct MpegTSService *service; - int pid; /* stream associated pid */ - int cc; - int payload_size; - int first_pts_check; ///< first pts check needed - int prev_payload_key; - int64_t payload_pts; - int64_t payload_dts; - int payload_flags; - uint8_t *payload; - AVFormatContext *amux; -} MpegTSWriteStream; - -static void mpegts_write_pat(AVFormatContext *s) -{ - MpegTSWrite *ts = s->priv_data; - MpegTSService *service; - uint8_t data[1012], *q; - int i; - - q = data; - for(i = 0; i < ts->nb_services; i++) { - service = ts->services[i]; - put16(&q, service->sid); - put16(&q, 0xe000 | service->pmt.pid); - } - mpegts_write_section1(&ts->pat, PAT_TID, ts->tsid, 0, 0, 0, - data, q - data); -} - -static void mpegts_write_pmt(AVFormatContext *s, MpegTSService *service) -{ - MpegTSWrite *ts = s->priv_data; - uint8_t data[1012], *q, *desc_length_ptr, *program_info_length_ptr; - int val, stream_type, i; - - q = data; - put16(&q, 0xe000 | service->pcr_pid); - - program_info_length_ptr = q; - q += 2; /* patched after */ - - /* put program info here */ - - val = 0xf000 | (q - program_info_length_ptr - 2); - program_info_length_ptr[0] = val >> 8; - program_info_length_ptr[1] = val; - - for(i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - MpegTSWriteStream *ts_st = st->priv_data; - AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL,0); - switch(st->codec->codec_id) { - case AV_CODEC_ID_MPEG1VIDEO: - case AV_CODEC_ID_MPEG2VIDEO: - stream_type = STREAM_TYPE_VIDEO_MPEG2; - break; - case AV_CODEC_ID_MPEG4: - stream_type = STREAM_TYPE_VIDEO_MPEG4; - break; - case AV_CODEC_ID_H264: - stream_type = STREAM_TYPE_VIDEO_H264; - break; - case AV_CODEC_ID_CAVS: - stream_type = STREAM_TYPE_VIDEO_CAVS; - break; - case AV_CODEC_ID_DIRAC: - stream_type = STREAM_TYPE_VIDEO_DIRAC; - break; - case AV_CODEC_ID_MP2: - case AV_CODEC_ID_MP3: - stream_type = STREAM_TYPE_AUDIO_MPEG1; - break; - case AV_CODEC_ID_AAC: - stream_type = (ts->flags & MPEGTS_FLAG_AAC_LATM) ? STREAM_TYPE_AUDIO_AAC_LATM : STREAM_TYPE_AUDIO_AAC; - break; - case AV_CODEC_ID_AAC_LATM: - stream_type = STREAM_TYPE_AUDIO_AAC_LATM; - break; - case AV_CODEC_ID_AC3: - stream_type = STREAM_TYPE_AUDIO_AC3; - break; - default: - stream_type = STREAM_TYPE_PRIVATE_DATA; - break; - } - *q++ = stream_type; - put16(&q, 0xe000 | ts_st->pid); - desc_length_ptr = q; - q += 2; /* patched after */ - - /* write optional descriptors here */ - switch(st->codec->codec_type) { - case AVMEDIA_TYPE_AUDIO: - if(st->codec->codec_id==AV_CODEC_ID_EAC3){ - *q++=0x7a; // EAC3 descriptor see A038 DVB SI - *q++=1; // 1 byte, all flags sets to 0 - *q++=0; // omit all fields... - } - if(st->codec->codec_id==AV_CODEC_ID_S302M){ - *q++ = 0x05; /* MPEG-2 registration descriptor*/ - *q++ = 4; - *q++ = 'B'; - *q++ = 'S'; - *q++ = 'S'; - *q++ = 'D'; - } - - if (lang) { - char *p; - char *next = lang->value; - uint8_t *len_ptr; - - *q++ = 0x0a; /* ISO 639 language descriptor */ - len_ptr = q++; - *len_ptr = 0; - - for (p = lang->value; next && *len_ptr < 255 / 4 * 4; p = next + 1) { - next = strchr(p, ','); - if (strlen(p) != 3 && (!next || next != p + 3)) - continue; /* not a 3-letter code */ - - *q++ = *p++; - *q++ = *p++; - *q++ = *p++; - - if (st->disposition & AV_DISPOSITION_CLEAN_EFFECTS) - *q++ = 0x01; - else if (st->disposition & AV_DISPOSITION_HEARING_IMPAIRED) - *q++ = 0x02; - else if (st->disposition & AV_DISPOSITION_VISUAL_IMPAIRED) - *q++ = 0x03; - else - *q++ = 0; /* undefined type */ - - *len_ptr += 4; - } - - if (*len_ptr == 0) - q -= 2; /* no language codes were written */ - } - break; - case AVMEDIA_TYPE_SUBTITLE: - { - const char *language; - language = lang && strlen(lang->value)==3 ? lang->value : "eng"; - *q++ = 0x59; - *q++ = 8; - *q++ = language[0]; - *q++ = language[1]; - *q++ = language[2]; - *q++ = 0x10; /* normal subtitles (0x20 = if hearing pb) */ - if(st->codec->extradata_size == 4) { - memcpy(q, st->codec->extradata, 4); - q += 4; - } else { - put16(&q, 1); /* page id */ - put16(&q, 1); /* ancillary page id */ - } - } - break; - case AVMEDIA_TYPE_VIDEO: - if (stream_type == STREAM_TYPE_VIDEO_DIRAC) { - *q++ = 0x05; /*MPEG-2 registration descriptor*/ - *q++ = 4; - *q++ = 'd'; - *q++ = 'r'; - *q++ = 'a'; - *q++ = 'c'; - } - break; - } - - val = 0xf000 | (q - desc_length_ptr - 2); - desc_length_ptr[0] = val >> 8; - desc_length_ptr[1] = val; - } - mpegts_write_section1(&service->pmt, PMT_TID, service->sid, 0, 0, 0, - data, q - data); -} - -/* NOTE: str == NULL is accepted for an empty string */ -static void putstr8(uint8_t **q_ptr, const char *str) -{ - uint8_t *q; - int len; - - q = *q_ptr; - if (!str) - len = 0; - else - len = strlen(str); - *q++ = len; - memcpy(q, str, len); - q += len; - *q_ptr = q; -} - -static void mpegts_write_sdt(AVFormatContext *s) -{ - MpegTSWrite *ts = s->priv_data; - MpegTSService *service; - uint8_t data[1012], *q, *desc_list_len_ptr, *desc_len_ptr; - int i, running_status, free_ca_mode, val; - - q = data; - put16(&q, ts->onid); - *q++ = 0xff; - for(i = 0; i < ts->nb_services; i++) { - service = ts->services[i]; - put16(&q, service->sid); - *q++ = 0xfc | 0x00; /* currently no EIT info */ - desc_list_len_ptr = q; - q += 2; - running_status = 4; /* running */ - free_ca_mode = 0; - - /* write only one descriptor for the service name and provider */ - *q++ = 0x48; - desc_len_ptr = q; - q++; - *q++ = 0x01; /* digital television service */ - putstr8(&q, service->provider_name); - putstr8(&q, service->name); - desc_len_ptr[0] = q - desc_len_ptr - 1; - - /* fill descriptor length */ - val = (running_status << 13) | (free_ca_mode << 12) | - (q - desc_list_len_ptr - 2); - desc_list_len_ptr[0] = val >> 8; - desc_list_len_ptr[1] = val; - } - mpegts_write_section1(&ts->sdt, SDT_TID, ts->tsid, 0, 0, 0, - data, q - data); -} - -static MpegTSService *mpegts_add_service(MpegTSWrite *ts, - int sid, - const char *provider_name, - const char *name) -{ - MpegTSService *service; - - service = av_mallocz(sizeof(MpegTSService)); - if (!service) - return NULL; - service->pmt.pid = ts->pmt_start_pid + ts->nb_services; - service->sid = sid; - service->provider_name = av_strdup(provider_name); - service->name = av_strdup(name); - service->pcr_pid = 0x1fff; - dynarray_add(&ts->services, &ts->nb_services, service); - return service; -} - -static int64_t get_pcr(const MpegTSWrite *ts, AVIOContext *pb) -{ - return av_rescale(avio_tell(pb) + 11, 8 * PCR_TIME_BASE, ts->mux_rate) + - ts->first_pcr; -} - -static void mpegts_prefix_m2ts_header(AVFormatContext *s) -{ - MpegTSWrite *ts = s->priv_data; - if (ts->m2ts_mode) { - int64_t pcr = get_pcr(s->priv_data, s->pb); - uint32_t tp_extra_header = pcr % 0x3fffffff; - tp_extra_header = AV_RB32(&tp_extra_header); - avio_write(s->pb, (unsigned char *) &tp_extra_header, - sizeof(tp_extra_header)); - } -} - -static void section_write_packet(MpegTSSection *s, const uint8_t *packet) -{ - AVFormatContext *ctx = s->opaque; - mpegts_prefix_m2ts_header(ctx); - avio_write(ctx->pb, packet, TS_PACKET_SIZE); -} - -static int mpegts_write_header(AVFormatContext *s) -{ - MpegTSWrite *ts = s->priv_data; - MpegTSWriteStream *ts_st; - MpegTSService *service; - AVStream *st, *pcr_st = NULL; - AVDictionaryEntry *title, *provider; - int i, j; - const char *service_name; - const char *provider_name; - int *pids; - int ret; - - if (s->max_delay < 0) /* Not set by the caller */ - s->max_delay = 0; - - // round up to a whole number of TS packets - ts->pes_payload_size = (ts->pes_payload_size + 14 + 183) / 184 * 184 - 14; - - ts->tsid = ts->transport_stream_id; - ts->onid = ts->original_network_id; - /* allocate a single DVB service */ - title = av_dict_get(s->metadata, "service_name", NULL, 0); - if (!title) - title = av_dict_get(s->metadata, "title", NULL, 0); - service_name = title ? title->value : DEFAULT_SERVICE_NAME; - provider = av_dict_get(s->metadata, "service_provider", NULL, 0); - provider_name = provider ? provider->value : DEFAULT_PROVIDER_NAME; - service = mpegts_add_service(ts, ts->service_id, provider_name, service_name); - service->pmt.write_packet = section_write_packet; - service->pmt.opaque = s; - service->pmt.cc = 15; - - ts->pat.pid = PAT_PID; - ts->pat.cc = 15; // Initialize at 15 so that it wraps and be equal to 0 for the first packet we write - ts->pat.write_packet = section_write_packet; - ts->pat.opaque = s; - - ts->sdt.pid = SDT_PID; - ts->sdt.cc = 15; - ts->sdt.write_packet = section_write_packet; - ts->sdt.opaque = s; - - pids = av_malloc(s->nb_streams * sizeof(*pids)); - if (!pids) - return AVERROR(ENOMEM); - - /* assign pids to each stream */ - for(i = 0;i < s->nb_streams; i++) { - st = s->streams[i]; - avpriv_set_pts_info(st, 33, 1, 90000); - ts_st = av_mallocz(sizeof(MpegTSWriteStream)); - if (!ts_st) { - ret = AVERROR(ENOMEM); - goto fail; - } - st->priv_data = ts_st; - ts_st->payload = av_mallocz(ts->pes_payload_size); - if (!ts_st->payload) { - ret = AVERROR(ENOMEM); - goto fail; - } - ts_st->service = service; - /* MPEG pid values < 16 are reserved. Applications which set st->id in - * this range are assigned a calculated pid. */ - if (st->id < 16) { - ts_st->pid = ts->start_pid + i; - } else if (st->id < 0x1FFF) { - ts_st->pid = st->id; - } else { - av_log(s, AV_LOG_ERROR, "Invalid stream id %d, must be less than 8191\n", st->id); - ret = AVERROR(EINVAL); - goto fail; - } - if (ts_st->pid == service->pmt.pid) { - av_log(s, AV_LOG_ERROR, "Duplicate stream id %d\n", ts_st->pid); - ret = AVERROR(EINVAL); - goto fail; - } - for (j = 0; j < i; j++) - if (pids[j] == ts_st->pid) { - av_log(s, AV_LOG_ERROR, "Duplicate stream id %d\n", ts_st->pid); - ret = AVERROR(EINVAL); - goto fail; - } - pids[i] = ts_st->pid; - ts_st->payload_pts = AV_NOPTS_VALUE; - ts_st->payload_dts = AV_NOPTS_VALUE; - ts_st->first_pts_check = 1; - ts_st->cc = 15; - /* update PCR pid by using the first video stream */ - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && - service->pcr_pid == 0x1fff) { - service->pcr_pid = ts_st->pid; - pcr_st = st; - } - if (st->codec->codec_id == AV_CODEC_ID_AAC && - st->codec->extradata_size > 0) - { - AVStream *ast; - ts_st->amux = avformat_alloc_context(); - if (!ts_st->amux) { - ret = AVERROR(ENOMEM); - goto fail; - } - ts_st->amux->oformat = av_guess_format((ts->flags & MPEGTS_FLAG_AAC_LATM) ? "latm" : "adts", NULL, NULL); - if (!ts_st->amux->oformat) { - ret = AVERROR(EINVAL); - goto fail; - } - ast = avformat_new_stream(ts_st->amux, NULL); - ret = avcodec_copy_context(ast->codec, st->codec); - if (ret != 0) - goto fail; - ret = avformat_write_header(ts_st->amux, NULL); - if (ret < 0) - goto fail; - } - } - - av_free(pids); - - /* if no video stream, use the first stream as PCR */ - if (service->pcr_pid == 0x1fff && s->nb_streams > 0) { - pcr_st = s->streams[0]; - ts_st = pcr_st->priv_data; - service->pcr_pid = ts_st->pid; - } - - if (ts->mux_rate > 1) { - service->pcr_packet_period = (ts->mux_rate * PCR_RETRANS_TIME) / - (TS_PACKET_SIZE * 8 * 1000); - ts->sdt_packet_period = (ts->mux_rate * SDT_RETRANS_TIME) / - (TS_PACKET_SIZE * 8 * 1000); - ts->pat_packet_period = (ts->mux_rate * PAT_RETRANS_TIME) / - (TS_PACKET_SIZE * 8 * 1000); - - if(ts->copyts < 1) - ts->first_pcr = av_rescale(s->max_delay, PCR_TIME_BASE, AV_TIME_BASE); - } else { - /* Arbitrary values, PAT/PMT will also be written on video key frames */ - ts->sdt_packet_period = 200; - ts->pat_packet_period = 40; - if (pcr_st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - if (!pcr_st->codec->frame_size) { - av_log(s, AV_LOG_WARNING, "frame size not set\n"); - service->pcr_packet_period = - pcr_st->codec->sample_rate/(10*512); - } else { - service->pcr_packet_period = - pcr_st->codec->sample_rate/(10*pcr_st->codec->frame_size); - } - } else { - // max delta PCR 0.1s - service->pcr_packet_period = - pcr_st->codec->time_base.den/(10*pcr_st->codec->time_base.num); - } - if(!service->pcr_packet_period) - service->pcr_packet_period = 1; - } - - // output a PCR as soon as possible - service->pcr_packet_count = service->pcr_packet_period; - ts->pat_packet_count = ts->pat_packet_period-1; - ts->sdt_packet_count = ts->sdt_packet_period-1; - - if (ts->mux_rate == 1) - av_log(s, AV_LOG_VERBOSE, "muxrate VBR, "); - else - av_log(s, AV_LOG_VERBOSE, "muxrate %d, ", ts->mux_rate); - av_log(s, AV_LOG_VERBOSE, "pcr every %d pkts, " - "sdt every %d, pat/pmt every %d pkts\n", - service->pcr_packet_period, - ts->sdt_packet_period, ts->pat_packet_period); - - if (ts->m2ts_mode == -1) { - if (av_match_ext(s->filename, "m2ts")) { - ts->m2ts_mode = 1; - } else { - ts->m2ts_mode = 0; - } - } - - avio_flush(s->pb); - - return 0; - - fail: - av_free(pids); - for(i = 0;i < s->nb_streams; i++) { - MpegTSWriteStream *ts_st; - st = s->streams[i]; - ts_st = st->priv_data; - if (ts_st) { - av_freep(&ts_st->payload); - if (ts_st->amux) { - avformat_free_context(ts_st->amux); - ts_st->amux = NULL; - } - } - av_freep(&st->priv_data); - } - return ret; -} - -/* send SDT, PAT and PMT tables regulary */ -static void retransmit_si_info(AVFormatContext *s, int force_pat) -{ - MpegTSWrite *ts = s->priv_data; - int i; - - if (++ts->sdt_packet_count == ts->sdt_packet_period) { - ts->sdt_packet_count = 0; - mpegts_write_sdt(s); - } - if (++ts->pat_packet_count == ts->pat_packet_period || force_pat) { - ts->pat_packet_count = 0; - mpegts_write_pat(s); - for(i = 0; i < ts->nb_services; i++) { - mpegts_write_pmt(s, ts->services[i]); - } - } -} - -static int write_pcr_bits(uint8_t *buf, int64_t pcr) -{ - int64_t pcr_low = pcr % 300, pcr_high = pcr / 300; - - *buf++ = pcr_high >> 25; - *buf++ = pcr_high >> 17; - *buf++ = pcr_high >> 9; - *buf++ = pcr_high >> 1; - *buf++ = pcr_high << 7 | pcr_low >> 8 | 0x7e; - *buf++ = pcr_low; - - return 6; -} - -/* Write a single null transport stream packet */ -static void mpegts_insert_null_packet(AVFormatContext *s) -{ - uint8_t *q; - uint8_t buf[TS_PACKET_SIZE]; - - q = buf; - *q++ = 0x47; - *q++ = 0x00 | 0x1f; - *q++ = 0xff; - *q++ = 0x10; - memset(q, 0x0FF, TS_PACKET_SIZE - (q - buf)); - mpegts_prefix_m2ts_header(s); - avio_write(s->pb, buf, TS_PACKET_SIZE); -} - -/* Write a single transport stream packet with a PCR and no payload */ -static void mpegts_insert_pcr_only(AVFormatContext *s, AVStream *st) -{ - MpegTSWrite *ts = s->priv_data; - MpegTSWriteStream *ts_st = st->priv_data; - uint8_t *q; - uint8_t buf[TS_PACKET_SIZE]; - - q = buf; - *q++ = 0x47; - *q++ = ts_st->pid >> 8; - *q++ = ts_st->pid; - *q++ = 0x20 | ts_st->cc; /* Adaptation only */ - /* Continuity Count field does not increment (see 13818-1 section 2.4.3.3) */ - *q++ = TS_PACKET_SIZE - 5; /* Adaptation Field Length */ - *q++ = 0x10; /* Adaptation flags: PCR present */ - - /* PCR coded into 6 bytes */ - q += write_pcr_bits(q, get_pcr(ts, s->pb)); - - /* stuffing bytes */ - memset(q, 0xFF, TS_PACKET_SIZE - (q - buf)); - mpegts_prefix_m2ts_header(s); - avio_write(s->pb, buf, TS_PACKET_SIZE); -} - -static void write_pts(uint8_t *q, int fourbits, int64_t pts) -{ - int val; - - val = fourbits << 4 | (((pts >> 30) & 0x07) << 1) | 1; - *q++ = val; - val = (((pts >> 15) & 0x7fff) << 1) | 1; - *q++ = val >> 8; - *q++ = val; - val = (((pts) & 0x7fff) << 1) | 1; - *q++ = val >> 8; - *q++ = val; -} - -/* Set an adaptation field flag in an MPEG-TS packet*/ -static void set_af_flag(uint8_t *pkt, int flag) -{ - // expect at least one flag to set - av_assert0(flag); - - if ((pkt[3] & 0x20) == 0) { - // no AF yet, set adaptation field flag - pkt[3] |= 0x20; - // 1 byte length, no flags - pkt[4] = 1; - pkt[5] = 0; - } - pkt[5] |= flag; -} - -/* Extend the adaptation field by size bytes */ -static void extend_af(uint8_t *pkt, int size) -{ - // expect already existing adaptation field - av_assert0(pkt[3] & 0x20); - pkt[4] += size; -} - -/* Get a pointer to MPEG-TS payload (right after TS packet header) */ -static uint8_t *get_ts_payload_start(uint8_t *pkt) -{ - if (pkt[3] & 0x20) - return pkt + 5 + pkt[4]; - else - return pkt + 4; -} - -/* Add a pes header to the front of payload, and segment into an integer number of - * ts packets. The final ts packet is padded using an over-sized adaptation header - * to exactly fill the last ts packet. - * NOTE: 'payload' contains a complete PES payload. - */ -static void mpegts_write_pes(AVFormatContext *s, AVStream *st, - const uint8_t *payload, int payload_size, - int64_t pts, int64_t dts, int key) -{ - MpegTSWriteStream *ts_st = st->priv_data; - MpegTSWrite *ts = s->priv_data; - uint8_t buf[TS_PACKET_SIZE]; - uint8_t *q; - int val, is_start, len, header_len, write_pcr, private_code, flags; - int afc_len, stuffing_len; - int64_t pcr = -1; /* avoid warning */ - int64_t delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE); - int force_pat = st->codec->codec_type == AVMEDIA_TYPE_VIDEO && key && !ts_st->prev_payload_key; - - is_start = 1; - while (payload_size > 0) { - retransmit_si_info(s, force_pat); - force_pat = 0; - - write_pcr = 0; - if (ts_st->pid == ts_st->service->pcr_pid) { - if (ts->mux_rate > 1 || is_start) // VBR pcr period is based on frames - ts_st->service->pcr_packet_count++; - if (ts_st->service->pcr_packet_count >= - ts_st->service->pcr_packet_period) { - ts_st->service->pcr_packet_count = 0; - write_pcr = 1; - } - } - - if (ts->mux_rate > 1 && dts != AV_NOPTS_VALUE && - (dts - get_pcr(ts, s->pb)/300) > delay) { - /* pcr insert gets priority over null packet insert */ - if (write_pcr) - mpegts_insert_pcr_only(s, st); - else - mpegts_insert_null_packet(s); - continue; /* recalculate write_pcr and possibly retransmit si_info */ - } - - /* prepare packet header */ - q = buf; - *q++ = 0x47; - val = (ts_st->pid >> 8); - if (is_start) - val |= 0x40; - *q++ = val; - *q++ = ts_st->pid; - ts_st->cc = (ts_st->cc + 1) & 0xf; - *q++ = 0x10 | ts_st->cc; // payload indicator + CC - if (key && is_start && pts != AV_NOPTS_VALUE) { - // set Random Access for key frames - if (ts_st->pid == ts_st->service->pcr_pid) - write_pcr = 1; - set_af_flag(buf, 0x40); - q = get_ts_payload_start(buf); - } - if (write_pcr) { - set_af_flag(buf, 0x10); - q = get_ts_payload_start(buf); - // add 11, pcr references the last byte of program clock reference base - if (ts->mux_rate > 1) - pcr = get_pcr(ts, s->pb); - else - pcr = (dts - delay)*300; - if (dts != AV_NOPTS_VALUE && dts < pcr / 300) - av_log(s, AV_LOG_WARNING, "dts < pcr, TS is invalid\n"); - extend_af(buf, write_pcr_bits(q, pcr)); - q = get_ts_payload_start(buf); - } - if (is_start) { - int pes_extension = 0; - /* write PES header */ - *q++ = 0x00; - *q++ = 0x00; - *q++ = 0x01; - private_code = 0; - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { - if (st->codec->codec_id == AV_CODEC_ID_DIRAC) { - *q++ = 0xfd; - } else - *q++ = 0xe0; - } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && - (st->codec->codec_id == AV_CODEC_ID_MP2 || - st->codec->codec_id == AV_CODEC_ID_MP3 || - st->codec->codec_id == AV_CODEC_ID_AAC)) { - *q++ = 0xc0; - } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && - st->codec->codec_id == AV_CODEC_ID_AC3 && - ts->m2ts_mode) { - *q++ = 0xfd; - } else { - *q++ = 0xbd; - if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) { - private_code = 0x20; - } - } - header_len = 0; - flags = 0; - if (pts != AV_NOPTS_VALUE) { - header_len += 5; - flags |= 0x80; - } - if (dts != AV_NOPTS_VALUE && pts != AV_NOPTS_VALUE && dts != pts) { - header_len += 5; - flags |= 0x40; - } - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && - st->codec->codec_id == AV_CODEC_ID_DIRAC) { - /* set PES_extension_flag */ - pes_extension = 1; - flags |= 0x01; - - /* - * One byte for PES2 extension flag + - * one byte for extension length + - * one byte for extension id - */ - header_len += 3; - } - /* for Blu-ray AC3 Audio the PES Extension flag should be as follow - * otherwise it will not play sound on blu-ray - */ - if (ts->m2ts_mode && - st->codec->codec_type == AVMEDIA_TYPE_AUDIO && - st->codec->codec_id == AV_CODEC_ID_AC3) { - /* set PES_extension_flag */ - pes_extension = 1; - flags |= 0x01; - header_len += 3; - } - len = payload_size + header_len + 3; - if (private_code != 0) - len++; - if (len > 0xffff) - len = 0; - *q++ = len >> 8; - *q++ = len; - val = 0x80; - /* data alignment indicator is required for subtitle data */ - if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) - val |= 0x04; - *q++ = val; - *q++ = flags; - *q++ = header_len; - if (pts != AV_NOPTS_VALUE) { - write_pts(q, flags >> 6, pts); - q += 5; - } - if (dts != AV_NOPTS_VALUE && pts != AV_NOPTS_VALUE && dts != pts) { - write_pts(q, 1, dts); - q += 5; - } - if (pes_extension && st->codec->codec_id == AV_CODEC_ID_DIRAC) { - flags = 0x01; /* set PES_extension_flag_2 */ - *q++ = flags; - *q++ = 0x80 | 0x01; /* marker bit + extension length */ - /* - * Set the stream id extension flag bit to 0 and - * write the extended stream id - */ - *q++ = 0x00 | 0x60; - } - /* For Blu-ray AC3 Audio Setting extended flags */ - if (ts->m2ts_mode && - pes_extension && - st->codec->codec_id == AV_CODEC_ID_AC3) { - flags = 0x01; /* set PES_extension_flag_2 */ - *q++ = flags; - *q++ = 0x80 | 0x01; /* marker bit + extension length */ - *q++ = 0x00 | 0x71; /* for AC3 Audio (specifically on blue-rays) */ - } - - - if (private_code != 0) - *q++ = private_code; - is_start = 0; - } - /* header size */ - header_len = q - buf; - /* data len */ - len = TS_PACKET_SIZE - header_len; - if (len > payload_size) - len = payload_size; - stuffing_len = TS_PACKET_SIZE - header_len - len; - if (stuffing_len > 0) { - /* add stuffing with AFC */ - if (buf[3] & 0x20) { - /* stuffing already present: increase its size */ - afc_len = buf[4] + 1; - memmove(buf + 4 + afc_len + stuffing_len, - buf + 4 + afc_len, - header_len - (4 + afc_len)); - buf[4] += stuffing_len; - memset(buf + 4 + afc_len, 0xff, stuffing_len); - } else { - /* add stuffing */ - memmove(buf + 4 + stuffing_len, buf + 4, header_len - 4); - buf[3] |= 0x20; - buf[4] = stuffing_len - 1; - if (stuffing_len >= 2) { - buf[5] = 0x00; - memset(buf + 6, 0xff, stuffing_len - 2); - } - } - } - memcpy(buf + TS_PACKET_SIZE - len, payload, len); - payload += len; - payload_size -= len; - mpegts_prefix_m2ts_header(s); - avio_write(s->pb, buf, TS_PACKET_SIZE); - } - avio_flush(s->pb); - ts_st->prev_payload_key = key; -} - -static int mpegts_write_packet_internal(AVFormatContext *s, AVPacket *pkt) -{ - AVStream *st = s->streams[pkt->stream_index]; - int size = pkt->size; - uint8_t *buf= pkt->data; - uint8_t *data= NULL; - MpegTSWrite *ts = s->priv_data; - MpegTSWriteStream *ts_st = st->priv_data; - const int64_t delay = av_rescale(s->max_delay, 90000, AV_TIME_BASE)*2; - int64_t dts = pkt->dts, pts = pkt->pts; - - if (ts->reemit_pat_pmt) { - av_log(s, AV_LOG_WARNING, "resend_headers option is deprecated, use -mpegts_flags resend_headers\n"); - ts->reemit_pat_pmt = 0; - ts->flags |= MPEGTS_FLAG_REEMIT_PAT_PMT; - } - - if (ts->flags & MPEGTS_FLAG_REEMIT_PAT_PMT) { - ts->pat_packet_count = ts->pat_packet_period - 1; - ts->sdt_packet_count = ts->sdt_packet_period - 1; - ts->flags &= ~MPEGTS_FLAG_REEMIT_PAT_PMT; - } - - if(ts->copyts < 1){ - if (pts != AV_NOPTS_VALUE) - pts += delay; - if (dts != AV_NOPTS_VALUE) - dts += delay; - } - - if (ts_st->first_pts_check && pts == AV_NOPTS_VALUE) { - av_log(s, AV_LOG_ERROR, "first pts value must be set\n"); - return AVERROR_INVALIDDATA; - } - ts_st->first_pts_check = 0; - - if (st->codec->codec_id == AV_CODEC_ID_H264) { - const uint8_t *p = buf, *buf_end = p+size; - uint32_t state = -1; - - if (pkt->size < 5 || AV_RB32(pkt->data) != 0x0000001) { - av_log(s, AV_LOG_ERROR, "H.264 bitstream malformed, " - "no startcode found, use the h264_mp4toannexb bitstream filter (-bsf h264_mp4toannexb)\n"); - return AVERROR(EINVAL); - } - - do { - p = avpriv_mpv_find_start_code(p, buf_end, &state); - av_dlog(s, "nal %d\n", state & 0x1f); - } while (p < buf_end && (state & 0x1f) != 9 && - (state & 0x1f) != 5 && (state & 0x1f) != 1); - - if ((state & 0x1f) != 9) { // AUD NAL - data = av_malloc(pkt->size+6); - if (!data) - return AVERROR(ENOMEM); - memcpy(data+6, pkt->data, pkt->size); - AV_WB32(data, 0x00000001); - data[4] = 0x09; - data[5] = 0xf0; // any slice type (0xe) + rbsp stop one bit - buf = data; - size = pkt->size+6; - } - } else if (st->codec->codec_id == AV_CODEC_ID_AAC) { - if (pkt->size < 2) { - av_log(s, AV_LOG_ERROR, "AAC packet too short\n"); - return AVERROR_INVALIDDATA; - } - if ((AV_RB16(pkt->data) & 0xfff0) != 0xfff0) { - int ret; - AVPacket pkt2; - - if (!ts_st->amux) { - av_log(s, AV_LOG_ERROR, "AAC bitstream not in ADTS format " - "and extradata missing\n"); - return AVERROR_INVALIDDATA; - } - - av_init_packet(&pkt2); - pkt2.data = pkt->data; - pkt2.size = pkt->size; - ret = avio_open_dyn_buf(&ts_st->amux->pb); - if (ret < 0) - return AVERROR(ENOMEM); - - ret = av_write_frame(ts_st->amux, &pkt2); - if (ret < 0) { - avio_close_dyn_buf(ts_st->amux->pb, &data); - ts_st->amux->pb = NULL; - av_free(data); - return ret; - } - size = avio_close_dyn_buf(ts_st->amux->pb, &data); - ts_st->amux->pb = NULL; - buf = data; - } - } - - if (pkt->dts != AV_NOPTS_VALUE) { - int i; - for(i=0; inb_streams; i++){ - AVStream *st2 = s->streams[i]; - MpegTSWriteStream *ts_st2 = st2->priv_data; - if( ts_st2->payload_size - && (ts_st2->payload_dts == AV_NOPTS_VALUE || dts - ts_st2->payload_dts > delay/2)){ - mpegts_write_pes(s, st2, ts_st2->payload, ts_st2->payload_size, - ts_st2->payload_pts, ts_st2->payload_dts, - ts_st2->payload_flags & AV_PKT_FLAG_KEY); - ts_st2->payload_size = 0; - } - } - } - - if (ts_st->payload_size && ts_st->payload_size + size > ts->pes_payload_size) { - mpegts_write_pes(s, st, ts_st->payload, ts_st->payload_size, - ts_st->payload_pts, ts_st->payload_dts, - ts_st->payload_flags & AV_PKT_FLAG_KEY); - ts_st->payload_size = 0; - } - - if (st->codec->codec_type != AVMEDIA_TYPE_AUDIO || size > ts->pes_payload_size) { - av_assert0(!ts_st->payload_size); - // for video and subtitle, write a single pes packet - mpegts_write_pes(s, st, buf, size, pts, dts, pkt->flags & AV_PKT_FLAG_KEY); - av_free(data); - return 0; - } - - if (!ts_st->payload_size) { - ts_st->payload_pts = pts; - ts_st->payload_dts = dts; - ts_st->payload_flags = pkt->flags; - } - - memcpy(ts_st->payload + ts_st->payload_size, buf, size); - ts_st->payload_size += size; - - av_free(data); - - return 0; -} - -static void mpegts_write_flush(AVFormatContext *s) -{ - int i; - - /* flush current packets */ - for(i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - MpegTSWriteStream *ts_st = st->priv_data; - if (ts_st->payload_size > 0) { - mpegts_write_pes(s, st, ts_st->payload, ts_st->payload_size, - ts_st->payload_pts, ts_st->payload_dts, - ts_st->payload_flags & AV_PKT_FLAG_KEY); - ts_st->payload_size = 0; - } - } - avio_flush(s->pb); -} - -static int mpegts_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - if (!pkt) { - mpegts_write_flush(s); - return 1; - } else { - return mpegts_write_packet_internal(s, pkt); - } -} - -static int mpegts_write_end(AVFormatContext *s) -{ - MpegTSWrite *ts = s->priv_data; - MpegTSService *service; - int i; - - mpegts_write_flush(s); - - for(i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - MpegTSWriteStream *ts_st = st->priv_data; - av_freep(&ts_st->payload); - if (ts_st->amux) { - avformat_free_context(ts_st->amux); - ts_st->amux = NULL; - } - } - - for(i = 0; i < ts->nb_services; i++) { - service = ts->services[i]; - av_freep(&service->provider_name); - av_freep(&service->name); - av_free(service); - } - av_free(ts->services); - - return 0; -} - -AVOutputFormat ff_mpegts_muxer = { - .name = "mpegts", - .long_name = NULL_IF_CONFIG_SMALL("MPEG-TS (MPEG-2 Transport Stream)"), - .mime_type = "video/x-mpegts", - .extensions = "ts,m2t,m2ts,mts", - .priv_data_size = sizeof(MpegTSWrite), - .audio_codec = AV_CODEC_ID_MP2, - .video_codec = AV_CODEC_ID_MPEG2VIDEO, - .write_header = mpegts_write_header, - .write_packet = mpegts_write_packet, - .write_trailer = mpegts_write_end, - .flags = AVFMT_ALLOW_FLUSH, - .priv_class = &mpegts_muxer_class, -}; diff --git a/ffmpeg1/libavformat/mpegvideodec.c b/ffmpeg1/libavformat/mpegvideodec.c deleted file mode 100644 index 471d2f4..0000000 --- a/ffmpeg1/libavformat/mpegvideodec.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * RAW MPEG video demuxer - * Copyright (c) 2002-2003 Fabrice Bellard - * Copyright (c) 2006 Michael Niedermayer - * - * 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 "rawdec.h" - -#define SEQ_START_CODE 0x000001b3 -#define GOP_START_CODE 0x000001b8 -#define PICTURE_START_CODE 0x00000100 -#define SLICE_START_CODE 0x00000101 -#define PACK_START_CODE 0x000001ba -#define VIDEO_ID 0x000001e0 -#define AUDIO_ID 0x000001c0 - -static int mpegvideo_probe(AVProbeData *p) -{ - uint32_t code= -1; - int pic=0, seq=0, slice=0, pspack=0, vpes=0, apes=0, res=0, sicle=0; - int i; - uint32_t last = 0; - - for(i=0; ibuf_size; i++){ - code = (code<<8) + p->buf[i]; - if ((code & 0xffffff00) == 0x100) { - switch(code){ - case SEQ_START_CODE: seq++; break; - case PICTURE_START_CODE: pic++; break; - case PACK_START_CODE: pspack++; break; - case 0x1b6: - res++; break; - } - if (code >= SLICE_START_CODE && code <= 0x1af) { - if (last >= SLICE_START_CODE && last <= 0x1af) { - if (code >= last) slice++; - else sicle++; - }else{ - if (code == SLICE_START_CODE) slice++; - else sicle++; - } - } - if ((code & 0x1f0) == VIDEO_ID) vpes++; - else if((code & 0x1e0) == AUDIO_ID) apes++; - last = code; - } - } - if(seq && seq*9<=pic*10 && pic*9<=slice*10 && !pspack && !apes && !res && slice > sicle) { - if(vpes) return AVPROBE_SCORE_MAX/8; - else return pic>1 ? AVPROBE_SCORE_MAX/2+1 : AVPROBE_SCORE_MAX/4; // +1 for .mpg - } - return 0; -} - -FF_DEF_RAWVIDEO_DEMUXER(mpegvideo, "raw MPEG video", mpegvideo_probe, NULL, AV_CODEC_ID_MPEG1VIDEO) diff --git a/ffmpeg1/libavformat/mpjpeg.c b/ffmpeg1/libavformat/mpjpeg.c deleted file mode 100644 index 916938f..0000000 --- a/ffmpeg1/libavformat/mpjpeg.c +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Multipart JPEG format - * Copyright (c) 2000, 2001, 2002, 2003 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" - -/* Multipart JPEG */ - -#define BOUNDARY_TAG "ffserver" - -static int mpjpeg_write_header(AVFormatContext *s) -{ - uint8_t buf1[256]; - - snprintf(buf1, sizeof(buf1), "--%s\r\n", BOUNDARY_TAG); - avio_write(s->pb, buf1, strlen(buf1)); - avio_flush(s->pb); - return 0; -} - -static int mpjpeg_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - uint8_t buf1[256]; - - snprintf(buf1, sizeof(buf1), "Content-type: image/jpeg\r\n"); - avio_write(s->pb, buf1, strlen(buf1)); - - snprintf(buf1, sizeof(buf1), "Content-length: %d\r\n\r\n", pkt->size); - avio_write(s->pb, buf1, strlen(buf1)); - avio_write(s->pb, pkt->data, pkt->size); - - snprintf(buf1, sizeof(buf1), "\r\n--%s\r\n", BOUNDARY_TAG); - avio_write(s->pb, buf1, strlen(buf1)); - avio_flush(s->pb); - return 0; -} - -static int mpjpeg_write_trailer(AVFormatContext *s) -{ - return 0; -} - -AVOutputFormat ff_mpjpeg_muxer = { - .name = "mpjpeg", - .long_name = NULL_IF_CONFIG_SMALL("MIME multipart JPEG"), - .mime_type = "multipart/x-mixed-replace;boundary=" BOUNDARY_TAG, - .extensions = "mjpg", - .audio_codec = AV_CODEC_ID_NONE, - .video_codec = AV_CODEC_ID_MJPEG, - .write_header = mpjpeg_write_header, - .write_packet = mpjpeg_write_packet, - .write_trailer = mpjpeg_write_trailer, -}; diff --git a/ffmpeg1/libavformat/mpl2dec.c b/ffmpeg1/libavformat/mpl2dec.c deleted file mode 100644 index ce2061b..0000000 --- a/ffmpeg1/libavformat/mpl2dec.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright (c) 2012 Clément BÅ“sch - * - * 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 - */ - -/** - * @file - * MPL2 subtitles format demuxer - */ - -#include "avformat.h" -#include "internal.h" -#include "subtitles.h" - -typedef struct { - FFDemuxSubtitlesQueue q; -} MPL2Context; - -static int mpl2_probe(AVProbeData *p) -{ - int i; - char c; - int64_t start, end; - const unsigned char *ptr = p->buf; - const unsigned char *ptr_end = ptr + p->buf_size; - - for (i = 0; i < 2; i++) { - if (sscanf(ptr, "[%"PRId64"][%"PRId64"]%c", &start, &end, &c) != 3 && - sscanf(ptr, "[%"PRId64"][]%c", &start, &c) != 2) - return 0; - ptr += strcspn(ptr, "\r\n") + 1; - if (ptr >= ptr_end) - return 0; - } - return AVPROBE_SCORE_MAX; -} - -static int read_ts(char **line, int64_t *pts_start, int *duration) -{ - char c; - int len; - int64_t end; - - if (sscanf(*line, "[%"PRId64"][]%c%n", - pts_start, &c, &len) >= 2) { - *duration = -1; - *line += len - 1; - return 0; - } - if (sscanf(*line, "[%"PRId64"][%"PRId64"]%c%n", - pts_start, &end, &c, &len) >= 3) { - *duration = end - *pts_start; - *line += len - 1; - return 0; - } - return -1; -} - -static int mpl2_read_header(AVFormatContext *s) -{ - MPL2Context *mpl2 = s->priv_data; - AVStream *st = avformat_new_stream(s, NULL); - int res = 0; - - if (!st) - return AVERROR(ENOMEM); - avpriv_set_pts_info(st, 64, 1, 10); - st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE; - st->codec->codec_id = AV_CODEC_ID_MPL2; - - while (!url_feof(s->pb)) { - char line[4096]; - char *p = line; - const int64_t pos = avio_tell(s->pb); - int len = ff_get_line(s->pb, line, sizeof(line)); - int64_t pts_start; - int duration; - - if (!len) - break; - - line[strcspn(line, "\r\n")] = 0; - - if (!read_ts(&p, &pts_start, &duration)) { - AVPacket *sub; - - sub = ff_subtitles_queue_insert(&mpl2->q, p, strlen(p), 0); - if (!sub) - return AVERROR(ENOMEM); - sub->pos = pos; - sub->pts = pts_start; - sub->duration = duration; - } - } - - ff_subtitles_queue_finalize(&mpl2->q); - return res; -} - -static int mpl2_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - MPL2Context *mpl2 = s->priv_data; - return ff_subtitles_queue_read_packet(&mpl2->q, pkt); -} - -static int mpl2_read_seek(AVFormatContext *s, int stream_index, - int64_t min_ts, int64_t ts, int64_t max_ts, int flags) -{ - MPL2Context *mpl2 = s->priv_data; - return ff_subtitles_queue_seek(&mpl2->q, s, stream_index, - min_ts, ts, max_ts, flags); -} - -static int mpl2_read_close(AVFormatContext *s) -{ - MPL2Context *mpl2 = s->priv_data; - ff_subtitles_queue_clean(&mpl2->q); - return 0; -} - -AVInputFormat ff_mpl2_demuxer = { - .name = "mpl2", - .long_name = NULL_IF_CONFIG_SMALL("MPL2 subtitles"), - .priv_data_size = sizeof(MPL2Context), - .read_probe = mpl2_probe, - .read_header = mpl2_read_header, - .read_packet = mpl2_read_packet, - .read_seek2 = mpl2_read_seek, - .read_close = mpl2_read_close, - .extensions = "txt,mpl2", -}; diff --git a/ffmpeg1/libavformat/mpsubdec.c b/ffmpeg1/libavformat/mpsubdec.c deleted file mode 100644 index 2acafaa..0000000 --- a/ffmpeg1/libavformat/mpsubdec.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (c) 2012 Clément BÅ“sch - * - * 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 - */ - -/** - * @file - * MPlayer subtitles format demuxer - */ - -#include "avformat.h" -#include "internal.h" -#include "subtitles.h" - -typedef struct { - FFDemuxSubtitlesQueue q; -} MPSubContext; - -static int mpsub_probe(AVProbeData *p) -{ - const char *ptr = p->buf; - const char *ptr_end = p->buf + p->buf_size; - - while (ptr < ptr_end) { - int n; - - if (!memcmp(ptr, "FORMAT=TIME", 11) || - sscanf(ptr, "FORMAT=%d", &n) == 1) - return AVPROBE_SCORE_MAX/2; - ptr += strcspn(ptr, "\n") + 1; - } - return 0; -} - -static int mpsub_read_header(AVFormatContext *s) -{ - MPSubContext *mpsub = s->priv_data; - AVStream *st; - AVBPrint buf; - AVRational pts_info = (AVRational){ 100, 1 }; // ts based by default - int res = 0; - float multiplier = 100.0; - float current_pts = 0; - - av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED); - - while (!url_feof(s->pb)) { - char line[1024]; - float start, duration; - int fps, len = ff_get_line(s->pb, line, sizeof(line)); - - if (!len) - break; - - line[strcspn(line, "\r\n")] = 0; - - if (sscanf(line, "FORMAT=%d", &fps) == 1 && fps > 3 && fps < 100) { - /* frame based timing */ - pts_info = (AVRational){ fps, 1 }; - multiplier = 1.0; - } else if (sscanf(line, "%f %f", &start, &duration) == 2) { - AVPacket *sub; - const int64_t pos = avio_tell(s->pb); - - ff_subtitles_read_chunk(s->pb, &buf); - if (buf.len) { - sub = ff_subtitles_queue_insert(&mpsub->q, buf.str, buf.len, 0); - if (!sub) { - res = AVERROR(ENOMEM); - goto end; - } - sub->pts = (int64_t)(current_pts + start*multiplier); - sub->duration = (int)(duration * multiplier); - current_pts += (start + duration) * multiplier; - sub->pos = pos; - } - } - } - - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - avpriv_set_pts_info(st, 64, pts_info.den, pts_info.num); - st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE; - st->codec->codec_id = AV_CODEC_ID_TEXT; - - ff_subtitles_queue_finalize(&mpsub->q); - -end: - av_bprint_finalize(&buf, NULL); - return res; -} - -static int mpsub_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - MPSubContext *mpsub = s->priv_data; - return ff_subtitles_queue_read_packet(&mpsub->q, pkt); -} - -static int mpsub_read_seek(AVFormatContext *s, int stream_index, - int64_t min_ts, int64_t ts, int64_t max_ts, int flags) -{ - MPSubContext *mpsub = s->priv_data; - return ff_subtitles_queue_seek(&mpsub->q, s, stream_index, - min_ts, ts, max_ts, flags); -} - -static int mpsub_read_close(AVFormatContext *s) -{ - MPSubContext *mpsub = s->priv_data; - ff_subtitles_queue_clean(&mpsub->q); - return 0; -} - -AVInputFormat ff_mpsub_demuxer = { - .name = "mpsub", - .long_name = NULL_IF_CONFIG_SMALL("MPlayer subtitles"), - .priv_data_size = sizeof(MPSubContext), - .read_probe = mpsub_probe, - .read_header = mpsub_read_header, - .read_packet = mpsub_read_packet, - .read_seek2 = mpsub_read_seek, - .read_close = mpsub_read_close, - .extensions = "sub", -}; diff --git a/ffmpeg1/libavformat/msnwc_tcp.c b/ffmpeg1/libavformat/msnwc_tcp.c deleted file mode 100644 index 0ac1c30..0000000 --- a/ffmpeg1/libavformat/msnwc_tcp.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (C) 2008 Ramiro Polla - * - * 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 "libavcodec/bytestream.h" -#include "avformat.h" -#include "internal.h" - -#define HEADER_SIZE 24 - -/* - * Header structure: - * uint16_t ss; // struct size - * uint16_t width; // frame width - * uint16_t height; // frame height - * uint16_t ff; // keyframe + some other info(???) - * uint32_t size; // size of data - * uint32_t fourcc; // ML20 - * uint32_t u3; // ? - * uint32_t ts; // time - */ - -static int msnwc_tcp_probe(AVProbeData *p) -{ - int i; - - for(i = 0 ; i + HEADER_SIZE <= p->buf_size ; i++) { - uint16_t width, height; - uint32_t fourcc; - const uint8_t *bytestream = p->buf+i; - - if(bytestream_get_le16(&bytestream) != HEADER_SIZE) - continue; - width = bytestream_get_le16(&bytestream); - height = bytestream_get_le16(&bytestream); - if(!(width==320 && height==240) && !(width==160 && height==120)) - continue; - bytestream += 2; // keyframe - bytestream += 4; // size - fourcc = bytestream_get_le32(&bytestream); - if(fourcc != MKTAG('M', 'L', '2', '0')) - continue; - - if(i) { - if(i < 14) /* starts with SwitchBoard connection info */ - return AVPROBE_SCORE_MAX / 2; - else /* starts in the middle of stream */ - return AVPROBE_SCORE_MAX / 3; - } else { - return AVPROBE_SCORE_MAX; - } - } - - return -1; -} - -static int msnwc_tcp_read_header(AVFormatContext *ctx) -{ - AVIOContext *pb = ctx->pb; - AVCodecContext *codec; - AVStream *st; - - st = avformat_new_stream(ctx, NULL); - if(!st) - return AVERROR(ENOMEM); - - codec = st->codec; - codec->codec_type = AVMEDIA_TYPE_VIDEO; - codec->codec_id = AV_CODEC_ID_MIMIC; - codec->codec_tag = MKTAG('M', 'L', '2', '0'); - - avpriv_set_pts_info(st, 32, 1, 1000); - - /* Some files start with "connected\r\n\r\n". - * So skip until we find the first byte of struct size */ - while(avio_r8(pb) != HEADER_SIZE && !url_feof(pb)); - - if(url_feof(pb)) { - av_log(ctx, AV_LOG_ERROR, "Could not find valid start.\n"); - return -1; - } - - return 0; -} - -static int msnwc_tcp_read_packet(AVFormatContext *ctx, AVPacket *pkt) -{ - AVIOContext *pb = ctx->pb; - uint16_t keyframe; - uint32_t size, timestamp; - - avio_skip(pb, 1); /* one byte has been read ahead */ - avio_skip(pb, 2); - avio_skip(pb, 2); - keyframe = avio_rl16(pb); - size = avio_rl32(pb); - avio_skip(pb, 4); - avio_skip(pb, 4); - timestamp = avio_rl32(pb); - - if(!size || av_get_packet(pb, pkt, size) != size) - return -1; - - avio_skip(pb, 1); /* Read ahead one byte of struct size like read_header */ - - pkt->pts = timestamp; - pkt->dts = timestamp; - pkt->stream_index = 0; - - /* Some aMsn generated videos (or was it Mercury Messenger?) don't set - * this bit and rely on the codec to get keyframe information */ - if(keyframe&1) - pkt->flags |= AV_PKT_FLAG_KEY; - - return HEADER_SIZE + size; -} - -AVInputFormat ff_msnwc_tcp_demuxer = { - .name = "msnwctcp", - .long_name = NULL_IF_CONFIG_SMALL("MSN TCP Webcam stream"), - .read_probe = msnwc_tcp_probe, - .read_header = msnwc_tcp_read_header, - .read_packet = msnwc_tcp_read_packet, -}; diff --git a/ffmpeg1/libavformat/mtv.c b/ffmpeg1/libavformat/mtv.c deleted file mode 100644 index 6ffbb51..0000000 --- a/ffmpeg1/libavformat/mtv.c +++ /dev/null @@ -1,203 +0,0 @@ -/* - * mtv demuxer - * Copyright (c) 2006 Reynaldo H. Verdejo Pinochet - * - * 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 - */ - -/** - * @file - * MTV demuxer. - */ - -#include "libavutil/bswap.h" -#include "libavutil/intreadwrite.h" -#include "avformat.h" -#include "internal.h" - -#define MTV_ASUBCHUNK_DATA_SIZE 500 -#define MTV_HEADER_SIZE 512 -#define MTV_AUDIO_PADDING_SIZE 12 -#define AUDIO_SAMPLING_RATE 44100 - -typedef struct MTVDemuxContext { - - unsigned int file_size; ///< filesize, not always right - unsigned int segments; ///< number of 512 byte segments - unsigned int audio_identifier; ///< 'MP3' on all files I have seen - unsigned int audio_br; ///< bitrate of audio channel (mp3) - unsigned int img_colorfmt; ///< frame colorfmt rgb 565/555 - unsigned int img_bpp; ///< frame bits per pixel - unsigned int img_width; // - unsigned int img_height; // - unsigned int img_segment_size; ///< size of image segment - unsigned int video_fps; // - unsigned int full_segment_size; - -} MTVDemuxContext; - -static int mtv_probe(AVProbeData *p) -{ - /* Magic is 'AMV' */ - if (*p->buf != 'A' || *(p->buf + 1) != 'M' || *(p->buf + 2) != 'V') - return 0; - - /* Check for nonzero in bpp and (width|height) header fields */ - if(p->buf_size < 57 || !(p->buf[51] && AV_RL16(&p->buf[52]) | AV_RL16(&p->buf[54]))) - return 0; - - /* If width or height are 0 then imagesize header field should not */ - if(!AV_RL16(&p->buf[52]) || !AV_RL16(&p->buf[54])) - { - if(!!AV_RL16(&p->buf[56])) - return AVPROBE_SCORE_MAX/2; - else - return 0; - } - - if(p->buf[51] != 16) - return AVPROBE_SCORE_MAX/4; // But we are going to assume 16bpp anyway .. - - return AVPROBE_SCORE_MAX; -} - -static int mtv_read_header(AVFormatContext *s) -{ - MTVDemuxContext *mtv = s->priv_data; - AVIOContext *pb = s->pb; - AVStream *st; - unsigned int audio_subsegments; - - avio_skip(pb, 3); - mtv->file_size = avio_rl32(pb); - mtv->segments = avio_rl32(pb); - avio_skip(pb, 32); - mtv->audio_identifier = avio_rl24(pb); - mtv->audio_br = avio_rl16(pb); - mtv->img_colorfmt = avio_rl24(pb); - mtv->img_bpp = avio_r8(pb); - mtv->img_width = avio_rl16(pb); - mtv->img_height = avio_rl16(pb); - mtv->img_segment_size = avio_rl16(pb); - - /* Calculate width and height if missing from header */ - - if(mtv->img_bpp>>3){ - if(!mtv->img_width && mtv->img_height) - mtv->img_width=mtv->img_segment_size / (mtv->img_bpp>>3) - / mtv->img_height; - - if(!mtv->img_height && mtv->img_width) - mtv->img_height=mtv->img_segment_size / (mtv->img_bpp>>3) - / mtv->img_width; - } - if(!mtv->img_height || !mtv->img_width){ - av_log(s, AV_LOG_ERROR, "width or height is invalid and I cannot calculate them from other information\n"); - return AVERROR(EINVAL); - } - - avio_skip(pb, 4); - audio_subsegments = avio_rl16(pb); - - if (audio_subsegments == 0) { - avpriv_request_sample(s, "MTV files without audio"); - return AVERROR_PATCHWELCOME; - } - - mtv->full_segment_size = - audio_subsegments * (MTV_AUDIO_PADDING_SIZE + MTV_ASUBCHUNK_DATA_SIZE) + - mtv->img_segment_size; - mtv->video_fps = (mtv->audio_br / 4) / audio_subsegments; - - // FIXME Add sanity check here - - // all systems go! init decoders - - // video - raw rgb565 - - st = avformat_new_stream(s, NULL); - if(!st) - return AVERROR(ENOMEM); - - avpriv_set_pts_info(st, 64, 1, mtv->video_fps); - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = AV_CODEC_ID_RAWVIDEO; - st->codec->pix_fmt = AV_PIX_FMT_RGB565BE; - st->codec->width = mtv->img_width; - st->codec->height = mtv->img_height; - st->codec->sample_rate = mtv->video_fps; - st->codec->extradata = av_strdup("BottomUp"); - st->codec->extradata_size = 9; - - // audio - mp3 - - st = avformat_new_stream(s, NULL); - if(!st) - return AVERROR(ENOMEM); - - avpriv_set_pts_info(st, 64, 1, AUDIO_SAMPLING_RATE); - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = AV_CODEC_ID_MP3; - st->codec->bit_rate = mtv->audio_br; - st->need_parsing = AVSTREAM_PARSE_FULL; - - // Jump over header - - if(avio_seek(pb, MTV_HEADER_SIZE, SEEK_SET) != MTV_HEADER_SIZE) - return AVERROR(EIO); - - return 0; - -} - -static int mtv_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - MTVDemuxContext *mtv = s->priv_data; - AVIOContext *pb = s->pb; - int ret; - - if((avio_tell(pb) - s->data_offset + mtv->img_segment_size) % mtv->full_segment_size) - { - avio_skip(pb, MTV_AUDIO_PADDING_SIZE); - - ret = av_get_packet(pb, pkt, MTV_ASUBCHUNK_DATA_SIZE); - if(ret < 0) - return ret; - - pkt->pos -= MTV_AUDIO_PADDING_SIZE; - pkt->stream_index = 1; - - }else - { - ret = av_get_packet(pb, pkt, mtv->img_segment_size); - if(ret < 0) - return ret; - - pkt->stream_index = 0; - } - - return ret; -} - -AVInputFormat ff_mtv_demuxer = { - .name = "mtv", - .long_name = NULL_IF_CONFIG_SMALL("MTV"), - .priv_data_size = sizeof(MTVDemuxContext), - .read_probe = mtv_probe, - .read_header = mtv_read_header, - .read_packet = mtv_read_packet, -}; diff --git a/ffmpeg1/libavformat/mux.c b/ffmpeg1/libavformat/mux.c deleted file mode 100644 index 3578a52..0000000 --- a/ffmpeg1/libavformat/mux.c +++ /dev/null @@ -1,814 +0,0 @@ -/* - * muxing functions for use within FFmpeg - * Copyright (c) 2000, 2001, 2002 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 - */ - -/* #define DEBUG */ - -#include "avformat.h" -#include "avio_internal.h" -#include "internal.h" -#include "libavcodec/internal.h" -#include "libavcodec/bytestream.h" -#include "libavutil/opt.h" -#include "libavutil/dict.h" -#include "libavutil/pixdesc.h" -#include "libavutil/timestamp.h" -#include "metadata.h" -#include "id3v2.h" -#include "libavutil/avassert.h" -#include "libavutil/avstring.h" -#include "libavutil/mathematics.h" -#include "libavutil/parseutils.h" -#include "libavutil/time.h" -#include "riff.h" -#include "audiointerleave.h" -#include "url.h" -#include -#if CONFIG_NETWORK -#include "network.h" -#endif - -#undef NDEBUG -#include - -/** - * @file - * muxing functions for use within libavformat - */ - -/* fraction handling */ - -/** - * f = val + (num / den) + 0.5. - * - * 'num' is normalized so that it is such as 0 <= num < den. - * - * @param f fractional number - * @param val integer value - * @param num must be >= 0 - * @param den must be >= 1 - */ -static void frac_init(AVFrac *f, int64_t val, int64_t num, int64_t den) -{ - num += (den >> 1); - if (num >= den) { - val += num / den; - num = num % den; - } - f->val = val; - f->num = num; - f->den = den; -} - -/** - * Fractional addition to f: f = f + (incr / f->den). - * - * @param f fractional number - * @param incr increment, can be positive or negative - */ -static void frac_add(AVFrac *f, int64_t incr) -{ - int64_t num, den; - - num = f->num + incr; - den = f->den; - if (num < 0) { - f->val += num / den; - num = num % den; - if (num < 0) { - num += den; - f->val--; - } - } else if (num >= den) { - f->val += num / den; - num = num % den; - } - f->num = num; -} - -AVRational ff_choose_timebase(AVFormatContext *s, AVStream *st, int min_precission) -{ - AVRational q; - int j; - - if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - q = (AVRational){1, st->codec->sample_rate}; - } else { - q = st->codec->time_base; - } - for (j=2; j<14; j+= 1+(j>2)) - while (q.den / q.num < min_precission && q.num % j == 0) - q.num /= j; - while (q.den / q.num < min_precission && q.den < (1<<24)) - q.den <<= 1; - - return q; -} - -int avformat_alloc_output_context2(AVFormatContext **avctx, AVOutputFormat *oformat, - const char *format, const char *filename) -{ - AVFormatContext *s = avformat_alloc_context(); - int ret = 0; - - *avctx = NULL; - if (!s) - goto nomem; - - if (!oformat) { - if (format) { - oformat = av_guess_format(format, NULL, NULL); - if (!oformat) { - av_log(s, AV_LOG_ERROR, "Requested output format '%s' is not a suitable output format\n", format); - ret = AVERROR(EINVAL); - goto error; - } - } else { - oformat = av_guess_format(NULL, filename, NULL); - if (!oformat) { - ret = AVERROR(EINVAL); - av_log(s, AV_LOG_ERROR, "Unable to find a suitable output format for '%s'\n", - filename); - goto error; - } - } - } - - s->oformat = oformat; - if (s->oformat->priv_data_size > 0) { - s->priv_data = av_mallocz(s->oformat->priv_data_size); - if (!s->priv_data) - goto nomem; - if (s->oformat->priv_class) { - *(const AVClass**)s->priv_data= s->oformat->priv_class; - av_opt_set_defaults(s->priv_data); - } - } else - s->priv_data = NULL; - - if (filename) - av_strlcpy(s->filename, filename, sizeof(s->filename)); - *avctx = s; - return 0; -nomem: - av_log(s, AV_LOG_ERROR, "Out of memory\n"); - ret = AVERROR(ENOMEM); -error: - avformat_free_context(s); - return ret; -} - -#if FF_API_ALLOC_OUTPUT_CONTEXT -AVFormatContext *avformat_alloc_output_context(const char *format, - AVOutputFormat *oformat, const char *filename) -{ - AVFormatContext *avctx; - int ret = avformat_alloc_output_context2(&avctx, oformat, format, filename); - return ret < 0 ? NULL : avctx; -} -#endif - -static int validate_codec_tag(AVFormatContext *s, AVStream *st) -{ - const AVCodecTag *avctag; - int n; - enum AVCodecID id = AV_CODEC_ID_NONE; - unsigned int tag = 0; - - /** - * Check that tag + id is in the table - * If neither is in the table -> OK - * If tag is in the table with another id -> FAIL - * If id is in the table with another tag -> FAIL unless strict < normal - */ - for (n = 0; s->oformat->codec_tag[n]; n++) { - avctag = s->oformat->codec_tag[n]; - while (avctag->id != AV_CODEC_ID_NONE) { - if (avpriv_toupper4(avctag->tag) == avpriv_toupper4(st->codec->codec_tag)) { - id = avctag->id; - if (id == st->codec->codec_id) - return 1; - } - if (avctag->id == st->codec->codec_id) - tag = avctag->tag; - avctag++; - } - } - if (id != AV_CODEC_ID_NONE) - return 0; - if (tag && (st->codec->strict_std_compliance >= FF_COMPLIANCE_NORMAL)) - return 0; - return 1; -} - - -static int init_muxer(AVFormatContext *s, AVDictionary **options) -{ - int ret = 0, i; - AVStream *st; - AVDictionary *tmp = NULL; - AVCodecContext *codec = NULL; - AVOutputFormat *of = s->oformat; - - if (options) - av_dict_copy(&tmp, *options, 0); - - if ((ret = av_opt_set_dict(s, &tmp)) < 0) - goto fail; - if (s->priv_data && s->oformat->priv_class && *(const AVClass**)s->priv_data==s->oformat->priv_class && - (ret = av_opt_set_dict(s->priv_data, &tmp)) < 0) - goto fail; - - // some sanity checks - if (s->nb_streams == 0 && !(of->flags & AVFMT_NOSTREAMS)) { - av_log(s, AV_LOG_ERROR, "no streams\n"); - ret = AVERROR(EINVAL); - goto fail; - } - - for (i = 0; i < s->nb_streams; i++) { - st = s->streams[i]; - codec = st->codec; - - switch (codec->codec_type) { - case AVMEDIA_TYPE_AUDIO: - if (codec->sample_rate <= 0) { - av_log(s, AV_LOG_ERROR, "sample rate not set\n"); - ret = AVERROR(EINVAL); - goto fail; - } - if (!codec->block_align) - codec->block_align = codec->channels * - av_get_bits_per_sample(codec->codec_id) >> 3; - break; - case AVMEDIA_TYPE_VIDEO: - if (codec->time_base.num <= 0 || - codec->time_base.den <= 0) { //FIXME audio too? - av_log(s, AV_LOG_ERROR, "time base not set\n"); - ret = AVERROR(EINVAL); - goto fail; - } - - if ((codec->width <= 0 || codec->height <= 0) && - !(of->flags & AVFMT_NODIMENSIONS)) { - av_log(s, AV_LOG_ERROR, "dimensions not set\n"); - ret = AVERROR(EINVAL); - goto fail; - } - if (av_cmp_q(st->sample_aspect_ratio, codec->sample_aspect_ratio) - && FFABS(av_q2d(st->sample_aspect_ratio) - av_q2d(codec->sample_aspect_ratio)) > 0.004*av_q2d(st->sample_aspect_ratio) - ) { - av_log(s, AV_LOG_ERROR, "Aspect ratio mismatch between muxer " - "(%d/%d) and encoder layer (%d/%d)\n", - st->sample_aspect_ratio.num, st->sample_aspect_ratio.den, - codec->sample_aspect_ratio.num, - codec->sample_aspect_ratio.den); - ret = AVERROR(EINVAL); - goto fail; - } - break; - } - - if (of->codec_tag) { - if ( codec->codec_tag - && codec->codec_id == AV_CODEC_ID_RAWVIDEO - && ( av_codec_get_tag(of->codec_tag, codec->codec_id) == 0 - || av_codec_get_tag(of->codec_tag, codec->codec_id) == MKTAG('r', 'a', 'w', ' ')) - && !validate_codec_tag(s, st)) { - // the current rawvideo encoding system ends up setting - // the wrong codec_tag for avi/mov, we override it here - codec->codec_tag = 0; - } - if (codec->codec_tag) { - if (!validate_codec_tag(s, st)) { - char tagbuf[32], cortag[32]; - av_get_codec_tag_string(tagbuf, sizeof(tagbuf), codec->codec_tag); - av_get_codec_tag_string(cortag, sizeof(cortag), av_codec_get_tag(s->oformat->codec_tag, codec->codec_id)); - av_log(s, AV_LOG_ERROR, - "Tag %s/0x%08x incompatible with output codec id '%d' (%s)\n", - tagbuf, codec->codec_tag, codec->codec_id, cortag); - ret = AVERROR_INVALIDDATA; - goto fail; - } - } else - codec->codec_tag = av_codec_get_tag(of->codec_tag, codec->codec_id); - } - - if (of->flags & AVFMT_GLOBALHEADER && - !(codec->flags & CODEC_FLAG_GLOBAL_HEADER)) - av_log(s, AV_LOG_WARNING, - "Codec for stream %d does not use global headers " - "but container format requires global headers\n", i); - } - - if (!s->priv_data && of->priv_data_size > 0) { - s->priv_data = av_mallocz(of->priv_data_size); - if (!s->priv_data) { - ret = AVERROR(ENOMEM); - goto fail; - } - if (of->priv_class) { - *(const AVClass **)s->priv_data = of->priv_class; - av_opt_set_defaults(s->priv_data); - if ((ret = av_opt_set_dict(s->priv_data, &tmp)) < 0) - goto fail; - } - } - - /* set muxer identification string */ - if (s->nb_streams && !(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT)) { - av_dict_set(&s->metadata, "encoder", LIBAVFORMAT_IDENT, 0); - } - - if (options) { - av_dict_free(options); - *options = tmp; - } - - return 0; - -fail: - av_dict_free(&tmp); - return ret; -} - -static int init_pts(AVFormatContext *s) -{ - int i; - AVStream *st; - - /* init PTS generation */ - for (i = 0; i < s->nb_streams; i++) { - int64_t den = AV_NOPTS_VALUE; - st = s->streams[i]; - - switch (st->codec->codec_type) { - case AVMEDIA_TYPE_AUDIO: - den = (int64_t)st->time_base.num * st->codec->sample_rate; - break; - case AVMEDIA_TYPE_VIDEO: - den = (int64_t)st->time_base.num * st->codec->time_base.den; - break; - default: - break; - } - if (den != AV_NOPTS_VALUE) { - if (den <= 0) - return AVERROR_INVALIDDATA; - - frac_init(&st->pts, 0, 0, den); - } - } - - return 0; -} - -int avformat_write_header(AVFormatContext *s, AVDictionary **options) -{ - int ret = 0; - - if (ret = init_muxer(s, options)) - return ret; - - if (s->oformat->write_header) { - ret = s->oformat->write_header(s); - if (ret >= 0 && s->pb && s->pb->error < 0) - ret = s->pb->error; - if (ret < 0) - return ret; - } - - if ((ret = init_pts(s)) < 0) - return ret; - - return 0; -} - -//FIXME merge with compute_pkt_fields -static int compute_pkt_fields2(AVFormatContext *s, AVStream *st, AVPacket *pkt) -{ - int delay = FFMAX(st->codec->has_b_frames, st->codec->max_b_frames > 0); - int num, den, frame_size, i; - - av_dlog(s, "compute_pkt_fields2: pts:%s dts:%s cur_dts:%s b:%d size:%d st:%d\n", - av_ts2str(pkt->pts), av_ts2str(pkt->dts), av_ts2str(st->cur_dts), delay, pkt->size, pkt->stream_index); - - /* duration field */ - if (pkt->duration == 0) { - ff_compute_frame_duration(&num, &den, st, NULL, pkt); - if (den && num) { - pkt->duration = av_rescale(1, num * (int64_t)st->time_base.den * st->codec->ticks_per_frame, den * (int64_t)st->time_base.num); - } - } - - if (pkt->pts == AV_NOPTS_VALUE && pkt->dts != AV_NOPTS_VALUE && delay == 0) - pkt->pts = pkt->dts; - - //XXX/FIXME this is a temporary hack until all encoders output pts - if ((pkt->pts == 0 || pkt->pts == AV_NOPTS_VALUE) && pkt->dts == AV_NOPTS_VALUE && !delay) { - static int warned; - if (!warned) { - av_log(s, AV_LOG_WARNING, "Encoder did not produce proper pts, making some up.\n"); - warned = 1; - } - pkt->dts = -// pkt->pts= st->cur_dts; - pkt->pts = st->pts.val; - } - - //calculate dts from pts - if (pkt->pts != AV_NOPTS_VALUE && pkt->dts == AV_NOPTS_VALUE && delay <= MAX_REORDER_DELAY) { - st->pts_buffer[0] = pkt->pts; - for (i = 1; i < delay + 1 && st->pts_buffer[i] == AV_NOPTS_VALUE; i++) - st->pts_buffer[i] = pkt->pts + (i - delay - 1) * pkt->duration; - for (i = 0; ipts_buffer[i] > st->pts_buffer[i + 1]; i++) - FFSWAP(int64_t, st->pts_buffer[i], st->pts_buffer[i + 1]); - - pkt->dts = st->pts_buffer[0]; - } - - if (st->cur_dts && st->cur_dts != AV_NOPTS_VALUE && - ((!(s->oformat->flags & AVFMT_TS_NONSTRICT) && - st->cur_dts >= pkt->dts) || st->cur_dts > pkt->dts)) { - av_log(s, AV_LOG_ERROR, - "Application provided invalid, non monotonically increasing dts to muxer in stream %d: %s >= %s\n", - st->index, av_ts2str(st->cur_dts), av_ts2str(pkt->dts)); - return AVERROR(EINVAL); - } - if (pkt->dts != AV_NOPTS_VALUE && pkt->pts != AV_NOPTS_VALUE && pkt->pts < pkt->dts) { - av_log(s, AV_LOG_ERROR, "pts (%s) < dts (%s) in stream %d\n", - av_ts2str(pkt->pts), av_ts2str(pkt->dts), st->index); - return AVERROR(EINVAL); - } - - av_dlog(s, "av_write_frame: pts2:%s dts2:%s\n", - av_ts2str(pkt->pts), av_ts2str(pkt->dts)); - st->cur_dts = pkt->dts; - st->pts.val = pkt->dts; - - /* update pts */ - switch (st->codec->codec_type) { - case AVMEDIA_TYPE_AUDIO: - frame_size = ff_get_audio_frame_size(st->codec, pkt->size, 1); - - /* HACK/FIXME, we skip the initial 0 size packets as they are most - * likely equal to the encoder delay, but it would be better if we - * had the real timestamps from the encoder */ - if (frame_size >= 0 && (pkt->size || st->pts.num != st->pts.den >> 1 || st->pts.val)) { - frac_add(&st->pts, (int64_t)st->time_base.den * frame_size); - } - break; - case AVMEDIA_TYPE_VIDEO: - frac_add(&st->pts, (int64_t)st->time_base.den * st->codec->time_base.num); - break; - default: - break; - } - return 0; -} - -/** - * Move side data from payload to internal struct, call muxer, and restore - * original packet. - */ -static inline int split_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - int ret, did_split; - - did_split = av_packet_split_side_data(pkt); - ret = s->oformat->write_packet(s, pkt); - if (did_split) - av_packet_merge_side_data(pkt); - return ret; -} - -int av_write_frame(AVFormatContext *s, AVPacket *pkt) -{ - int ret; - - if (!pkt) { - if (s->oformat->flags & AVFMT_ALLOW_FLUSH) { - ret = s->oformat->write_packet(s, NULL); - if (ret >= 0 && s->pb && s->pb->error < 0) - ret = s->pb->error; - return ret; - } - return 1; - } - - ret = compute_pkt_fields2(s, s->streams[pkt->stream_index], pkt); - - if (ret < 0 && !(s->oformat->flags & AVFMT_NOTIMESTAMPS)) - return ret; - - ret = split_write_packet(s, pkt); - if (ret >= 0 && s->pb && s->pb->error < 0) - ret = s->pb->error; - - if (ret >= 0) - s->streams[pkt->stream_index]->nb_frames++; - return ret; -} - -#define CHUNK_START 0x1000 - -int ff_interleave_add_packet(AVFormatContext *s, AVPacket *pkt, - int (*compare)(AVFormatContext *, AVPacket *, AVPacket *)) -{ - AVPacketList **next_point, *this_pktl; - AVStream *st = s->streams[pkt->stream_index]; - int chunked = s->max_chunk_size || s->max_chunk_duration; - - this_pktl = av_mallocz(sizeof(AVPacketList)); - if (!this_pktl) - return AVERROR(ENOMEM); - this_pktl->pkt = *pkt; -#if FF_API_DESTRUCT_PACKET - pkt->destruct = NULL; // do not free original but only the copy -#endif - pkt->buf = NULL; - av_dup_packet(&this_pktl->pkt); // duplicate the packet if it uses non-allocated memory - - if (s->streams[pkt->stream_index]->last_in_packet_buffer) { - next_point = &(st->last_in_packet_buffer->next); - } else { - next_point = &s->packet_buffer; - } - - if (chunked) { - uint64_t max= av_rescale_q_rnd(s->max_chunk_duration, AV_TIME_BASE_Q, st->time_base, AV_ROUND_UP); - st->interleaver_chunk_size += pkt->size; - st->interleaver_chunk_duration += pkt->duration; - if ( (s->max_chunk_size && st->interleaver_chunk_size > s->max_chunk_size) - || (max && st->interleaver_chunk_duration > max)) { - st->interleaver_chunk_size = 0; - this_pktl->pkt.flags |= CHUNK_START; - if (max && st->interleaver_chunk_duration > max) { - int64_t syncoffset = (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)*max/2; - int64_t syncto = av_rescale(pkt->dts + syncoffset, 1, max)*max - syncoffset; - - st->interleaver_chunk_duration += (pkt->dts - syncto)/8 - max; - } else - st->interleaver_chunk_duration = 0; - } - } - if (*next_point) { - if (chunked && !(this_pktl->pkt.flags & CHUNK_START)) - goto next_non_null; - - if (compare(s, &s->packet_buffer_end->pkt, pkt)) { - while ( *next_point - && ((chunked && !((*next_point)->pkt.flags&CHUNK_START)) - || !compare(s, &(*next_point)->pkt, pkt))) - next_point = &(*next_point)->next; - if (*next_point) - goto next_non_null; - } else { - next_point = &(s->packet_buffer_end->next); - } - } - av_assert1(!*next_point); - - s->packet_buffer_end = this_pktl; -next_non_null: - - this_pktl->next = *next_point; - - s->streams[pkt->stream_index]->last_in_packet_buffer = - *next_point = this_pktl; - return 0; -} - -static int ff_interleave_compare_dts(AVFormatContext *s, AVPacket *next, AVPacket *pkt) -{ - AVStream *st = s->streams[pkt->stream_index]; - AVStream *st2 = s->streams[next->stream_index]; - int comp = av_compare_ts(next->dts, st2->time_base, pkt->dts, - st->time_base); - if (s->audio_preload && ((st->codec->codec_type == AVMEDIA_TYPE_AUDIO) != (st2->codec->codec_type == AVMEDIA_TYPE_AUDIO))) { - int64_t ts = av_rescale_q(pkt ->dts, st ->time_base, AV_TIME_BASE_Q) - s->audio_preload*(st ->codec->codec_type == AVMEDIA_TYPE_AUDIO); - int64_t ts2= av_rescale_q(next->dts, st2->time_base, AV_TIME_BASE_Q) - s->audio_preload*(st2->codec->codec_type == AVMEDIA_TYPE_AUDIO); - if (ts == ts2) { - ts= ( pkt ->dts* st->time_base.num*AV_TIME_BASE - s->audio_preload*(int64_t)(st ->codec->codec_type == AVMEDIA_TYPE_AUDIO)* st->time_base.den)*st2->time_base.den - -( next->dts*st2->time_base.num*AV_TIME_BASE - s->audio_preload*(int64_t)(st2->codec->codec_type == AVMEDIA_TYPE_AUDIO)*st2->time_base.den)* st->time_base.den; - ts2=0; - } - comp= (ts>ts2) - (tsstream_index < next->stream_index; - return comp > 0; -} - -int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out, - AVPacket *pkt, int flush) -{ - AVPacketList *pktl; - int stream_count = 0, noninterleaved_count = 0; - int64_t delta_dts_max = 0; - int i, ret; - - if (pkt) { - ret = ff_interleave_add_packet(s, pkt, ff_interleave_compare_dts); - if (ret < 0) - return ret; - } - - for (i = 0; i < s->nb_streams; i++) { - if (s->streams[i]->last_in_packet_buffer) { - ++stream_count; - } else if (s->streams[i]->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) { - ++noninterleaved_count; - } - } - - if (s->nb_streams == stream_count) { - flush = 1; - } else if (!flush) { - for (i=0; i < s->nb_streams; i++) { - if (s->streams[i]->last_in_packet_buffer) { - int64_t delta_dts = - av_rescale_q(s->streams[i]->last_in_packet_buffer->pkt.dts, - s->streams[i]->time_base, - AV_TIME_BASE_Q) - - av_rescale_q(s->packet_buffer->pkt.dts, - s->streams[s->packet_buffer->pkt.stream_index]->time_base, - AV_TIME_BASE_Q); - delta_dts_max= FFMAX(delta_dts_max, delta_dts); - } - } - if (s->nb_streams == stream_count+noninterleaved_count && - delta_dts_max > 20*AV_TIME_BASE) { - av_log(s, AV_LOG_DEBUG, "flushing with %d noninterleaved\n", noninterleaved_count); - flush = 1; - } - } - if (stream_count && flush) { - AVStream *st; - pktl = s->packet_buffer; - *out = pktl->pkt; - st = s->streams[out->stream_index]; - - s->packet_buffer = pktl->next; - if (!s->packet_buffer) - s->packet_buffer_end = NULL; - - if (st->last_in_packet_buffer == pktl) - st->last_in_packet_buffer = NULL; - av_freep(&pktl); - - if (s->avoid_negative_ts > 0) { - if (out->dts != AV_NOPTS_VALUE) { - if (!st->mux_ts_offset && out->dts < 0) { - for (i = 0; i < s->nb_streams; i++) { - s->streams[i]->mux_ts_offset = - av_rescale_q_rnd(-out->dts, - st->time_base, - s->streams[i]->time_base, - AV_ROUND_UP); - } - } - out->dts += st->mux_ts_offset; - } - if (out->pts != AV_NOPTS_VALUE) - out->pts += st->mux_ts_offset; - } - - return 1; - } else { - av_init_packet(out); - return 0; - } -} - -/** - * Interleave an AVPacket correctly so it can be muxed. - * @param out the interleaved packet will be output here - * @param in the input packet - * @param flush 1 if no further packets are available as input and all - * remaining packets should be output - * @return 1 if a packet was output, 0 if no packet could be output, - * < 0 if an error occurred - */ -static int interleave_packet(AVFormatContext *s, AVPacket *out, AVPacket *in, int flush) -{ - if (s->oformat->interleave_packet) { - int ret = s->oformat->interleave_packet(s, out, in, flush); - if (in) - av_free_packet(in); - return ret; - } else - return ff_interleave_packet_per_dts(s, out, in, flush); -} - -int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt) -{ - int ret, flush = 0; - - if (pkt) { - AVStream *st = s->streams[pkt->stream_index]; - - //FIXME/XXX/HACK drop zero sized packets - if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && pkt->size == 0) - return 0; - - av_dlog(s, "av_interleaved_write_frame size:%d dts:%s pts:%s\n", - pkt->size, av_ts2str(pkt->dts), av_ts2str(pkt->pts)); - if ((ret = compute_pkt_fields2(s, st, pkt)) < 0 && !(s->oformat->flags & AVFMT_NOTIMESTAMPS)) - return ret; - - if (pkt->dts == AV_NOPTS_VALUE && !(s->oformat->flags & AVFMT_NOTIMESTAMPS)) - return AVERROR(EINVAL); - } else { - av_dlog(s, "av_interleaved_write_frame FLUSH\n"); - flush = 1; - } - - for (;; ) { - AVPacket opkt; - int ret = interleave_packet(s, &opkt, pkt, flush); - if (ret <= 0) //FIXME cleanup needed for ret<0 ? - return ret; - - ret = split_write_packet(s, &opkt); - if (ret >= 0) - s->streams[opkt.stream_index]->nb_frames++; - - av_free_packet(&opkt); - pkt = NULL; - - if (ret < 0) - return ret; - if(s->pb && s->pb->error) - return s->pb->error; - } -} - -int av_write_trailer(AVFormatContext *s) -{ - int ret, i; - - for (;; ) { - AVPacket pkt; - ret = interleave_packet(s, &pkt, NULL, 1); - if (ret < 0) //FIXME cleanup needed for ret<0 ? - goto fail; - if (!ret) - break; - - ret = split_write_packet(s, &pkt); - if (ret >= 0) - s->streams[pkt.stream_index]->nb_frames++; - - av_free_packet(&pkt); - - if (ret < 0) - goto fail; - if(s->pb && s->pb->error) - goto fail; - } - - if (s->oformat->write_trailer) - ret = s->oformat->write_trailer(s); - -fail: - if (s->pb) - avio_flush(s->pb); - if (ret == 0) - ret = s->pb ? s->pb->error : 0; - for (i = 0; i < s->nb_streams; i++) { - av_freep(&s->streams[i]->priv_data); - av_freep(&s->streams[i]->index_entries); - } - if (s->oformat->priv_class) - av_opt_free(s->priv_data); - av_freep(&s->priv_data); - return ret; -} - -int av_get_output_timestamp(struct AVFormatContext *s, int stream, - int64_t *dts, int64_t *wall) -{ - if (!s->oformat || !s->oformat->get_output_timestamp) - return AVERROR(ENOSYS); - s->oformat->get_output_timestamp(s, stream, dts, wall); - return 0; -} diff --git a/ffmpeg1/libavformat/mvdec.c b/ffmpeg1/libavformat/mvdec.c deleted file mode 100644 index 5525233..0000000 --- a/ffmpeg1/libavformat/mvdec.c +++ /dev/null @@ -1,441 +0,0 @@ -/* - * Silicon Graphics Movie demuxer - * Copyright (c) 2012 Peter Ross - * - * 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 - */ - -/** - * @file - * Silicon Graphics Movie demuxer - */ - -#include "libavutil/eval.h" -#include "libavutil/intreadwrite.h" -#include "libavutil/rational.h" -#include "avformat.h" -#include "internal.h" - -typedef struct { - int nb_video_tracks; - int nb_audio_tracks; - - int eof_count; /**< number of streams that have finished */ - int stream_index; /**< current stream index */ - int frame[2]; /**< frame nb for current stream */ -} MvContext; - -#define AUDIO_FORMAT_SIGNED 401 - -static int mv_probe(AVProbeData *p) -{ - if (AV_RB32(p->buf) == MKBETAG('M','O','V','I') && AV_RB16(p->buf + 4) < 3) - return AVPROBE_SCORE_MAX; - return 0; -} - -static char * var_read_string(AVIOContext *pb, int size) -{ - char *str = av_malloc(size + 1); - int n; - if (!str) - return NULL; - n = avio_get_str(pb, size, str, size + 1); - if (n < size) - avio_skip(pb, size - n); - return str; -} - -static int var_read_int(AVIOContext *pb, int size) -{ - int v; - char * s = var_read_string(pb, size); - if (!s || sscanf(s, "%d", &v) != 1) - v = 0; - av_free(s); - return v; -} - -static AVRational var_read_float(AVIOContext *pb, int size) -{ - AVRational v; - char * s = var_read_string(pb, size); - if (!s) - return (AVRational){0, 0}; - v = av_d2q(av_strtod(s, NULL), INT_MAX); - av_free(s); - return v; -} - -static void var_read_metadata(AVFormatContext *avctx, const char *tag, int size) -{ - char *value = var_read_string(avctx->pb, size); - if (value) - av_dict_set(&avctx->metadata, tag, value, AV_DICT_DONT_STRDUP_VAL); -} - -static int set_channels(AVFormatContext *avctx, AVStream *st, int channels) { - if (channels <= 0) { - av_log(avctx, AV_LOG_ERROR, "Channel count %d invalid\n", channels); - return AVERROR_INVALIDDATA; - } - st->codec->channels = channels; - st->codec->channel_layout = (st->codec->channels == 1) ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO; - return 0; -} - -/** - * Parse global variable - * @return < 0 if unknown - */ -static int parse_global_var(AVFormatContext *avctx, AVStream *st, const char *name, int size) -{ - MvContext *mv = avctx->priv_data; - AVIOContext *pb = avctx->pb; - if (!strcmp(name, "__NUM_I_TRACKS")) { - mv->nb_video_tracks = var_read_int(pb, size); - } else if (!strcmp(name, "__NUM_A_TRACKS")) { - mv->nb_audio_tracks = var_read_int(pb, size); - } else if (!strcmp(name, "COMMENT") || !strcmp(name, "TITLE")) { - var_read_metadata(avctx, name, size); - } else if (!strcmp(name, "LOOP_MODE") || !strcmp(name, "NUM_LOOPS") || !strcmp(name, "OPTIMIZED")) { - avio_skip(pb, size); // ignore - } else - return -1; - - return 0; -} - -/** - * Parse audio variable - * @return < 0 if unknown - */ -static int parse_audio_var(AVFormatContext *avctx, AVStream *st, const char *name, int size) -{ - AVIOContext *pb = avctx->pb; - if (!strcmp(name, "__DIR_COUNT")) { - st->nb_frames = var_read_int(pb, size); - } else if (!strcmp(name, "AUDIO_FORMAT")) { - st->codec->codec_id = var_read_int(pb, size); - } else if (!strcmp(name, "COMPRESSION")) { - st->codec->codec_tag = var_read_int(pb, size); - } else if (!strcmp(name, "DEFAULT_VOL")) { - var_read_metadata(avctx, name, size); - } else if (!strcmp(name, "NUM_CHANNELS")) { - return set_channels(avctx, st, var_read_int(pb, size)); - } else if (!strcmp(name, "SAMPLE_RATE")) { - st->codec->sample_rate = var_read_int(pb, size); - avpriv_set_pts_info(st, 33, 1, st->codec->sample_rate); - } else if (!strcmp(name, "SAMPLE_WIDTH")) { - st->codec->bits_per_coded_sample = var_read_int(pb, size) * 8; - } else - return -1; - return 0; -} - -/** - * Parse video variable - * @return < 0 if unknown - */ -static int parse_video_var(AVFormatContext *avctx, AVStream *st, const char *name, int size) -{ - AVIOContext *pb = avctx->pb; - if (!strcmp(name, "__DIR_COUNT")) { - st->nb_frames = st->duration = var_read_int(pb, size); - } else if (!strcmp(name, "COMPRESSION")) { - char * str = var_read_string(pb, size); - if (!str) - return AVERROR_INVALIDDATA; - if (!strcmp(str, "1")) { - st->codec->codec_id = AV_CODEC_ID_MVC1; - } else if (!strcmp(str, "2")) { - st->codec->pix_fmt = AV_PIX_FMT_ABGR; - st->codec->codec_id = AV_CODEC_ID_RAWVIDEO; - } else if (!strcmp(str, "3")) { - st->codec->codec_id = AV_CODEC_ID_SGIRLE; - } else if (!strcmp(str, "10")) { - st->codec->codec_id = AV_CODEC_ID_MJPEG; - } else if (!strcmp(str, "MVC2")) { - st->codec->codec_id = AV_CODEC_ID_MVC2; - } else { - avpriv_request_sample(avctx, "video compression %s", str); - } - av_free(str); - } else if (!strcmp(name, "FPS")) { - AVRational fps = var_read_float(pb, size); - avpriv_set_pts_info(st, 64, fps.den, fps.num); - } else if (!strcmp(name, "HEIGHT")) { - st->codec->height = var_read_int(pb, size); - } else if (!strcmp(name, "PIXEL_ASPECT")) { - st->sample_aspect_ratio = var_read_float(pb, size); - av_reduce(&st->sample_aspect_ratio.num, &st->sample_aspect_ratio.den, - st->sample_aspect_ratio.num, st->sample_aspect_ratio.den, INT_MAX); - } else if (!strcmp(name, "WIDTH")) { - st->codec->width = var_read_int(pb, size); - } else if (!strcmp(name, "ORIENTATION")) { - if (var_read_int(pb, size) == 1101) { - st->codec->extradata = av_strdup("BottomUp"); - st->codec->extradata_size = 9; - } - } else if (!strcmp(name, "Q_SPATIAL") || !strcmp(name, "Q_TEMPORAL")) { - var_read_metadata(avctx, name, size); - } else if (!strcmp(name, "INTERLACING") || !strcmp(name, "PACKING")) { - avio_skip(pb, size); // ignore - } else - return -1; - return 0; -} - -static void read_table(AVFormatContext *avctx, AVStream *st, int (*parse)(AVFormatContext *avctx, AVStream *st, const char *name, int size)) -{ - int count, i; - AVIOContext *pb = avctx->pb; - avio_skip(pb, 4); - count = avio_rb32(pb); - avio_skip(pb, 4); - for (i = 0; i < count; i++) { - char name[17]; - int size; - avio_read(pb, name, 16); - name[sizeof(name) - 1] = 0; - size = avio_rb32(pb); - if (parse(avctx, st, name, size) < 0) { - avpriv_request_sample(avctx, "variable %s", name); - avio_skip(pb, size); - } - } -} - -static void read_index(AVIOContext *pb, AVStream *st) -{ - uint64_t timestamp = 0; - int i; - for (i = 0; i < st->nb_frames; i++) { - uint32_t pos = avio_rb32(pb); - uint32_t size = avio_rb32(pb); - avio_skip(pb, 8); - av_add_index_entry(st, pos, timestamp, size, 0, AVINDEX_KEYFRAME); - if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - timestamp += size / (st->codec->channels * 2); - } else { - timestamp++; - } - } -} - -static int mv_read_header(AVFormatContext *avctx) -{ - MvContext *mv = avctx->priv_data; - AVIOContext *pb = avctx->pb; - AVStream *ast = NULL, *vst = NULL; //initialization to suppress warning - int version, i; - - avio_skip(pb, 4); - - version = avio_rb16(pb); - if (version == 2) { - uint64_t timestamp; - int v; - avio_skip(pb, 22); - - /* allocate audio track first to prevent unnecessary seeking - (audio packet always precede video packet for a given frame) */ - ast = avformat_new_stream(avctx, NULL); - if (!ast) - return AVERROR(ENOMEM); - - vst = avformat_new_stream(avctx, NULL); - if (!vst) - return AVERROR(ENOMEM); - vst->codec->codec_type = AVMEDIA_TYPE_VIDEO; - avpriv_set_pts_info(vst, 64, 1, 15); - vst->nb_frames = avio_rb32(pb); - v = avio_rb32(pb); - switch (v) { - case 1: - vst->codec->codec_id = AV_CODEC_ID_MVC1; - break; - case 2: - vst->codec->pix_fmt = AV_PIX_FMT_ARGB; - vst->codec->codec_id = AV_CODEC_ID_RAWVIDEO; - break; - default: - avpriv_request_sample(avctx, "video compression %i", v); - break; - } - vst->codec->codec_tag = 0; - vst->codec->width = avio_rb32(pb); - vst->codec->height = avio_rb32(pb); - avio_skip(pb, 12); - - ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; - ast->nb_frames = vst->nb_frames; - ast->codec->sample_rate = avio_rb32(pb); - avpriv_set_pts_info(ast, 33, 1, ast->codec->sample_rate); - if (set_channels(avctx, ast, avio_rb32(pb)) < 0) - return AVERROR_INVALIDDATA; - - v = avio_rb32(pb); - if (v == AUDIO_FORMAT_SIGNED) { - ast->codec->codec_id = AV_CODEC_ID_PCM_S16BE; - } else { - avpriv_request_sample(avctx, "audio compression (format %i)", v); - } - - avio_skip(pb, 12); - var_read_metadata(avctx, "title", 0x80); - var_read_metadata(avctx, "comment", 0x100); - avio_skip(pb, 0x80); - - timestamp = 0; - for (i = 0; i < vst->nb_frames; i++) { - uint32_t pos = avio_rb32(pb); - uint32_t asize = avio_rb32(pb); - uint32_t vsize = avio_rb32(pb); - avio_skip(pb, 8); - av_add_index_entry(ast, pos, timestamp, asize, 0, AVINDEX_KEYFRAME); - av_add_index_entry(vst, pos + asize, i, vsize, 0, AVINDEX_KEYFRAME); - timestamp += asize / (ast->codec->channels * 2); - } - } else if (!version && avio_rb16(pb) == 3) { - avio_skip(pb, 4); - - read_table(avctx, NULL, parse_global_var); - - if (mv->nb_audio_tracks > 1) { - avpriv_request_sample(avctx, "multiple audio streams support"); - return AVERROR_PATCHWELCOME; - } else if (mv->nb_audio_tracks) { - ast = avformat_new_stream(avctx, NULL); - if (!ast) - return AVERROR(ENOMEM); - ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; - /* temporarily store compression value in codec_tag; format value in codec_id */ - read_table(avctx, ast, parse_audio_var); - if (ast->codec->codec_tag == 100 && ast->codec->codec_id == AUDIO_FORMAT_SIGNED && ast->codec->bits_per_coded_sample == 16) { - ast->codec->codec_id = AV_CODEC_ID_PCM_S16BE; - } else { - avpriv_request_sample(avctx, "audio compression %i (format %i, width %i)", - ast->codec->codec_tag, ast->codec->codec_id, ast->codec->bits_per_coded_sample); - ast->codec->codec_id = AV_CODEC_ID_NONE; - } - ast->codec->codec_tag = 0; - if (ast->codec->channels <= 0) { - av_log(avctx, AV_LOG_ERROR, "No valid channel count found\n"); - return AVERROR_INVALIDDATA; - } - } - - if (mv->nb_video_tracks > 1) { - avpriv_request_sample(avctx, "multiple video streams support"); - return AVERROR_PATCHWELCOME; - } else if (mv->nb_video_tracks) { - vst = avformat_new_stream(avctx, NULL); - if (!vst) - return AVERROR(ENOMEM); - vst->codec->codec_type = AVMEDIA_TYPE_VIDEO; - read_table(avctx, vst, parse_video_var); - } - - if (mv->nb_audio_tracks) - read_index(pb, ast); - - if (mv->nb_video_tracks) - read_index(pb, vst); - } else { - avpriv_request_sample(avctx, "version %i", version); - return AVERROR_PATCHWELCOME; - } - - return 0; -} - -static int mv_read_packet(AVFormatContext *avctx, AVPacket *pkt) -{ - MvContext *mv = avctx->priv_data; - AVIOContext *pb = avctx->pb; - AVStream *st = avctx->streams[mv->stream_index]; - const AVIndexEntry *index; - int frame = mv->frame[mv->stream_index]; - int ret; - uint64_t pos; - - if (frame < st->nb_index_entries) { - index = &st->index_entries[frame]; - pos = avio_tell(pb); - if (index->pos > pos) - avio_skip(pb, index->pos - pos); - else if (index->pos < pos) { - if (!pb->seekable) - return AVERROR(EIO); - ret = avio_seek(pb, index->pos, SEEK_SET); - if (ret < 0) - return ret; - } - ret = av_get_packet(pb, pkt, index->size); - if (ret < 0) - return ret; - - pkt->stream_index = mv->stream_index; - pkt->pts = index->timestamp; - pkt->flags |= AV_PKT_FLAG_KEY; - - mv->frame[mv->stream_index]++; - mv->eof_count = 0; - } else { - mv->eof_count++; - if (mv->eof_count >= avctx->nb_streams) - return AVERROR_EOF; - } - - mv->stream_index++; - if (mv->stream_index >= avctx->nb_streams) - mv->stream_index = 0; - - return 0; -} - -static int mv_read_seek(AVFormatContext *avctx, int stream_index, int64_t timestamp, int flags) -{ - MvContext *mv = avctx->priv_data; - AVStream *st = avctx->streams[stream_index]; - int frame, i; - - if ((flags & AVSEEK_FLAG_FRAME) || (flags & AVSEEK_FLAG_BYTE)) - return AVERROR(ENOSYS); - - if (!avctx->pb->seekable) - return AVERROR(EIO); - - frame = av_index_search_timestamp(st, timestamp, flags); - if (frame < 0) - return -1; - - for (i = 0; i < avctx->nb_streams; i++) - mv->frame[i] = frame; - return 0; -} - -AVInputFormat ff_mv_demuxer = { - .name = "mv", - .long_name = NULL_IF_CONFIG_SMALL("Silicon Graphics Movie"), - .priv_data_size = sizeof(MvContext), - .read_probe = mv_probe, - .read_header = mv_read_header, - .read_packet = mv_read_packet, - .read_seek = mv_read_seek, -}; diff --git a/ffmpeg1/libavformat/mvi.c b/ffmpeg1/libavformat/mvi.c deleted file mode 100644 index 953c182..0000000 --- a/ffmpeg1/libavformat/mvi.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Motion Pixels MVI Demuxer - * Copyright (c) 2008 Gregory Montoir (cyx@users.sourceforge.net) - * - * 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 "libavutil/channel_layout.h" -#include "avformat.h" -#include "internal.h" - -#define MVI_FRAC_BITS 10 - -#define MVI_AUDIO_STREAM_INDEX 0 -#define MVI_VIDEO_STREAM_INDEX 1 - -typedef struct MviDemuxContext { - unsigned int (*get_int)(AVIOContext *); - uint32_t audio_data_size; - uint64_t audio_size_counter; - uint64_t audio_frame_size; - int audio_size_left; - int video_frame_size; -} MviDemuxContext; - -static int read_header(AVFormatContext *s) -{ - MviDemuxContext *mvi = s->priv_data; - AVIOContext *pb = s->pb; - AVStream *ast, *vst; - unsigned int version, frames_count, msecs_per_frame, player_version; - - ast = avformat_new_stream(s, NULL); - if (!ast) - return AVERROR(ENOMEM); - - vst = avformat_new_stream(s, NULL); - if (!vst) - return AVERROR(ENOMEM); - - vst->codec->extradata_size = 2; - vst->codec->extradata = av_mallocz(2 + FF_INPUT_BUFFER_PADDING_SIZE); - if (!vst->codec->extradata) - return AVERROR(ENOMEM); - - version = avio_r8(pb); - vst->codec->extradata[0] = avio_r8(pb); - vst->codec->extradata[1] = avio_r8(pb); - frames_count = avio_rl32(pb); - msecs_per_frame = avio_rl32(pb); - vst->codec->width = avio_rl16(pb); - vst->codec->height = avio_rl16(pb); - avio_r8(pb); - ast->codec->sample_rate = avio_rl16(pb); - mvi->audio_data_size = avio_rl32(pb); - avio_r8(pb); - player_version = avio_rl32(pb); - avio_rl16(pb); - avio_r8(pb); - - if (frames_count == 0 || mvi->audio_data_size == 0) - return AVERROR_INVALIDDATA; - - if (version != 7 || player_version > 213) { - av_log(s, AV_LOG_ERROR, "unhandled version (%d,%d)\n", version, player_version); - return AVERROR_INVALIDDATA; - } - - avpriv_set_pts_info(ast, 64, 1, ast->codec->sample_rate); - ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; - ast->codec->codec_id = AV_CODEC_ID_PCM_U8; - ast->codec->channels = 1; - ast->codec->channel_layout = AV_CH_LAYOUT_MONO; - ast->codec->bits_per_coded_sample = 8; - ast->codec->bit_rate = ast->codec->sample_rate * 8; - - avpriv_set_pts_info(vst, 64, msecs_per_frame, 1000000); - vst->avg_frame_rate = av_inv_q(vst->time_base); - vst->codec->codec_type = AVMEDIA_TYPE_VIDEO; - vst->codec->codec_id = AV_CODEC_ID_MOTIONPIXELS; - - mvi->get_int = (vst->codec->width * vst->codec->height < (1 << 16)) ? avio_rl16 : avio_rl24; - - mvi->audio_frame_size = ((uint64_t)mvi->audio_data_size << MVI_FRAC_BITS) / frames_count; - if (!mvi->audio_frame_size) { - av_log(s, AV_LOG_ERROR, "audio_frame_size is 0\n"); - return AVERROR_INVALIDDATA; - } - mvi->audio_size_counter = (ast->codec->sample_rate * 830 / mvi->audio_frame_size - 1) * mvi->audio_frame_size; - mvi->audio_size_left = mvi->audio_data_size; - - return 0; -} - -static int read_packet(AVFormatContext *s, AVPacket *pkt) -{ - int ret, count; - MviDemuxContext *mvi = s->priv_data; - AVIOContext *pb = s->pb; - - if (mvi->video_frame_size == 0) { - mvi->video_frame_size = (mvi->get_int)(pb); - if (mvi->audio_size_left == 0) - return AVERROR(EIO); - count = (mvi->audio_size_counter + mvi->audio_frame_size + 512) >> MVI_FRAC_BITS; - if (count > mvi->audio_size_left) - count = mvi->audio_size_left; - if ((ret = av_get_packet(pb, pkt, count)) < 0) - return ret; - pkt->stream_index = MVI_AUDIO_STREAM_INDEX; - mvi->audio_size_left -= count; - mvi->audio_size_counter += mvi->audio_frame_size - (count << MVI_FRAC_BITS); - } else { - if ((ret = av_get_packet(pb, pkt, mvi->video_frame_size)) < 0) - return ret; - pkt->stream_index = MVI_VIDEO_STREAM_INDEX; - mvi->video_frame_size = 0; - } - return 0; -} - -AVInputFormat ff_mvi_demuxer = { - .name = "mvi", - .long_name = NULL_IF_CONFIG_SMALL("Motion Pixels MVI"), - .priv_data_size = sizeof(MviDemuxContext), - .read_header = read_header, - .read_packet = read_packet, - .extensions = "mvi", -}; diff --git a/ffmpeg1/libavformat/mxf.c b/ffmpeg1/libavformat/mxf.c deleted file mode 100644 index 4a4158a..0000000 --- a/ffmpeg1/libavformat/mxf.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * MXF - * Copyright (c) 2006 SmartJog S.A., Baptiste Coudurier - * - * 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 "libavutil/common.h" -#include "mxf.h" - -/** - * SMPTE RP224 http://www.smpte-ra.org/mdd/index.html - */ -const MXFCodecUL ff_mxf_data_definition_uls[] = { - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x01,0x03,0x02,0x02,0x01,0x00,0x00,0x00 }, 13, AVMEDIA_TYPE_VIDEO }, - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x01,0x03,0x02,0x02,0x02,0x00,0x00,0x00 }, 13, AVMEDIA_TYPE_AUDIO }, - { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, AVMEDIA_TYPE_DATA }, -}; - -const MXFCodecUL ff_mxf_codec_uls[] = { - /* PictureEssenceCoding */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x01,0x11,0x00 }, 14, AV_CODEC_ID_MPEG2VIDEO }, /* MP@ML Long GoP */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x01 }, 14, AV_CODEC_ID_MPEG2VIDEO }, /* D-10 50Mbps PAL */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x03,0x03,0x00 }, 14, AV_CODEC_ID_MPEG2VIDEO }, /* MP@HL Long GoP */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x04,0x02,0x00 }, 14, AV_CODEC_ID_MPEG2VIDEO }, /* 422P@HL I-Frame */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x20,0x02,0x03 }, 14, AV_CODEC_ID_MPEG4 }, /* XDCAM proxy_pal030926.mxf */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x01,0x02,0x00 }, 13, AV_CODEC_ID_DVVIDEO }, /* DV25 IEC PAL */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x07,0x04,0x01,0x02,0x02,0x03,0x01,0x01,0x00 }, 14, AV_CODEC_ID_JPEG2000 }, /* JPEG2000 Codestream */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x01,0x7F,0x00,0x00,0x00 }, 13, AV_CODEC_ID_RAWVIDEO }, /* Uncompressed */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x01,0x01,0x02,0x01,0x00 }, 15, AV_CODEC_ID_RAWVIDEO }, /* Uncompressed 422 8-bit */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x71,0x00,0x00,0x00 }, 13, AV_CODEC_ID_DNXHD }, /* SMPTE VC-3/DNxHD */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x03,0x02,0x00,0x00 }, 14, AV_CODEC_ID_DNXHD }, /* SMPTE VC-3/DNxHD */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x01,0x32,0x00,0x00 }, 14, AV_CODEC_ID_H264 }, /* H.264/MPEG-4 AVC Intra */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x01,0x01,0x02,0x02,0x01 }, 16, AV_CODEC_ID_V210 }, /* V210 */ - /* SoundEssenceCompression */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 }, 13, AV_CODEC_ID_PCM_S16LE }, /* Uncompressed */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x7F,0x00,0x00,0x00 }, 13, AV_CODEC_ID_PCM_S16LE }, - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x07,0x04,0x02,0x02,0x01,0x7E,0x00,0x00,0x00 }, 13, AV_CODEC_ID_PCM_S16BE }, /* From Omneon MXF file */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x04,0x04,0x02,0x02,0x02,0x03,0x01,0x01,0x00 }, 15, AV_CODEC_ID_PCM_ALAW }, /* XDCAM Proxy C0023S01.mxf */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x02,0x03,0x02,0x01,0x00 }, 15, AV_CODEC_ID_AC3 }, - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x02,0x03,0x02,0x05,0x00 }, 15, AV_CODEC_ID_MP2 }, /* MP2 or MP3 */ - //{ { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x02,0x03,0x02,0x1C,0x00 }, 15, AV_CODEC_ID_DOLBY_E }, /* Dolby-E */ - { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, AV_CODEC_ID_NONE }, -}; - -const MXFCodecUL ff_mxf_pixel_format_uls[] = { - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x01,0x01,0x02,0x01,0x01 }, 16, AV_PIX_FMT_UYVY422 }, - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x01,0x01,0x02,0x01,0x02 }, 16, AV_PIX_FMT_YUYV422 }, - { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, AV_PIX_FMT_NONE }, -}; - -static const struct { - enum AVPixelFormat pix_fmt; - const char data[16]; -} ff_mxf_pixel_layouts[] = { - /** - * See SMPTE 377M E.2.46 - * - * Note: Only RGB, palette based and "abnormal" YUV pixel formats like 4:2:2:4 go here. - * For regular YUV, use CDCIPictureEssenceDescriptor. - * - * Note: Do not use these for encoding descriptors for little-endian formats until we - * get samples or official word from SMPTE on how/if those can be encoded. - */ - {AV_PIX_FMT_ABGR, {'A', 8, 'B', 8, 'G', 8, 'R', 8 }}, - {AV_PIX_FMT_ARGB, {'A', 8, 'R', 8, 'G', 8, 'B', 8 }}, - {AV_PIX_FMT_BGR24, {'B', 8, 'G', 8, 'R', 8 }}, - {AV_PIX_FMT_BGRA, {'B', 8, 'G', 8, 'R', 8, 'A', 8 }}, - {AV_PIX_FMT_RGB24, {'R', 8, 'G', 8, 'B', 8 }}, - {AV_PIX_FMT_RGB444BE,{'F', 4, 'R', 4, 'G', 4, 'B', 4 }}, - {AV_PIX_FMT_RGB48BE, {'R', 8, 'r', 8, 'G', 8, 'g', 8, 'B', 8, 'b', 8 }}, - {AV_PIX_FMT_RGB48BE, {'R', 16, 'G', 16, 'B', 16 }}, - {AV_PIX_FMT_RGB48LE, {'r', 8, 'R', 8, 'g', 8, 'G', 8, 'b', 8, 'B', 8 }}, - {AV_PIX_FMT_RGB555BE,{'F', 1, 'R', 5, 'G', 5, 'B', 5 }}, - {AV_PIX_FMT_RGB565BE,{'R', 5, 'G', 6, 'B', 5 }}, - {AV_PIX_FMT_RGBA, {'R', 8, 'G', 8, 'B', 8, 'A', 8 }}, - {AV_PIX_FMT_PAL8, {'P', 8 }}, -}; - -static const int num_pixel_layouts = FF_ARRAY_ELEMS(ff_mxf_pixel_layouts); - -int ff_mxf_decode_pixel_layout(const char pixel_layout[16], enum AVPixelFormat *pix_fmt) -{ - int x; - - for(x = 0; x < num_pixel_layouts; x++) { - if (!memcmp(pixel_layout, ff_mxf_pixel_layouts[x].data, 16)) { - *pix_fmt = ff_mxf_pixel_layouts[x].pix_fmt; - return 0; - } - } - - return -1; -} - -static const MXFSamplesPerFrame mxf_samples_per_frames[] = { - { { 1001, 24000 }, { 2002, 0, 0, 0, 0, 0 } }, // FILM 23.976 - { { 1, 24}, { 2000, 0, 0, 0, 0, 0 } }, // FILM 24 - { { 1001, 30000 }, { 1602, 1601, 1602, 1601, 1602, 0 } }, // NTSC 29.97 - { { 1001, 60000 }, { 801, 801, 801, 801, 800, 0 } }, // NTSC 59.94 - { { 1, 25 }, { 1920, 0, 0, 0, 0, 0 } }, // PAL 25 - { { 1, 50 }, { 960, 0, 0, 0, 0, 0 } }, // PAL 50 -}; - -const MXFSamplesPerFrame *ff_mxf_get_samples_per_frame(AVFormatContext *s, AVRational time_base) -{ - int i; - for (i = 0; i < FF_ARRAY_ELEMS(mxf_samples_per_frames); i++) { - if (!av_cmp_q(mxf_samples_per_frames[i].time_base, time_base)) - return &mxf_samples_per_frames[i]; - } - - // Find closest container time base for approximative codec time base like 1/29.97, 1/30, ... - for (i = 0; i < FF_ARRAY_ELEMS(mxf_samples_per_frames); i++) { - if (fabs(av_q2d(mxf_samples_per_frames[i].time_base) - av_q2d(time_base)) < 0.0001) { - av_log(s, AV_LOG_WARNING, "%d/%d input time base matched %d/%d container time base\n", - time_base.num, time_base.den, - mxf_samples_per_frames[i].time_base.num, mxf_samples_per_frames[i].time_base.den); - return &mxf_samples_per_frames[i]; - } - } - return NULL; -} diff --git a/ffmpeg1/libavformat/mxf.h b/ffmpeg1/libavformat/mxf.h deleted file mode 100644 index 4c751e8..0000000 --- a/ffmpeg1/libavformat/mxf.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * MXF - * Copyright (c) 2006 SmartJog S.A., Baptiste Coudurier - * - * 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 AVFORMAT_MXF_H -#define AVFORMAT_MXF_H - -#include "avformat.h" -#include "libavcodec/avcodec.h" -#include - -typedef uint8_t UID[16]; - -enum MXFMetadataSetType { - AnyType, - MaterialPackage, - SourcePackage, - SourceClip, - TimecodeComponent, - Sequence, - MultipleDescriptor, - Descriptor, - Track, - CryptoContext, - Preface, - Identification, - ContentStorage, - SubDescriptor, - IndexTableSegment, - EssenceContainerData, - TypeBottom,// add metadata type before this -}; - -enum MXFFrameLayout { - FullFrame = 0, - SeparateFields, - OneField, - MixedFields, - SegmentedFrame, -}; - -typedef struct KLVPacket { - UID key; - int64_t offset; - uint64_t length; -} KLVPacket; - -typedef struct MXFCodecUL { - UID uid; - unsigned matching_len; - int id; -} MXFCodecUL; - -typedef struct { - struct AVRational time_base; - int samples_per_frame[6]; -} MXFSamplesPerFrame; - -extern const MXFCodecUL ff_mxf_data_definition_uls[]; -extern const MXFCodecUL ff_mxf_codec_uls[]; -extern const MXFCodecUL ff_mxf_pixel_format_uls[]; - -int ff_mxf_decode_pixel_layout(const char pixel_layout[16], enum AVPixelFormat *pix_fmt); -const MXFSamplesPerFrame *ff_mxf_get_samples_per_frame(AVFormatContext *s, AVRational time_base); - -#define PRINT_KEY(pc, s, x) av_dlog(pc, "%s %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n", s, \ - (x)[0], (x)[1], (x)[2], (x)[3], (x)[4], (x)[5], (x)[6], (x)[7], (x)[8], (x)[9], (x)[10], (x)[11], (x)[12], (x)[13], (x)[14], (x)[15]) - -#endif /* AVFORMAT_MXF_H */ diff --git a/ffmpeg1/libavformat/mxfdec.c b/ffmpeg1/libavformat/mxfdec.c deleted file mode 100644 index 4580e1b..0000000 --- a/ffmpeg1/libavformat/mxfdec.c +++ /dev/null @@ -1,2392 +0,0 @@ -/* - * MXF demuxer. - * Copyright (c) 2006 SmartJog S.A., Baptiste Coudurier - * - * 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 - */ - -/* - * References - * SMPTE 336M KLV Data Encoding Protocol Using Key-Length-Value - * SMPTE 377M MXF File Format Specifications - * SMPTE 378M Operational Pattern 1a - * SMPTE 379M MXF Generic Container - * SMPTE 381M Mapping MPEG Streams into the MXF Generic Container - * SMPTE 382M Mapping AES3 and Broadcast Wave Audio into the MXF Generic Container - * SMPTE 383M Mapping DV-DIF Data to the MXF Generic Container - * - * Principle - * Search for Track numbers which will identify essence element KLV packets. - * Search for SourcePackage which define tracks which contains Track numbers. - * Material Package contains tracks with reference to SourcePackage tracks. - * Search for Descriptors (Picture, Sound) which contains codec info and parameters. - * Assign Descriptors to correct Tracks. - * - * Metadata reading functions read Local Tags, get InstanceUID(0x3C0A) then add MetaDataSet to MXFContext. - * Metadata parsing resolves Strong References to objects. - * - * Simple demuxer, only OP1A supported and some files might not work at all. - * Only tracks with associated descriptors will be decoded. "Highly Desirable" SMPTE 377M D.1 - */ - -//#define DEBUG - -#include "libavutil/aes.h" -#include "libavutil/avassert.h" -#include "libavutil/mathematics.h" -#include "libavcodec/bytestream.h" -#include "libavutil/timecode.h" -#include "avformat.h" -#include "internal.h" -#include "mxf.h" - -typedef enum { - Header, - BodyPartition, - Footer -} MXFPartitionType; - -typedef enum { - OP1a = 1, - OP1b, - OP1c, - OP2a, - OP2b, - OP2c, - OP3a, - OP3b, - OP3c, - OPAtom, - OPSONYOpt, /* FATE sample, violates the spec in places */ -} MXFOP; - -typedef struct { - int closed; - int complete; - MXFPartitionType type; - uint64_t previous_partition; - int index_sid; - int body_sid; - int64_t this_partition; - int64_t essence_offset; ///< absolute offset of essence - int64_t essence_length; - int32_t kag_size; - int64_t header_byte_count; - int64_t index_byte_count; - int pack_length; -} MXFPartition; - -typedef struct { - UID uid; - enum MXFMetadataSetType type; - UID source_container_ul; -} MXFCryptoContext; - -typedef struct { - UID uid; - enum MXFMetadataSetType type; - UID source_package_uid; - UID data_definition_ul; - int64_t duration; - int64_t start_position; - int source_track_id; -} MXFStructuralComponent; - -typedef struct { - UID uid; - enum MXFMetadataSetType type; - UID data_definition_ul; - UID *structural_components_refs; - int structural_components_count; - int64_t duration; -} MXFSequence; - -typedef struct { - UID uid; - enum MXFMetadataSetType type; - int drop_frame; - int start_frame; - struct AVRational rate; - AVTimecode tc; -} MXFTimecodeComponent; - -typedef struct { - UID uid; - enum MXFMetadataSetType type; - MXFSequence *sequence; /* mandatory, and only one */ - UID sequence_ref; - int track_id; - uint8_t track_number[4]; - AVRational edit_rate; - int intra_only; - uint64_t sample_count; - int64_t original_duration; ///< duration before multiplying st->duration by SampleRate/EditRate -} MXFTrack; - -typedef struct { - UID uid; - enum MXFMetadataSetType type; - UID essence_container_ul; - UID essence_codec_ul; - AVRational sample_rate; - AVRational aspect_ratio; - int width; - int height; /* Field height, not frame height */ - int frame_layout; /* See MXFFrameLayout enum */ - int channels; - int bits_per_sample; - int field_dominance; - unsigned int component_depth; - unsigned int horiz_subsampling; - unsigned int vert_subsampling; - UID *sub_descriptors_refs; - int sub_descriptors_count; - int linked_track_id; - uint8_t *extradata; - int extradata_size; - enum AVPixelFormat pix_fmt; -} MXFDescriptor; - -typedef struct { - UID uid; - enum MXFMetadataSetType type; - int edit_unit_byte_count; - int index_sid; - int body_sid; - AVRational index_edit_rate; - uint64_t index_start_position; - uint64_t index_duration; - int8_t *temporal_offset_entries; - int *flag_entries; - uint64_t *stream_offset_entries; - int nb_index_entries; -} MXFIndexTableSegment; - -typedef struct { - UID uid; - enum MXFMetadataSetType type; - UID package_uid; - UID *tracks_refs; - int tracks_count; - MXFDescriptor *descriptor; /* only one */ - UID descriptor_ref; -} MXFPackage; - -typedef struct { - UID uid; - enum MXFMetadataSetType type; -} MXFMetadataSet; - -/* decoded index table */ -typedef struct { - int index_sid; - int body_sid; - int nb_ptses; /* number of PTSes or total duration of index */ - int64_t first_dts; /* DTS = EditUnit + first_dts */ - int64_t *ptses; /* maps EditUnit -> PTS */ - int nb_segments; - MXFIndexTableSegment **segments; /* sorted by IndexStartPosition */ - AVIndexEntry *fake_index; /* used for calling ff_index_search_timestamp() */ -} MXFIndexTable; - -typedef struct { - MXFPartition *partitions; - unsigned partitions_count; - MXFOP op; - UID *packages_refs; - int packages_count; - MXFMetadataSet **metadata_sets; - int metadata_sets_count; - AVFormatContext *fc; - struct AVAES *aesc; - uint8_t *local_tags; - int local_tags_count; - uint64_t footer_partition; - KLVPacket current_klv_data; - int current_klv_index; - int run_in; - MXFPartition *current_partition; - int parsing_backward; - int64_t last_forward_tell; - int last_forward_partition; - int current_edit_unit; - int nb_index_tables; - MXFIndexTable *index_tables; - int edit_units_per_packet; ///< how many edit units to read at a time (PCM, OPAtom) -} MXFContext; - -enum MXFWrappingScheme { - Frame, - Clip, -}; - -/* NOTE: klv_offset is not set (-1) for local keys */ -typedef int MXFMetadataReadFunc(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset); - -typedef struct { - const UID key; - MXFMetadataReadFunc *read; - int ctx_size; - enum MXFMetadataSetType type; -} MXFMetadataReadTableEntry; - -static int mxf_read_close(AVFormatContext *s); - -/* partial keys to match */ -static const uint8_t mxf_header_partition_pack_key[] = { 0x06,0x0e,0x2b,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02 }; -static const uint8_t mxf_essence_element_key[] = { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01 }; -static const uint8_t mxf_avid_essence_element_key[] = { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0e,0x04,0x03,0x01 }; -static const uint8_t mxf_system_item_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x03,0x01,0x04 }; -static const uint8_t mxf_klv_key[] = { 0x06,0x0e,0x2b,0x34 }; -/* complete keys to match */ -static const uint8_t mxf_crypto_source_container_ul[] = { 0x06,0x0e,0x2b,0x34,0x01,0x01,0x01,0x09,0x06,0x01,0x01,0x02,0x02,0x00,0x00,0x00 }; -static const uint8_t mxf_encrypted_triplet_key[] = { 0x06,0x0e,0x2b,0x34,0x02,0x04,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x7e,0x01,0x00 }; -static const uint8_t mxf_encrypted_essence_container[] = { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x07,0x0d,0x01,0x03,0x01,0x02,0x0b,0x01,0x00 }; -static const uint8_t mxf_sony_mpeg4_extradata[] = { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0e,0x06,0x06,0x02,0x02,0x01,0x00,0x00 }; - -#define IS_KLV_KEY(x, y) (!memcmp(x, y, sizeof(y))) - -static int64_t klv_decode_ber_length(AVIOContext *pb) -{ - uint64_t size = avio_r8(pb); - if (size & 0x80) { /* long form */ - int bytes_num = size & 0x7f; - /* SMPTE 379M 5.3.4 guarantee that bytes_num must not exceed 8 bytes */ - if (bytes_num > 8) - return AVERROR_INVALIDDATA; - size = 0; - while (bytes_num--) - size = size << 8 | avio_r8(pb); - } - return size; -} - -static int mxf_read_sync(AVIOContext *pb, const uint8_t *key, unsigned size) -{ - int i, b; - for (i = 0; i < size && !url_feof(pb); i++) { - b = avio_r8(pb); - if (b == key[0]) - i = 0; - else if (b != key[i]) - i = -1; - } - return i == size; -} - -static int klv_read_packet(KLVPacket *klv, AVIOContext *pb) -{ - if (!mxf_read_sync(pb, mxf_klv_key, 4)) - return AVERROR_INVALIDDATA; - klv->offset = avio_tell(pb) - 4; - memcpy(klv->key, mxf_klv_key, 4); - avio_read(pb, klv->key + 4, 12); - klv->length = klv_decode_ber_length(pb); - return klv->length == -1 ? -1 : 0; -} - -static int mxf_get_stream_index(AVFormatContext *s, KLVPacket *klv) -{ - int i; - - for (i = 0; i < s->nb_streams; i++) { - MXFTrack *track = s->streams[i]->priv_data; - /* SMPTE 379M 7.3 */ - if (!memcmp(klv->key + sizeof(mxf_essence_element_key), track->track_number, sizeof(track->track_number))) - return i; - } - /* return 0 if only one stream, for OP Atom files with 0 as track number */ - return s->nb_streams == 1 ? 0 : -1; -} - -/* XXX: use AVBitStreamFilter */ -static int mxf_get_d10_aes3_packet(AVIOContext *pb, AVStream *st, AVPacket *pkt, int64_t length) -{ - const uint8_t *buf_ptr, *end_ptr; - uint8_t *data_ptr; - int i; - - if (length > 61444) /* worst case PAL 1920 samples 8 channels */ - return AVERROR_INVALIDDATA; - length = av_get_packet(pb, pkt, length); - if (length < 0) - return length; - data_ptr = pkt->data; - end_ptr = pkt->data + length; - buf_ptr = pkt->data + 4; /* skip SMPTE 331M header */ - for (; buf_ptr + st->codec->channels*4 <= end_ptr; ) { - for (i = 0; i < st->codec->channels; i++) { - uint32_t sample = bytestream_get_le32(&buf_ptr); - if (st->codec->bits_per_coded_sample == 24) - bytestream_put_le24(&data_ptr, (sample >> 4) & 0xffffff); - else - bytestream_put_le16(&data_ptr, (sample >> 12) & 0xffff); - } - buf_ptr += 32 - st->codec->channels*4; // always 8 channels stored SMPTE 331M - } - av_shrink_packet(pkt, data_ptr - pkt->data); - return 0; -} - -static int mxf_decrypt_triplet(AVFormatContext *s, AVPacket *pkt, KLVPacket *klv) -{ - static const uint8_t checkv[16] = {0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b, 0x43, 0x48, 0x55, 0x4b}; - MXFContext *mxf = s->priv_data; - AVIOContext *pb = s->pb; - int64_t end = avio_tell(pb) + klv->length; - int64_t size; - uint64_t orig_size; - uint64_t plaintext_size; - uint8_t ivec[16]; - uint8_t tmpbuf[16]; - int index; - - if (!mxf->aesc && s->key && s->keylen == 16) { - mxf->aesc = av_aes_alloc(); - if (!mxf->aesc) - return AVERROR(ENOMEM); - av_aes_init(mxf->aesc, s->key, 128, 1); - } - // crypto context - avio_skip(pb, klv_decode_ber_length(pb)); - // plaintext offset - klv_decode_ber_length(pb); - plaintext_size = avio_rb64(pb); - // source klv key - klv_decode_ber_length(pb); - avio_read(pb, klv->key, 16); - if (!IS_KLV_KEY(klv, mxf_essence_element_key)) - return AVERROR_INVALIDDATA; - index = mxf_get_stream_index(s, klv); - if (index < 0) - return AVERROR_INVALIDDATA; - // source size - klv_decode_ber_length(pb); - orig_size = avio_rb64(pb); - if (orig_size < plaintext_size) - return AVERROR_INVALIDDATA; - // enc. code - size = klv_decode_ber_length(pb); - if (size < 32 || size - 32 < orig_size) - return AVERROR_INVALIDDATA; - avio_read(pb, ivec, 16); - avio_read(pb, tmpbuf, 16); - if (mxf->aesc) - av_aes_crypt(mxf->aesc, tmpbuf, tmpbuf, 1, ivec, 1); - if (memcmp(tmpbuf, checkv, 16)) - av_log(s, AV_LOG_ERROR, "probably incorrect decryption key\n"); - size -= 32; - size = av_get_packet(pb, pkt, size); - if (size < 0) - return size; - else if (size < plaintext_size) - return AVERROR_INVALIDDATA; - size -= plaintext_size; - if (mxf->aesc) - av_aes_crypt(mxf->aesc, &pkt->data[plaintext_size], - &pkt->data[plaintext_size], size >> 4, ivec, 1); - av_shrink_packet(pkt, orig_size); - pkt->stream_index = index; - avio_skip(pb, end - avio_tell(pb)); - return 0; -} - -static int mxf_read_primer_pack(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset) -{ - MXFContext *mxf = arg; - int item_num = avio_rb32(pb); - int item_len = avio_rb32(pb); - - if (item_len != 18) { - avpriv_request_sample(pb, "Primer pack item length %d", item_len); - return AVERROR_PATCHWELCOME; - } - if (item_num > 65536) { - av_log(mxf->fc, AV_LOG_ERROR, "item_num %d is too large\n", item_num); - return AVERROR_INVALIDDATA; - } - mxf->local_tags = av_calloc(item_num, item_len); - if (!mxf->local_tags) - return AVERROR(ENOMEM); - mxf->local_tags_count = item_num; - avio_read(pb, mxf->local_tags, item_num*item_len); - return 0; -} - -static int mxf_read_partition_pack(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset) -{ - MXFContext *mxf = arg; - MXFPartition *partition, *tmp_part; - UID op; - uint64_t footer_partition; - uint32_t nb_essence_containers; - - if (mxf->partitions_count+1 >= UINT_MAX / sizeof(*mxf->partitions)) - return AVERROR(ENOMEM); - - tmp_part = av_realloc(mxf->partitions, (mxf->partitions_count + 1) * sizeof(*mxf->partitions)); - if (!tmp_part) - return AVERROR(ENOMEM); - mxf->partitions = tmp_part; - - if (mxf->parsing_backward) { - /* insert the new partition pack in the middle - * this makes the entries in mxf->partitions sorted by offset */ - memmove(&mxf->partitions[mxf->last_forward_partition+1], - &mxf->partitions[mxf->last_forward_partition], - (mxf->partitions_count - mxf->last_forward_partition)*sizeof(*mxf->partitions)); - partition = mxf->current_partition = &mxf->partitions[mxf->last_forward_partition]; - } else { - mxf->last_forward_partition++; - partition = mxf->current_partition = &mxf->partitions[mxf->partitions_count]; - } - - memset(partition, 0, sizeof(*partition)); - mxf->partitions_count++; - partition->pack_length = avio_tell(pb) - klv_offset + size; - - switch(uid[13]) { - case 2: - partition->type = Header; - break; - case 3: - partition->type = BodyPartition; - break; - case 4: - partition->type = Footer; - break; - default: - av_log(mxf->fc, AV_LOG_ERROR, "unknown partition type %i\n", uid[13]); - return AVERROR_INVALIDDATA; - } - - /* consider both footers to be closed (there is only Footer and CompleteFooter) */ - partition->closed = partition->type == Footer || !(uid[14] & 1); - partition->complete = uid[14] > 2; - avio_skip(pb, 4); - partition->kag_size = avio_rb32(pb); - partition->this_partition = avio_rb64(pb); - partition->previous_partition = avio_rb64(pb); - footer_partition = avio_rb64(pb); - partition->header_byte_count = avio_rb64(pb); - partition->index_byte_count = avio_rb64(pb); - partition->index_sid = avio_rb32(pb); - avio_skip(pb, 8); - partition->body_sid = avio_rb32(pb); - avio_read(pb, op, sizeof(UID)); - nb_essence_containers = avio_rb32(pb); - - /* some files don'thave FooterPartition set in every partition */ - if (footer_partition) { - if (mxf->footer_partition && mxf->footer_partition != footer_partition) { - av_log(mxf->fc, AV_LOG_ERROR, - "inconsistent FooterPartition value: %"PRIu64" != %"PRIu64"\n", - mxf->footer_partition, footer_partition); - } else { - mxf->footer_partition = footer_partition; - } - } - - av_dlog(mxf->fc, - "PartitionPack: ThisPartition = 0x%"PRIX64 - ", PreviousPartition = 0x%"PRIX64", " - "FooterPartition = 0x%"PRIX64", IndexSID = %i, BodySID = %i\n", - partition->this_partition, - partition->previous_partition, footer_partition, - partition->index_sid, partition->body_sid); - - /* sanity check PreviousPartition if set */ - if (partition->previous_partition && - mxf->run_in + partition->previous_partition >= klv_offset) { - av_log(mxf->fc, AV_LOG_ERROR, - "PreviousPartition points to this partition or forward\n"); - return AVERROR_INVALIDDATA; - } - - if (op[12] == 1 && op[13] == 1) mxf->op = OP1a; - else if (op[12] == 1 && op[13] == 2) mxf->op = OP1b; - else if (op[12] == 1 && op[13] == 3) mxf->op = OP1c; - else if (op[12] == 2 && op[13] == 1) mxf->op = OP2a; - else if (op[12] == 2 && op[13] == 2) mxf->op = OP2b; - else if (op[12] == 2 && op[13] == 3) mxf->op = OP2c; - else if (op[12] == 3 && op[13] == 1) mxf->op = OP3a; - else if (op[12] == 3 && op[13] == 2) mxf->op = OP3b; - else if (op[12] == 3 && op[13] == 3) mxf->op = OP3c; - else if (op[12] == 64&& op[13] == 1) mxf->op = OPSONYOpt; - else if (op[12] == 0x10) { - /* SMPTE 390m: "There shall be exactly one essence container" - * The following block deals with files that violate this, namely: - * 2011_DCPTEST_24FPS.V.mxf - two ECs, OP1a - * abcdefghiv016f56415e.mxf - zero ECs, OPAtom, output by Avid AirSpeed */ - if (nb_essence_containers != 1) { - MXFOP op = nb_essence_containers ? OP1a : OPAtom; - - /* only nag once */ - if (!mxf->op) - av_log(mxf->fc, AV_LOG_WARNING, "\"OPAtom\" with %u ECs - assuming %s\n", - nb_essence_containers, op == OP1a ? "OP1a" : "OPAtom"); - - mxf->op = op; - } else - mxf->op = OPAtom; - } else { - av_log(mxf->fc, AV_LOG_ERROR, "unknown operational pattern: %02xh %02xh - guessing OP1a\n", op[12], op[13]); - mxf->op = OP1a; - } - - if (partition->kag_size <= 0 || partition->kag_size > (1 << 20)) { - av_log(mxf->fc, AV_LOG_WARNING, "invalid KAGSize %i - guessing ", partition->kag_size); - - if (mxf->op == OPSONYOpt) - partition->kag_size = 512; - else - partition->kag_size = 1; - - av_log(mxf->fc, AV_LOG_WARNING, "%i\n", partition->kag_size); - } - - return 0; -} - -static int mxf_add_metadata_set(MXFContext *mxf, void *metadata_set) -{ - MXFMetadataSet **tmp; - if (mxf->metadata_sets_count+1 >= UINT_MAX / sizeof(*mxf->metadata_sets)) - return AVERROR(ENOMEM); - tmp = av_realloc(mxf->metadata_sets, (mxf->metadata_sets_count + 1) * sizeof(*mxf->metadata_sets)); - if (!tmp) - return AVERROR(ENOMEM); - mxf->metadata_sets = tmp; - mxf->metadata_sets[mxf->metadata_sets_count] = metadata_set; - mxf->metadata_sets_count++; - return 0; -} - -static int mxf_read_cryptographic_context(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset) -{ - MXFCryptoContext *cryptocontext = arg; - if (size != 16) - return AVERROR_INVALIDDATA; - if (IS_KLV_KEY(uid, mxf_crypto_source_container_ul)) - avio_read(pb, cryptocontext->source_container_ul, 16); - return 0; -} - -static int mxf_read_content_storage(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset) -{ - MXFContext *mxf = arg; - switch (tag) { - case 0x1901: - mxf->packages_count = avio_rb32(pb); - mxf->packages_refs = av_calloc(mxf->packages_count, sizeof(UID)); - if (!mxf->packages_refs) - return AVERROR(ENOMEM); - avio_skip(pb, 4); /* useless size of objects, always 16 according to specs */ - avio_read(pb, (uint8_t *)mxf->packages_refs, mxf->packages_count * sizeof(UID)); - break; - } - return 0; -} - -static int mxf_read_source_clip(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset) -{ - MXFStructuralComponent *source_clip = arg; - switch(tag) { - case 0x0202: - source_clip->duration = avio_rb64(pb); - break; - case 0x1201: - source_clip->start_position = avio_rb64(pb); - break; - case 0x1101: - /* UMID, only get last 16 bytes */ - avio_skip(pb, 16); - avio_read(pb, source_clip->source_package_uid, 16); - break; - case 0x1102: - source_clip->source_track_id = avio_rb32(pb); - break; - } - return 0; -} - -static int mxf_read_material_package(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset) -{ - MXFPackage *package = arg; - switch(tag) { - case 0x4403: - package->tracks_count = avio_rb32(pb); - package->tracks_refs = av_calloc(package->tracks_count, sizeof(UID)); - if (!package->tracks_refs) - return AVERROR(ENOMEM); - avio_skip(pb, 4); /* useless size of objects, always 16 according to specs */ - avio_read(pb, (uint8_t *)package->tracks_refs, package->tracks_count * sizeof(UID)); - break; - } - return 0; -} - -static int mxf_read_timecode_component(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset) -{ - MXFTimecodeComponent *mxf_timecode = arg; - switch(tag) { - case 0x1501: - mxf_timecode->start_frame = avio_rb64(pb); - break; - case 0x1502: - mxf_timecode->rate = (AVRational){avio_rb16(pb), 1}; - break; - case 0x1503: - mxf_timecode->drop_frame = avio_r8(pb); - break; - } - return 0; -} - -static int mxf_read_track(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset) -{ - MXFTrack *track = arg; - switch(tag) { - case 0x4801: - track->track_id = avio_rb32(pb); - break; - case 0x4804: - avio_read(pb, track->track_number, 4); - break; - case 0x4B01: - track->edit_rate.num = avio_rb32(pb); - track->edit_rate.den = avio_rb32(pb); - break; - case 0x4803: - avio_read(pb, track->sequence_ref, 16); - break; - } - return 0; -} - -static int mxf_read_sequence(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset) -{ - MXFSequence *sequence = arg; - switch(tag) { - case 0x0202: - sequence->duration = avio_rb64(pb); - break; - case 0x0201: - avio_read(pb, sequence->data_definition_ul, 16); - break; - case 0x1001: - sequence->structural_components_count = avio_rb32(pb); - sequence->structural_components_refs = av_calloc(sequence->structural_components_count, sizeof(UID)); - if (!sequence->structural_components_refs) - return AVERROR(ENOMEM); - avio_skip(pb, 4); /* useless size of objects, always 16 according to specs */ - avio_read(pb, (uint8_t *)sequence->structural_components_refs, sequence->structural_components_count * sizeof(UID)); - break; - } - return 0; -} - -static int mxf_read_source_package(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset) -{ - MXFPackage *package = arg; - switch(tag) { - case 0x4403: - package->tracks_count = avio_rb32(pb); - package->tracks_refs = av_calloc(package->tracks_count, sizeof(UID)); - if (!package->tracks_refs) - return AVERROR(ENOMEM); - avio_skip(pb, 4); /* useless size of objects, always 16 according to specs */ - avio_read(pb, (uint8_t *)package->tracks_refs, package->tracks_count * sizeof(UID)); - break; - case 0x4401: - /* UMID, only get last 16 bytes */ - avio_skip(pb, 16); - avio_read(pb, package->package_uid, 16); - break; - case 0x4701: - avio_read(pb, package->descriptor_ref, 16); - break; - } - return 0; -} - -static int mxf_read_index_entry_array(AVIOContext *pb, MXFIndexTableSegment *segment) -{ - int i, length; - - segment->nb_index_entries = avio_rb32(pb); - - length = avio_rb32(pb); - - if (!(segment->temporal_offset_entries=av_calloc(segment->nb_index_entries, sizeof(*segment->temporal_offset_entries))) || - !(segment->flag_entries = av_calloc(segment->nb_index_entries, sizeof(*segment->flag_entries))) || - !(segment->stream_offset_entries = av_calloc(segment->nb_index_entries, sizeof(*segment->stream_offset_entries)))) - return AVERROR(ENOMEM); - - for (i = 0; i < segment->nb_index_entries; i++) { - segment->temporal_offset_entries[i] = avio_r8(pb); - avio_r8(pb); /* KeyFrameOffset */ - segment->flag_entries[i] = avio_r8(pb); - segment->stream_offset_entries[i] = avio_rb64(pb); - avio_skip(pb, length - 11); - } - return 0; -} - -static int mxf_read_index_table_segment(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset) -{ - MXFIndexTableSegment *segment = arg; - switch(tag) { - case 0x3F05: - segment->edit_unit_byte_count = avio_rb32(pb); - av_dlog(NULL, "EditUnitByteCount %d\n", segment->edit_unit_byte_count); - break; - case 0x3F06: - segment->index_sid = avio_rb32(pb); - av_dlog(NULL, "IndexSID %d\n", segment->index_sid); - break; - case 0x3F07: - segment->body_sid = avio_rb32(pb); - av_dlog(NULL, "BodySID %d\n", segment->body_sid); - break; - case 0x3F0A: - av_dlog(NULL, "IndexEntryArray found\n"); - return mxf_read_index_entry_array(pb, segment); - case 0x3F0B: - segment->index_edit_rate.num = avio_rb32(pb); - segment->index_edit_rate.den = avio_rb32(pb); - av_dlog(NULL, "IndexEditRate %d/%d\n", segment->index_edit_rate.num, - segment->index_edit_rate.den); - break; - case 0x3F0C: - segment->index_start_position = avio_rb64(pb); - av_dlog(NULL, "IndexStartPosition %"PRId64"\n", segment->index_start_position); - break; - case 0x3F0D: - segment->index_duration = avio_rb64(pb); - av_dlog(NULL, "IndexDuration %"PRId64"\n", segment->index_duration); - break; - } - return 0; -} - -static void mxf_read_pixel_layout(AVIOContext *pb, MXFDescriptor *descriptor) -{ - int code, value, ofs = 0; - char layout[16] = {0}; /* not for printing, may end up not terminated on purpose */ - - do { - code = avio_r8(pb); - value = avio_r8(pb); - av_dlog(NULL, "pixel layout: code %#x\n", code); - - if (ofs <= 14) { - layout[ofs++] = code; - layout[ofs++] = value; - } else - break; /* don't read byte by byte on sneaky files filled with lots of non-zeroes */ - } while (code != 0); /* SMPTE 377M E.2.46 */ - - ff_mxf_decode_pixel_layout(layout, &descriptor->pix_fmt); -} - -static int mxf_read_generic_descriptor(void *arg, AVIOContext *pb, int tag, int size, UID uid, int64_t klv_offset) -{ - MXFDescriptor *descriptor = arg; - descriptor->pix_fmt = AV_PIX_FMT_NONE; - switch(tag) { - case 0x3F01: - descriptor->sub_descriptors_count = avio_rb32(pb); - descriptor->sub_descriptors_refs = av_calloc(descriptor->sub_descriptors_count, sizeof(UID)); - if (!descriptor->sub_descriptors_refs) - return AVERROR(ENOMEM); - avio_skip(pb, 4); /* useless size of objects, always 16 according to specs */ - avio_read(pb, (uint8_t *)descriptor->sub_descriptors_refs, descriptor->sub_descriptors_count * sizeof(UID)); - break; - case 0x3004: - avio_read(pb, descriptor->essence_container_ul, 16); - break; - case 0x3006: - descriptor->linked_track_id = avio_rb32(pb); - break; - case 0x3201: /* PictureEssenceCoding */ - avio_read(pb, descriptor->essence_codec_ul, 16); - break; - case 0x3203: - descriptor->width = avio_rb32(pb); - break; - case 0x3202: - descriptor->height = avio_rb32(pb); - break; - case 0x320C: - descriptor->frame_layout = avio_r8(pb); - break; - case 0x320E: - descriptor->aspect_ratio.num = avio_rb32(pb); - descriptor->aspect_ratio.den = avio_rb32(pb); - break; - case 0x3212: - descriptor->field_dominance = avio_r8(pb); - break; - case 0x3301: - descriptor->component_depth = avio_rb32(pb); - break; - case 0x3302: - descriptor->horiz_subsampling = avio_rb32(pb); - break; - case 0x3308: - descriptor->vert_subsampling = avio_rb32(pb); - break; - case 0x3D03: - descriptor->sample_rate.num = avio_rb32(pb); - descriptor->sample_rate.den = avio_rb32(pb); - break; - case 0x3D06: /* SoundEssenceCompression */ - avio_read(pb, descriptor->essence_codec_ul, 16); - break; - case 0x3D07: - descriptor->channels = avio_rb32(pb); - break; - case 0x3D01: - descriptor->bits_per_sample = avio_rb32(pb); - break; - case 0x3401: - mxf_read_pixel_layout(pb, descriptor); - break; - default: - /* Private uid used by SONY C0023S01.mxf */ - if (IS_KLV_KEY(uid, mxf_sony_mpeg4_extradata)) { - if (descriptor->extradata) - av_log(NULL, AV_LOG_WARNING, "Duplicate sony_mpeg4_extradata\n"); - av_free(descriptor->extradata); - descriptor->extradata_size = 0; - descriptor->extradata = av_malloc(size); - if (!descriptor->extradata) - return AVERROR(ENOMEM); - descriptor->extradata_size = size; - avio_read(pb, descriptor->extradata, size); - } - break; - } - return 0; -} - -/* - * Match an uid independently of the version byte and up to len common bytes - * Returns: boolean - */ -static int mxf_match_uid(const UID key, const UID uid, int len) -{ - int i; - for (i = 0; i < len; i++) { - if (i != 7 && key[i] != uid[i]) - return 0; - } - return 1; -} - -static const MXFCodecUL *mxf_get_codec_ul(const MXFCodecUL *uls, UID *uid) -{ - while (uls->uid[0]) { - if(mxf_match_uid(uls->uid, *uid, uls->matching_len)) - break; - uls++; - } - return uls; -} - -static void *mxf_resolve_strong_ref(MXFContext *mxf, UID *strong_ref, enum MXFMetadataSetType type) -{ - int i; - - if (!strong_ref) - return NULL; - for (i = 0; i < mxf->metadata_sets_count; i++) { - if (!memcmp(*strong_ref, mxf->metadata_sets[i]->uid, 16) && - (type == AnyType || mxf->metadata_sets[i]->type == type)) { - return mxf->metadata_sets[i]; - } - } - return NULL; -} - -static const MXFCodecUL mxf_picture_essence_container_uls[] = { - // video essence container uls - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x02,0x0D,0x01,0x03,0x01,0x02,0x04,0x60,0x01 }, 14, AV_CODEC_ID_MPEG2VIDEO }, /* MPEG-ES Frame wrapped */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x41,0x01 }, 14, AV_CODEC_ID_DVVIDEO }, /* DV 625 25mbps */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x05,0x00,0x00 }, 14, AV_CODEC_ID_RAWVIDEO }, /* Uncompressed Picture */ - { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, AV_CODEC_ID_NONE }, -}; - -/* EC ULs for intra-only formats */ -static const MXFCodecUL mxf_intra_only_essence_container_uls[] = { - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x00,0x00 }, 14, AV_CODEC_ID_MPEG2VIDEO }, /* MXF-GC SMPTE D-10 Mappings */ - { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, AV_CODEC_ID_NONE }, -}; - -/* intra-only PictureEssenceCoding ULs, where no corresponding EC UL exists */ -static const MXFCodecUL mxf_intra_only_picture_essence_coding_uls[] = { - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x01,0x32,0x00,0x00 }, 14, AV_CODEC_ID_H264 }, /* H.264/MPEG-4 AVC Intra Profiles */ - { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, AV_CODEC_ID_NONE }, -}; - -static const MXFCodecUL mxf_sound_essence_container_uls[] = { - // sound essence container uls - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x06,0x01,0x00 }, 14, AV_CODEC_ID_PCM_S16LE }, /* BWF Frame wrapped */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x02,0x0D,0x01,0x03,0x01,0x02,0x04,0x40,0x01 }, 14, AV_CODEC_ID_MP2 }, /* MPEG-ES Frame wrapped, 0x40 ??? stream id */ - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x01,0x01 }, 14, AV_CODEC_ID_PCM_S16LE }, /* D-10 Mapping 50Mbps PAL Extended Template */ - { { 0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0xFF,0x4B,0x46,0x41,0x41,0x00,0x0D,0x4D,0x4F }, 14, AV_CODEC_ID_PCM_S16LE }, /* 0001GL00.MXF.A1.mxf_opatom.mxf */ - { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, 0, AV_CODEC_ID_NONE }, -}; - -static int mxf_get_sorted_table_segments(MXFContext *mxf, int *nb_sorted_segments, MXFIndexTableSegment ***sorted_segments) -{ - int i, j, nb_segments = 0; - MXFIndexTableSegment **unsorted_segments; - int last_body_sid = -1, last_index_sid = -1, last_index_start = -1; - - /* count number of segments, allocate arrays and copy unsorted segments */ - for (i = 0; i < mxf->metadata_sets_count; i++) - if (mxf->metadata_sets[i]->type == IndexTableSegment) - nb_segments++; - - if (!nb_segments) - return AVERROR_INVALIDDATA; - - if (!(unsorted_segments = av_calloc(nb_segments, sizeof(*unsorted_segments))) || - !(*sorted_segments = av_calloc(nb_segments, sizeof(**sorted_segments)))) { - av_freep(sorted_segments); - av_free(unsorted_segments); - return AVERROR(ENOMEM); - } - - for (i = j = 0; i < mxf->metadata_sets_count; i++) - if (mxf->metadata_sets[i]->type == IndexTableSegment) - unsorted_segments[j++] = (MXFIndexTableSegment*)mxf->metadata_sets[i]; - - *nb_sorted_segments = 0; - - /* sort segments by {BodySID, IndexSID, IndexStartPosition}, remove duplicates while we're at it */ - for (i = 0; i < nb_segments; i++) { - int best = -1, best_body_sid = -1, best_index_sid = -1, best_index_start = -1; - uint64_t best_index_duration = 0; - - for (j = 0; j < nb_segments; j++) { - MXFIndexTableSegment *s = unsorted_segments[j]; - - /* Require larger BosySID, IndexSID or IndexStartPosition then the previous entry. This removes duplicates. - * We want the smallest values for the keys than what we currently have, unless this is the first such entry this time around. - * If we come across an entry with the same IndexStartPosition but larger IndexDuration, then we'll prefer it over the one we currently have. - */ - if ((i == 0 || s->body_sid > last_body_sid || s->index_sid > last_index_sid || s->index_start_position > last_index_start) && - (best == -1 || s->body_sid < best_body_sid || s->index_sid < best_index_sid || s->index_start_position < best_index_start || - (s->index_start_position == best_index_start && s->index_duration > best_index_duration))) { - best = j; - best_body_sid = s->body_sid; - best_index_sid = s->index_sid; - best_index_start = s->index_start_position; - best_index_duration = s->index_duration; - } - } - - /* no suitable entry found -> we're done */ - if (best == -1) - break; - - (*sorted_segments)[(*nb_sorted_segments)++] = unsorted_segments[best]; - last_body_sid = best_body_sid; - last_index_sid = best_index_sid; - last_index_start = best_index_start; - } - - av_free(unsorted_segments); - - return 0; -} - -/** - * Computes the absolute file offset of the given essence container offset - */ -static int mxf_absolute_bodysid_offset(MXFContext *mxf, int body_sid, int64_t offset, int64_t *offset_out) -{ - int x; - int64_t offset_in = offset; /* for logging */ - - for (x = 0; x < mxf->partitions_count; x++) { - MXFPartition *p = &mxf->partitions[x]; - - if (p->body_sid != body_sid) - continue; - - if (offset < p->essence_length || !p->essence_length) { - *offset_out = p->essence_offset + offset; - return 0; - } - - offset -= p->essence_length; - } - - av_log(mxf->fc, AV_LOG_ERROR, - "failed to find absolute offset of %"PRIX64" in BodySID %i - partial file?\n", - offset_in, body_sid); - - return AVERROR_INVALIDDATA; -} - -/** - * Returns the end position of the essence container with given BodySID, or zero if unknown - */ -static int64_t mxf_essence_container_end(MXFContext *mxf, int body_sid) -{ - int x; - int64_t ret = 0; - - for (x = 0; x < mxf->partitions_count; x++) { - MXFPartition *p = &mxf->partitions[x]; - - if (p->body_sid != body_sid) - continue; - - if (!p->essence_length) - return 0; - - ret = p->essence_offset + p->essence_length; - } - - return ret; -} - -/* EditUnit -> absolute offset */ -static int mxf_edit_unit_absolute_offset(MXFContext *mxf, MXFIndexTable *index_table, int64_t edit_unit, int64_t *edit_unit_out, int64_t *offset_out, int nag) -{ - int i; - int64_t offset_temp = 0; - - for (i = 0; i < index_table->nb_segments; i++) { - MXFIndexTableSegment *s = index_table->segments[i]; - - edit_unit = FFMAX(edit_unit, s->index_start_position); /* clamp if trying to seek before start */ - - if (edit_unit < s->index_start_position + s->index_duration) { - int64_t index = edit_unit - s->index_start_position; - - if (s->edit_unit_byte_count) - offset_temp += s->edit_unit_byte_count * index; - else if (s->nb_index_entries) { - if (s->nb_index_entries == 2 * s->index_duration + 1) - index *= 2; /* Avid index */ - - if (index < 0 || index >= s->nb_index_entries) { - av_log(mxf->fc, AV_LOG_ERROR, "IndexSID %i segment at %"PRId64" IndexEntryArray too small\n", - index_table->index_sid, s->index_start_position); - return AVERROR_INVALIDDATA; - } - - offset_temp = s->stream_offset_entries[index]; - } else { - av_log(mxf->fc, AV_LOG_ERROR, "IndexSID %i segment at %"PRId64" missing EditUnitByteCount and IndexEntryArray\n", - index_table->index_sid, s->index_start_position); - return AVERROR_INVALIDDATA; - } - - if (edit_unit_out) - *edit_unit_out = edit_unit; - - return mxf_absolute_bodysid_offset(mxf, index_table->body_sid, offset_temp, offset_out); - } else { - /* EditUnitByteCount == 0 for VBR indexes, which is fine since they use explicit StreamOffsets */ - offset_temp += s->edit_unit_byte_count * s->index_duration; - } - } - - if (nag) - av_log(mxf->fc, AV_LOG_ERROR, "failed to map EditUnit %"PRId64" in IndexSID %i to an offset\n", edit_unit, index_table->index_sid); - - return AVERROR_INVALIDDATA; -} - -static int mxf_compute_ptses_fake_index(MXFContext *mxf, MXFIndexTable *index_table) -{ - int i, j, x; - int8_t max_temporal_offset = -128; - - /* first compute how many entries we have */ - for (i = 0; i < index_table->nb_segments; i++) { - MXFIndexTableSegment *s = index_table->segments[i]; - - if (!s->nb_index_entries) { - index_table->nb_ptses = 0; - return 0; /* no TemporalOffsets */ - } - - index_table->nb_ptses += s->index_duration; - } - - /* paranoid check */ - if (index_table->nb_ptses <= 0) - return 0; - - if (!(index_table->ptses = av_calloc(index_table->nb_ptses, sizeof(int64_t))) || - !(index_table->fake_index = av_calloc(index_table->nb_ptses, sizeof(AVIndexEntry)))) { - av_freep(&index_table->ptses); - return AVERROR(ENOMEM); - } - - /* we may have a few bad TemporalOffsets - * make sure the corresponding PTSes don't have the bogus value 0 */ - for (x = 0; x < index_table->nb_ptses; x++) - index_table->ptses[x] = AV_NOPTS_VALUE; - - /** - * We have this: - * - * x TemporalOffset - * 0: 0 - * 1: 1 - * 2: 1 - * 3: -2 - * 4: 1 - * 5: 1 - * 6: -2 - * - * We want to transform it into this: - * - * x DTS PTS - * 0: -1 0 - * 1: 0 3 - * 2: 1 1 - * 3: 2 2 - * 4: 3 6 - * 5: 4 4 - * 6: 5 5 - * - * We do this by bucket sorting x by x+TemporalOffset[x] into mxf->ptses, - * then settings mxf->first_dts = -max(TemporalOffset[x]). - * The latter makes DTS <= PTS. - */ - for (i = x = 0; i < index_table->nb_segments; i++) { - MXFIndexTableSegment *s = index_table->segments[i]; - int index_delta = 1; - int n = s->nb_index_entries; - - if (s->nb_index_entries == 2 * s->index_duration + 1) { - index_delta = 2; /* Avid index */ - /* ignore the last entry - it's the size of the essence container */ - n--; - } - - for (j = 0; j < n; j += index_delta, x++) { - int offset = s->temporal_offset_entries[j] / index_delta; - int index = x + offset; - - if (x >= index_table->nb_ptses) { - av_log(mxf->fc, AV_LOG_ERROR, - "x >= nb_ptses - IndexEntryCount %i < IndexDuration %"PRId64"?\n", - s->nb_index_entries, s->index_duration); - break; - } - - index_table->fake_index[x].timestamp = x; - index_table->fake_index[x].flags = !(s->flag_entries[j] & 0x30) ? AVINDEX_KEYFRAME : 0; - - if (index < 0 || index >= index_table->nb_ptses) { - av_log(mxf->fc, AV_LOG_ERROR, - "index entry %i + TemporalOffset %i = %i, which is out of bounds\n", - x, offset, index); - continue; - } - - index_table->ptses[index] = x; - max_temporal_offset = FFMAX(max_temporal_offset, offset); - } - } - - index_table->first_dts = -max_temporal_offset; - - return 0; -} - -/** - * Sorts and collects index table segments into index tables. - * Also computes PTSes if possible. - */ -static int mxf_compute_index_tables(MXFContext *mxf) -{ - int i, j, k, ret, nb_sorted_segments; - MXFIndexTableSegment **sorted_segments = NULL; - - if ((ret = mxf_get_sorted_table_segments(mxf, &nb_sorted_segments, &sorted_segments)) || - nb_sorted_segments <= 0) { - av_log(mxf->fc, AV_LOG_WARNING, "broken or empty index\n"); - return 0; - } - - /* sanity check and count unique BodySIDs/IndexSIDs */ - for (i = 0; i < nb_sorted_segments; i++) { - if (i == 0 || sorted_segments[i-1]->index_sid != sorted_segments[i]->index_sid) - mxf->nb_index_tables++; - else if (sorted_segments[i-1]->body_sid != sorted_segments[i]->body_sid) { - av_log(mxf->fc, AV_LOG_ERROR, "found inconsistent BodySID\n"); - ret = AVERROR_INVALIDDATA; - goto finish_decoding_index; - } - } - - if (!(mxf->index_tables = av_calloc(mxf->nb_index_tables, sizeof(MXFIndexTable)))) { - av_log(mxf->fc, AV_LOG_ERROR, "failed to allocate index tables\n"); - ret = AVERROR(ENOMEM); - goto finish_decoding_index; - } - - /* distribute sorted segments to index tables */ - for (i = j = 0; i < nb_sorted_segments; i++) { - if (i != 0 && sorted_segments[i-1]->index_sid != sorted_segments[i]->index_sid) { - /* next IndexSID */ - j++; - } - - mxf->index_tables[j].nb_segments++; - } - - for (i = j = 0; j < mxf->nb_index_tables; i += mxf->index_tables[j++].nb_segments) { - MXFIndexTable *t = &mxf->index_tables[j]; - - if (!(t->segments = av_calloc(t->nb_segments, sizeof(MXFIndexTableSegment*)))) { - av_log(mxf->fc, AV_LOG_ERROR, "failed to allocate IndexTableSegment pointer array\n"); - ret = AVERROR(ENOMEM); - goto finish_decoding_index; - } - - if (sorted_segments[i]->index_start_position) - av_log(mxf->fc, AV_LOG_WARNING, "IndexSID %i starts at EditUnit %"PRId64" - seeking may not work as expected\n", - sorted_segments[i]->index_sid, sorted_segments[i]->index_start_position); - - memcpy(t->segments, &sorted_segments[i], t->nb_segments * sizeof(MXFIndexTableSegment*)); - t->index_sid = sorted_segments[i]->index_sid; - t->body_sid = sorted_segments[i]->body_sid; - - if ((ret = mxf_compute_ptses_fake_index(mxf, t)) < 0) - goto finish_decoding_index; - - /* fix zero IndexDurations */ - for (k = 0; k < t->nb_segments; k++) { - if (t->segments[k]->index_duration) - continue; - - if (t->nb_segments > 1) - av_log(mxf->fc, AV_LOG_WARNING, "IndexSID %i segment %i has zero IndexDuration and there's more than one segment\n", - t->index_sid, k); - - if (mxf->fc->nb_streams <= 0) { - av_log(mxf->fc, AV_LOG_WARNING, "no streams?\n"); - break; - } - - /* assume the first stream's duration is reasonable - * leave index_duration = 0 on further segments in case we have any (unlikely) - */ - t->segments[k]->index_duration = mxf->fc->streams[0]->duration; - break; - } - } - - ret = 0; -finish_decoding_index: - av_free(sorted_segments); - return ret; -} - -static int mxf_is_intra_only(MXFDescriptor *descriptor) -{ - return mxf_get_codec_ul(mxf_intra_only_essence_container_uls, - &descriptor->essence_container_ul)->id != AV_CODEC_ID_NONE || - mxf_get_codec_ul(mxf_intra_only_picture_essence_coding_uls, - &descriptor->essence_codec_ul)->id != AV_CODEC_ID_NONE; -} - -static int mxf_add_timecode_metadata(AVDictionary **pm, const char *key, AVTimecode *tc) -{ - char buf[AV_TIMECODE_STR_SIZE]; - av_dict_set(pm, key, av_timecode_make_string(tc, buf, 0), 0); - - return 0; -} - -static int mxf_parse_structural_metadata(MXFContext *mxf) -{ - MXFPackage *material_package = NULL; - MXFPackage *temp_package = NULL; - int i, j, k, ret; - - av_dlog(mxf->fc, "metadata sets count %d\n", mxf->metadata_sets_count); - /* TODO: handle multiple material packages (OP3x) */ - for (i = 0; i < mxf->packages_count; i++) { - material_package = mxf_resolve_strong_ref(mxf, &mxf->packages_refs[i], MaterialPackage); - if (material_package) break; - } - if (!material_package) { - av_log(mxf->fc, AV_LOG_ERROR, "no material package found\n"); - return AVERROR_INVALIDDATA; - } - - for (i = 0; i < material_package->tracks_count; i++) { - MXFPackage *source_package = NULL; - MXFTrack *material_track = NULL; - MXFTrack *source_track = NULL; - MXFTrack *temp_track = NULL; - MXFDescriptor *descriptor = NULL; - MXFStructuralComponent *component = NULL; - MXFTimecodeComponent *mxf_tc = NULL; - UID *essence_container_ul = NULL; - const MXFCodecUL *codec_ul = NULL; - const MXFCodecUL *container_ul = NULL; - const MXFCodecUL *pix_fmt_ul = NULL; - AVStream *st; - AVTimecode tc; - int flags; - - if (!(material_track = mxf_resolve_strong_ref(mxf, &material_package->tracks_refs[i], Track))) { - av_log(mxf->fc, AV_LOG_ERROR, "could not resolve material track strong ref\n"); - continue; - } - - if ((component = mxf_resolve_strong_ref(mxf, &material_track->sequence_ref, TimecodeComponent))) { - mxf_tc = (MXFTimecodeComponent*)component; - flags = mxf_tc->drop_frame == 1 ? AV_TIMECODE_FLAG_DROPFRAME : 0; - if (av_timecode_init(&tc, mxf_tc->rate, flags, mxf_tc->start_frame, mxf->fc) == 0) { - mxf_add_timecode_metadata(&mxf->fc->metadata, "timecode", &tc); - } - } - - if (!(material_track->sequence = mxf_resolve_strong_ref(mxf, &material_track->sequence_ref, Sequence))) { - av_log(mxf->fc, AV_LOG_ERROR, "could not resolve material track sequence strong ref\n"); - continue; - } - - for (j = 0; j < material_track->sequence->structural_components_count; j++) { - component = mxf_resolve_strong_ref(mxf, &material_track->sequence->structural_components_refs[j], TimecodeComponent); - if (!component) - continue; - - mxf_tc = (MXFTimecodeComponent*)component; - flags = mxf_tc->drop_frame == 1 ? AV_TIMECODE_FLAG_DROPFRAME : 0; - if (av_timecode_init(&tc, mxf_tc->rate, flags, mxf_tc->start_frame, mxf->fc) == 0) { - mxf_add_timecode_metadata(&mxf->fc->metadata, "timecode", &tc); - break; - } - } - - /* TODO: handle multiple source clips */ - for (j = 0; j < material_track->sequence->structural_components_count; j++) { - component = mxf_resolve_strong_ref(mxf, &material_track->sequence->structural_components_refs[j], SourceClip); - if (!component) - continue; - - for (k = 0; k < mxf->packages_count; k++) { - temp_package = mxf_resolve_strong_ref(mxf, &mxf->packages_refs[k], SourcePackage); - if (!temp_package) - continue; - if (!memcmp(temp_package->package_uid, component->source_package_uid, 16)) { - source_package = temp_package; - break; - } - } - if (!source_package) { - av_dlog(mxf->fc, "material track %d: no corresponding source package found\n", material_track->track_id); - break; - } - for (k = 0; k < source_package->tracks_count; k++) { - if (!(temp_track = mxf_resolve_strong_ref(mxf, &source_package->tracks_refs[k], Track))) { - av_log(mxf->fc, AV_LOG_ERROR, "could not resolve source track strong ref\n"); - ret = AVERROR_INVALIDDATA; - goto fail_and_free; - } - if (temp_track->track_id == component->source_track_id) { - source_track = temp_track; - break; - } - } - if (!source_track) { - av_log(mxf->fc, AV_LOG_ERROR, "material track %d: no corresponding source track found\n", material_track->track_id); - break; - } - } - if (!source_track || !component) - continue; - - if (!(source_track->sequence = mxf_resolve_strong_ref(mxf, &source_track->sequence_ref, Sequence))) { - av_log(mxf->fc, AV_LOG_ERROR, "could not resolve source track sequence strong ref\n"); - ret = AVERROR_INVALIDDATA; - goto fail_and_free; - } - - /* 0001GL00.MXF.A1.mxf_opatom.mxf has the same SourcePackageID as 0001GL.MXF.V1.mxf_opatom.mxf - * This would result in both files appearing to have two streams. Work around this by sanity checking DataDefinition */ - if (memcmp(material_track->sequence->data_definition_ul, source_track->sequence->data_definition_ul, 16)) { - av_log(mxf->fc, AV_LOG_ERROR, "material track %d: DataDefinition mismatch\n", material_track->track_id); - continue; - } - - st = avformat_new_stream(mxf->fc, NULL); - if (!st) { - av_log(mxf->fc, AV_LOG_ERROR, "could not allocate stream\n"); - ret = AVERROR(ENOMEM); - goto fail_and_free; - } - st->id = source_track->track_id; - st->priv_data = source_track; - source_track->original_duration = st->duration = component->duration; - if (st->duration == -1) - st->duration = AV_NOPTS_VALUE; - st->start_time = component->start_position; - if (material_track->edit_rate.num <= 0 || material_track->edit_rate.den <= 0) { - av_log(mxf->fc, AV_LOG_WARNING, - "invalid edit rate (%d/%d) found on stream #%d, defaulting to 25/1\n", - material_track->edit_rate.num, material_track->edit_rate.den, st->index); - material_track->edit_rate = (AVRational){25, 1}; - } - avpriv_set_pts_info(st, 64, material_track->edit_rate.den, material_track->edit_rate.num); - - /* ensure SourceTrack EditRate == MaterialTrack EditRate since only the former is accessible via st->priv_data */ - source_track->edit_rate = material_track->edit_rate; - - PRINT_KEY(mxf->fc, "data definition ul", source_track->sequence->data_definition_ul); - codec_ul = mxf_get_codec_ul(ff_mxf_data_definition_uls, &source_track->sequence->data_definition_ul); - st->codec->codec_type = codec_ul->id; - - source_package->descriptor = mxf_resolve_strong_ref(mxf, &source_package->descriptor_ref, AnyType); - if (source_package->descriptor) { - if (source_package->descriptor->type == MultipleDescriptor) { - for (j = 0; j < source_package->descriptor->sub_descriptors_count; j++) { - MXFDescriptor *sub_descriptor = mxf_resolve_strong_ref(mxf, &source_package->descriptor->sub_descriptors_refs[j], Descriptor); - - if (!sub_descriptor) { - av_log(mxf->fc, AV_LOG_ERROR, "could not resolve sub descriptor strong ref\n"); - continue; - } - if (sub_descriptor->linked_track_id == source_track->track_id) { - descriptor = sub_descriptor; - break; - } - } - } else if (source_package->descriptor->type == Descriptor) - descriptor = source_package->descriptor; - } - if (!descriptor) { - av_log(mxf->fc, AV_LOG_INFO, "source track %d: stream %d, no descriptor found\n", source_track->track_id, st->index); - continue; - } - PRINT_KEY(mxf->fc, "essence codec ul", descriptor->essence_codec_ul); - PRINT_KEY(mxf->fc, "essence container ul", descriptor->essence_container_ul); - essence_container_ul = &descriptor->essence_container_ul; - /* HACK: replacing the original key with mxf_encrypted_essence_container - * is not allowed according to s429-6, try to find correct information anyway */ - if (IS_KLV_KEY(essence_container_ul, mxf_encrypted_essence_container)) { - av_log(mxf->fc, AV_LOG_INFO, "broken encrypted mxf file\n"); - for (k = 0; k < mxf->metadata_sets_count; k++) { - MXFMetadataSet *metadata = mxf->metadata_sets[k]; - if (metadata->type == CryptoContext) { - essence_container_ul = &((MXFCryptoContext *)metadata)->source_container_ul; - break; - } - } - } - - /* TODO: drop PictureEssenceCoding and SoundEssenceCompression, only check EssenceContainer */ - codec_ul = mxf_get_codec_ul(ff_mxf_codec_uls, &descriptor->essence_codec_ul); - st->codec->codec_id = (enum AVCodecID)codec_ul->id; - av_log(mxf->fc, AV_LOG_VERBOSE, "%s: Universal Label: ", - avcodec_get_name(st->codec->codec_id)); - for (k = 0; k < 16; k++) { - av_log(mxf->fc, AV_LOG_VERBOSE, "%.2x", - descriptor->essence_codec_ul[k]); - if (!(k+1 & 19) || k == 5) - av_log(mxf->fc, AV_LOG_VERBOSE, "."); - } - av_log(mxf->fc, AV_LOG_VERBOSE, "\n"); - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { - source_track->intra_only = mxf_is_intra_only(descriptor); - container_ul = mxf_get_codec_ul(mxf_picture_essence_container_uls, essence_container_ul); - if (st->codec->codec_id == AV_CODEC_ID_NONE) - st->codec->codec_id = container_ul->id; - st->codec->width = descriptor->width; - st->codec->height = descriptor->height; /* Field height, not frame height */ - switch (descriptor->frame_layout) { - case SegmentedFrame: - /* This one is a weird layout I don't fully understand. */ - av_log(mxf->fc, AV_LOG_INFO, "SegmentedFrame layout isn't currently supported\n"); - break; - case FullFrame: - st->codec->field_order = AV_FIELD_PROGRESSIVE; - break; - case OneField: - /* Every other line is stored and needs to be duplicated. */ - av_log(mxf->fc, AV_LOG_INFO, "OneField frame layout isn't currently supported\n"); - break; /* The correct thing to do here is fall through, but by breaking we might be - able to decode some streams at half the vertical resolution, rather than not al all. - It's also for compatibility with the old behavior. */ - case MixedFields: - break; - case SeparateFields: - st->codec->height *= 2; /* Turn field height into frame height. */ - break; - default: - av_log(mxf->fc, AV_LOG_INFO, "Unknown frame layout type: %d\n", descriptor->frame_layout); - } - if (st->codec->codec_id == AV_CODEC_ID_RAWVIDEO) { - st->codec->pix_fmt = descriptor->pix_fmt; - if (st->codec->pix_fmt == AV_PIX_FMT_NONE) { - pix_fmt_ul = mxf_get_codec_ul(ff_mxf_pixel_format_uls, - &descriptor->essence_codec_ul); - st->codec->pix_fmt = (enum AVPixelFormat)pix_fmt_ul->id; - if (st->codec->pix_fmt == AV_PIX_FMT_NONE) { - /* support files created before RP224v10 by defaulting to UYVY422 - if subsampling is 4:2:2 and component depth is 8-bit */ - if (descriptor->horiz_subsampling == 2 && - descriptor->vert_subsampling == 1 && - descriptor->component_depth == 8) { - st->codec->pix_fmt = AV_PIX_FMT_UYVY422; - } - } - } - } - st->need_parsing = AVSTREAM_PARSE_HEADERS; - } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - container_ul = mxf_get_codec_ul(mxf_sound_essence_container_uls, essence_container_ul); - /* Only overwrite existing codec ID if it is unset or A-law, which is the default according to SMPTE RP 224. */ - if (st->codec->codec_id == AV_CODEC_ID_NONE || (st->codec->codec_id == AV_CODEC_ID_PCM_ALAW && (enum AVCodecID)container_ul->id != AV_CODEC_ID_NONE)) - st->codec->codec_id = (enum AVCodecID)container_ul->id; - st->codec->channels = descriptor->channels; - st->codec->bits_per_coded_sample = descriptor->bits_per_sample; - - if (descriptor->sample_rate.den > 0) { - avpriv_set_pts_info(st, 64, descriptor->sample_rate.den, descriptor->sample_rate.num); - st->codec->sample_rate = descriptor->sample_rate.num / descriptor->sample_rate.den; - } else { - av_log(mxf->fc, AV_LOG_WARNING, "invalid sample rate (%d/%d) found for stream #%d, time base forced to 1/48000\n", - descriptor->sample_rate.num, descriptor->sample_rate.den, st->index); - avpriv_set_pts_info(st, 64, 1, 48000); - } - - /* if duration is set, rescale it from EditRate to SampleRate */ - if (st->duration != AV_NOPTS_VALUE) - st->duration = av_rescale_q(st->duration, av_inv_q(material_track->edit_rate), st->time_base); - - /* TODO: implement AV_CODEC_ID_RAWAUDIO */ - if (st->codec->codec_id == AV_CODEC_ID_PCM_S16LE) { - if (descriptor->bits_per_sample > 16 && descriptor->bits_per_sample <= 24) - st->codec->codec_id = AV_CODEC_ID_PCM_S24LE; - else if (descriptor->bits_per_sample == 32) - st->codec->codec_id = AV_CODEC_ID_PCM_S32LE; - } else if (st->codec->codec_id == AV_CODEC_ID_PCM_S16BE) { - if (descriptor->bits_per_sample > 16 && descriptor->bits_per_sample <= 24) - st->codec->codec_id = AV_CODEC_ID_PCM_S24BE; - else if (descriptor->bits_per_sample == 32) - st->codec->codec_id = AV_CODEC_ID_PCM_S32BE; - } else if (st->codec->codec_id == AV_CODEC_ID_MP2) { - st->need_parsing = AVSTREAM_PARSE_FULL; - } - } - if (descriptor->extradata) { - st->codec->extradata = av_mallocz(descriptor->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); - if (st->codec->extradata) - memcpy(st->codec->extradata, descriptor->extradata, descriptor->extradata_size); - } else if(st->codec->codec_id == AV_CODEC_ID_H264) { - ff_generate_avci_extradata(st); - } - if (st->codec->codec_type != AVMEDIA_TYPE_DATA && (*essence_container_ul)[15] > 0x01) { - /* TODO: decode timestamps */ - st->need_parsing = AVSTREAM_PARSE_TIMESTAMPS; - } - } - - ret = 0; -fail_and_free: - return ret; -} - -static const MXFMetadataReadTableEntry mxf_metadata_read_table[] = { - { { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x05,0x01,0x00 }, mxf_read_primer_pack }, - { { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02,0x01,0x00 }, mxf_read_partition_pack }, - { { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02,0x02,0x00 }, mxf_read_partition_pack }, - { { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02,0x03,0x00 }, mxf_read_partition_pack }, - { { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x02,0x04,0x00 }, mxf_read_partition_pack }, - { { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x03,0x01,0x00 }, mxf_read_partition_pack }, - { { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x03,0x02,0x00 }, mxf_read_partition_pack }, - { { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x03,0x03,0x00 }, mxf_read_partition_pack }, - { { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x03,0x04,0x00 }, mxf_read_partition_pack }, - { { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x04,0x02,0x00 }, mxf_read_partition_pack }, - { { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x04,0x04,0x00 }, mxf_read_partition_pack }, - { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x18,0x00 }, mxf_read_content_storage, 0, AnyType }, - { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x37,0x00 }, mxf_read_source_package, sizeof(MXFPackage), SourcePackage }, - { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x36,0x00 }, mxf_read_material_package, sizeof(MXFPackage), MaterialPackage }, - { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x0F,0x00 }, mxf_read_sequence, sizeof(MXFSequence), Sequence }, - { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x11,0x00 }, mxf_read_source_clip, sizeof(MXFStructuralComponent), SourceClip }, - { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x44,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), MultipleDescriptor }, - { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x42,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* Generic Sound */ - { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x28,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* CDCI */ - { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x29,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* RGBA */ - { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x51,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* MPEG 2 Video */ - { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x48,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* Wave */ - { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x47,0x00 }, mxf_read_generic_descriptor, sizeof(MXFDescriptor), Descriptor }, /* AES3 */ - { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x3A,0x00 }, mxf_read_track, sizeof(MXFTrack), Track }, /* Static Track */ - { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x3B,0x00 }, mxf_read_track, sizeof(MXFTrack), Track }, /* Generic Track */ - { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x14,0x00 }, mxf_read_timecode_component, sizeof(MXFTimecodeComponent), TimecodeComponent }, - { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x04,0x01,0x02,0x02,0x00,0x00 }, mxf_read_cryptographic_context, sizeof(MXFCryptoContext), CryptoContext }, - { { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x10,0x01,0x00 }, mxf_read_index_table_segment, sizeof(MXFIndexTableSegment), IndexTableSegment }, - { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, NULL, 0, AnyType }, -}; - -static int mxf_read_local_tags(MXFContext *mxf, KLVPacket *klv, MXFMetadataReadFunc *read_child, int ctx_size, enum MXFMetadataSetType type) -{ - AVIOContext *pb = mxf->fc->pb; - MXFMetadataSet *ctx = ctx_size ? av_mallocz(ctx_size) : mxf; - uint64_t klv_end = avio_tell(pb) + klv->length; - - if (!ctx) - return AVERROR(ENOMEM); - while (avio_tell(pb) + 4 < klv_end && !url_feof(pb)) { - int ret; - int tag = avio_rb16(pb); - int size = avio_rb16(pb); /* KLV specified by 0x53 */ - uint64_t next = avio_tell(pb) + size; - UID uid = {0}; - - av_dlog(mxf->fc, "local tag %#04x size %d\n", tag, size); - if (!size) { /* ignore empty tag, needed for some files with empty UMID tag */ - av_log(mxf->fc, AV_LOG_ERROR, "local tag %#04x with 0 size\n", tag); - continue; - } - if (tag > 0x7FFF) { /* dynamic tag */ - int i; - for (i = 0; i < mxf->local_tags_count; i++) { - int local_tag = AV_RB16(mxf->local_tags+i*18); - if (local_tag == tag) { - memcpy(uid, mxf->local_tags+i*18+2, 16); - av_dlog(mxf->fc, "local tag %#04x\n", local_tag); - PRINT_KEY(mxf->fc, "uid", uid); - } - } - } - if (ctx_size && tag == 0x3C0A) - avio_read(pb, ctx->uid, 16); - else if ((ret = read_child(ctx, pb, tag, size, uid, -1)) < 0) - return ret; - - /* Accept the 64k local set limit being exceeded (Avid). Don't accept - * it extending past the end of the KLV though (zzuf5.mxf). */ - if (avio_tell(pb) > klv_end) { - if (ctx_size) - av_free(ctx); - - av_log(mxf->fc, AV_LOG_ERROR, - "local tag %#04x extends past end of local set @ %#"PRIx64"\n", - tag, klv->offset); - return AVERROR_INVALIDDATA; - } else if (avio_tell(pb) <= next) /* only seek forward, else this can loop for a long time */ - avio_seek(pb, next, SEEK_SET); - } - if (ctx_size) ctx->type = type; - return ctx_size ? mxf_add_metadata_set(mxf, ctx) : 0; -} - -/** - * Seeks to the previous partition, if possible - * @return <= 0 if we should stop parsing, > 0 if we should keep going - */ -static int mxf_seek_to_previous_partition(MXFContext *mxf) -{ - AVIOContext *pb = mxf->fc->pb; - - if (!mxf->current_partition || - mxf->run_in + mxf->current_partition->previous_partition <= mxf->last_forward_tell) - return 0; /* we've parsed all partitions */ - - /* seek to previous partition */ - avio_seek(pb, mxf->run_in + mxf->current_partition->previous_partition, SEEK_SET); - mxf->current_partition = NULL; - - av_dlog(mxf->fc, "seeking to previous partition\n"); - - return 1; -} - -/** - * Called when essence is encountered - * @return <= 0 if we should stop parsing, > 0 if we should keep going - */ -static int mxf_parse_handle_essence(MXFContext *mxf) -{ - AVIOContext *pb = mxf->fc->pb; - int64_t ret; - - if (mxf->parsing_backward) { - return mxf_seek_to_previous_partition(mxf); - } else { - if (!mxf->footer_partition) { - av_dlog(mxf->fc, "no footer\n"); - return 0; - } - - av_dlog(mxf->fc, "seeking to footer\n"); - - /* remember where we were so we don't end up seeking further back than this */ - mxf->last_forward_tell = avio_tell(pb); - - if (!pb->seekable) { - av_log(mxf->fc, AV_LOG_INFO, "file is not seekable - not parsing footer\n"); - return -1; - } - - /* seek to footer partition and parse backward */ - if ((ret = avio_seek(pb, mxf->run_in + mxf->footer_partition, SEEK_SET)) < 0) { - av_log(mxf->fc, AV_LOG_ERROR, "failed to seek to footer @ 0x%"PRIx64" (%"PRId64") - partial file?\n", - mxf->run_in + mxf->footer_partition, ret); - return ret; - } - - mxf->current_partition = NULL; - mxf->parsing_backward = 1; - } - - return 1; -} - -/** - * Called when the next partition or EOF is encountered - * @return <= 0 if we should stop parsing, > 0 if we should keep going - */ -static int mxf_parse_handle_partition_or_eof(MXFContext *mxf) -{ - return mxf->parsing_backward ? mxf_seek_to_previous_partition(mxf) : 1; -} - -/** - * Figures out the proper offset and length of the essence container in each partition - */ -static void mxf_compute_essence_containers(MXFContext *mxf) -{ - int x; - - /* everything is already correct */ - if (mxf->op == OPAtom) - return; - - for (x = 0; x < mxf->partitions_count; x++) { - MXFPartition *p = &mxf->partitions[x]; - - if (!p->body_sid) - continue; /* BodySID == 0 -> no essence */ - - if (x >= mxf->partitions_count - 1) - break; /* last partition - can't compute length (and we don't need to) */ - - /* essence container spans to the next partition */ - p->essence_length = mxf->partitions[x+1].this_partition - p->essence_offset; - - if (p->essence_length < 0) { - /* next ThisPartition < essence_offset */ - p->essence_length = 0; - av_log(mxf->fc, AV_LOG_ERROR, - "partition %i: bad ThisPartition = %"PRIX64"\n", - x+1, mxf->partitions[x+1].this_partition); - } - } -} - -static int64_t round_to_kag(int64_t position, int kag_size) -{ - /* TODO: account for run-in? the spec isn't clear whether KAG should account for it */ - /* NOTE: kag_size may be any integer between 1 - 2^10 */ - int64_t ret = (position / kag_size) * kag_size; - return ret == position ? ret : ret + kag_size; -} - -static int is_pcm(enum AVCodecID codec_id) -{ - /* we only care about "normal" PCM codecs until we get samples */ - return codec_id >= AV_CODEC_ID_PCM_S16LE && codec_id < AV_CODEC_ID_PCM_S24DAUD; -} - -/** - * Deal with the case where for some audio atoms EditUnitByteCount is - * very small (2, 4..). In those cases we should read more than one - * sample per call to mxf_read_packet(). - */ -static void mxf_handle_small_eubc(AVFormatContext *s) -{ - MXFContext *mxf = s->priv_data; - - /* assuming non-OPAtom == frame wrapped - * no sane writer would wrap 2 byte PCM packets with 20 byte headers.. */ - if (mxf->op != OPAtom) - return; - - /* expect PCM with exactly one index table segment and a small (< 32) EUBC */ - if (s->nb_streams != 1 || - s->streams[0]->codec->codec_type != AVMEDIA_TYPE_AUDIO || - !is_pcm(s->streams[0]->codec->codec_id) || - mxf->nb_index_tables != 1 || - mxf->index_tables[0].nb_segments != 1 || - mxf->index_tables[0].segments[0]->edit_unit_byte_count >= 32) - return; - - /* arbitrarily default to 48 kHz PAL audio frame size */ - /* TODO: We could compute this from the ratio between the audio - * and video edit rates for 48 kHz NTSC we could use the - * 1802-1802-1802-1802-1801 pattern. */ - mxf->edit_units_per_packet = 1920; -} - -static int mxf_read_header(AVFormatContext *s) -{ - MXFContext *mxf = s->priv_data; - KLVPacket klv; - int64_t essence_offset = 0; - int ret; - - mxf->last_forward_tell = INT64_MAX; - mxf->edit_units_per_packet = 1; - - if (!mxf_read_sync(s->pb, mxf_header_partition_pack_key, 14)) { - av_log(s, AV_LOG_ERROR, "could not find header partition pack key\n"); - return AVERROR_INVALIDDATA; - } - avio_seek(s->pb, -14, SEEK_CUR); - mxf->fc = s; - mxf->run_in = avio_tell(s->pb); - - while (!url_feof(s->pb)) { - const MXFMetadataReadTableEntry *metadata; - - if (klv_read_packet(&klv, s->pb) < 0) { - /* EOF - seek to previous partition or stop */ - if(mxf_parse_handle_partition_or_eof(mxf) <= 0) - break; - else - continue; - } - - PRINT_KEY(s, "read header", klv.key); - av_dlog(s, "size %"PRIu64" offset %#"PRIx64"\n", klv.length, klv.offset); - if (IS_KLV_KEY(klv.key, mxf_encrypted_triplet_key) || - IS_KLV_KEY(klv.key, mxf_essence_element_key) || - IS_KLV_KEY(klv.key, mxf_avid_essence_element_key) || - IS_KLV_KEY(klv.key, mxf_system_item_key)) { - - if (!mxf->current_partition) { - av_log(mxf->fc, AV_LOG_ERROR, "found essence prior to first PartitionPack\n"); - return AVERROR_INVALIDDATA; - } - - if (!mxf->current_partition->essence_offset) { - /* for OP1a we compute essence_offset - * for OPAtom we point essence_offset after the KL (usually op1a_essence_offset + 20 or 25) - * TODO: for OP1a we could eliminate this entire if statement, always stopping parsing at op1a_essence_offset - * for OPAtom we still need the actual essence_offset though (the KL's length can vary) - */ - int64_t op1a_essence_offset = - round_to_kag(mxf->current_partition->this_partition + - mxf->current_partition->pack_length, mxf->current_partition->kag_size) + - round_to_kag(mxf->current_partition->header_byte_count, mxf->current_partition->kag_size) + - round_to_kag(mxf->current_partition->index_byte_count, mxf->current_partition->kag_size); - - if (mxf->op == OPAtom) { - /* point essence_offset to the actual data - * OPAtom has all the essence in one big KLV - */ - mxf->current_partition->essence_offset = avio_tell(s->pb); - mxf->current_partition->essence_length = klv.length; - } else { - /* NOTE: op1a_essence_offset may be less than to klv.offset (C0023S01.mxf) */ - mxf->current_partition->essence_offset = op1a_essence_offset; - } - } - - if (!essence_offset) - essence_offset = klv.offset; - - /* seek to footer, previous partition or stop */ - if (mxf_parse_handle_essence(mxf) <= 0) - break; - continue; - } else if (!memcmp(klv.key, mxf_header_partition_pack_key, 13) && - klv.key[13] >= 2 && klv.key[13] <= 4 && mxf->current_partition) { - /* next partition pack - keep going, seek to previous partition or stop */ - if(mxf_parse_handle_partition_or_eof(mxf) <= 0) - break; - else if (mxf->parsing_backward) - continue; - /* we're still parsing forward. proceed to parsing this partition pack */ - } - - for (metadata = mxf_metadata_read_table; metadata->read; metadata++) { - if (IS_KLV_KEY(klv.key, metadata->key)) { - int res; - if (klv.key[5] == 0x53) { - res = mxf_read_local_tags(mxf, &klv, metadata->read, metadata->ctx_size, metadata->type); - } else { - uint64_t next = avio_tell(s->pb) + klv.length; - res = metadata->read(mxf, s->pb, 0, klv.length, klv.key, klv.offset); - - /* only seek forward, else this can loop for a long time */ - if (avio_tell(s->pb) > next) { - av_log(s, AV_LOG_ERROR, "read past end of KLV @ %#"PRIx64"\n", - klv.offset); - return AVERROR_INVALIDDATA; - } - - avio_seek(s->pb, next, SEEK_SET); - } - if (res < 0) { - av_log(s, AV_LOG_ERROR, "error reading header metadata\n"); - return res; - } - break; - } - } - if (!metadata->read) - avio_skip(s->pb, klv.length); - } - /* FIXME avoid seek */ - if (!essence_offset) { - av_log(s, AV_LOG_ERROR, "no essence\n"); - return AVERROR_INVALIDDATA; - } - avio_seek(s->pb, essence_offset, SEEK_SET); - - mxf_compute_essence_containers(mxf); - - /* we need to do this before computing the index tables - * to be able to fill in zero IndexDurations with st->duration */ - if ((ret = mxf_parse_structural_metadata(mxf)) < 0) - goto fail; - - if ((ret = mxf_compute_index_tables(mxf)) < 0) - goto fail; - - if (mxf->nb_index_tables > 1) { - /* TODO: look up which IndexSID to use via EssenceContainerData */ - av_log(mxf->fc, AV_LOG_INFO, "got %i index tables - only the first one (IndexSID %i) will be used\n", - mxf->nb_index_tables, mxf->index_tables[0].index_sid); - } else if (mxf->nb_index_tables == 0 && mxf->op == OPAtom) { - av_log(mxf->fc, AV_LOG_ERROR, "cannot demux OPAtom without an index\n"); - ret = AVERROR_INVALIDDATA; - goto fail; - } - - mxf_handle_small_eubc(s); - - return 0; -fail: - mxf_read_close(s); - - return ret; -} - -/** - * Sets mxf->current_edit_unit based on what offset we're currently at. - * @return next_ofs if OK, <0 on error - */ -static int64_t mxf_set_current_edit_unit(MXFContext *mxf, int64_t current_offset) -{ - int64_t last_ofs = -1, next_ofs = -1; - MXFIndexTable *t = &mxf->index_tables[0]; - - /* this is called from the OP1a demuxing logic, which means there - * may be no index tables */ - if (mxf->nb_index_tables <= 0) - return -1; - - /* find mxf->current_edit_unit so that the next edit unit starts ahead of current_offset */ - while (mxf->current_edit_unit >= 0) { - if (mxf_edit_unit_absolute_offset(mxf, t, mxf->current_edit_unit + 1, NULL, &next_ofs, 0) < 0) - return -1; - - if (next_ofs <= last_ofs) { - /* large next_ofs didn't change or current_edit_unit wrapped - * around this fixes the infinite loop on zzuf3.mxf */ - av_log(mxf->fc, AV_LOG_ERROR, - "next_ofs didn't change. not deriving packet timestamps\n"); - return -1; - } - - if (next_ofs > current_offset) - break; - - last_ofs = next_ofs; - mxf->current_edit_unit++; - } - - /* not checking mxf->current_edit_unit >= t->nb_ptses here since CBR files may lack IndexEntryArrays */ - if (mxf->current_edit_unit < 0) - return -1; - - return next_ofs; -} - -static int mxf_compute_sample_count(MXFContext *mxf, int stream_index, uint64_t *sample_count) -{ - int i, total = 0, size = 0; - AVStream *st = mxf->fc->streams[stream_index]; - MXFTrack *track = st->priv_data; - AVRational time_base = av_inv_q(track->edit_rate); - AVRational sample_rate = av_inv_q(st->time_base); - const MXFSamplesPerFrame *spf = NULL; - - if ((sample_rate.num / sample_rate.den) == 48000) - spf = ff_mxf_get_samples_per_frame(mxf->fc, time_base); - if (!spf) { - int remainder = (sample_rate.num * time_base.num) % (time_base.den * sample_rate.den); - *sample_count = av_q2d(av_mul_q((AVRational){mxf->current_edit_unit, 1}, - av_mul_q(sample_rate, time_base))); - if (remainder) - av_log(mxf->fc, AV_LOG_WARNING, - "seeking detected on stream #%d with time base (%d/%d) and sample rate (%d/%d), audio pts won't be accurate.\n", - stream_index, time_base.num, time_base.den, sample_rate.num, sample_rate.den); - return 0; - } - - while (spf->samples_per_frame[size]) { - total += spf->samples_per_frame[size]; - size++; - } - - av_assert2(size); - - *sample_count = (mxf->current_edit_unit / size) * (uint64_t)total; - for (i = 0; i < mxf->current_edit_unit % size; i++) { - *sample_count += spf->samples_per_frame[i]; - } - - return 0; -} - -static int mxf_set_audio_pts(MXFContext *mxf, AVCodecContext *codec, AVPacket *pkt) -{ - MXFTrack *track = mxf->fc->streams[pkt->stream_index]->priv_data; - pkt->pts = track->sample_count; - if (codec->channels <= 0 || av_get_bits_per_sample(codec->codec_id) <= 0) - return AVERROR(EINVAL); - track->sample_count += pkt->size / (codec->channels * (int64_t)av_get_bits_per_sample(codec->codec_id) / 8); - return 0; -} - -static int mxf_read_packet_old(AVFormatContext *s, AVPacket *pkt) -{ - KLVPacket klv; - MXFContext *mxf = s->priv_data; - - while (!url_feof(s->pb)) { - int ret; - if (klv_read_packet(&klv, s->pb) < 0) - return -1; - PRINT_KEY(s, "read packet", klv.key); - av_dlog(s, "size %"PRIu64" offset %#"PRIx64"\n", klv.length, klv.offset); - if (IS_KLV_KEY(klv.key, mxf_encrypted_triplet_key)) { - ret = mxf_decrypt_triplet(s, pkt, &klv); - if (ret < 0) { - av_log(s, AV_LOG_ERROR, "invalid encoded triplet\n"); - return AVERROR_INVALIDDATA; - } - return 0; - } - if (IS_KLV_KEY(klv.key, mxf_essence_element_key) || - IS_KLV_KEY(klv.key, mxf_avid_essence_element_key)) { - int index = mxf_get_stream_index(s, &klv); - int64_t next_ofs, next_klv; - AVStream *st; - MXFTrack *track; - AVCodecContext *codec; - - if (index < 0) { - av_log(s, AV_LOG_ERROR, "error getting stream index %d\n", AV_RB32(klv.key+12)); - goto skip; - } - - st = s->streams[index]; - track = st->priv_data; - - if (s->streams[index]->discard == AVDISCARD_ALL) - goto skip; - - next_klv = avio_tell(s->pb) + klv.length; - next_ofs = mxf_set_current_edit_unit(mxf, klv.offset); - - if (next_ofs >= 0 && next_klv > next_ofs) { - /* if this check is hit then it's possible OPAtom was treated as OP1a - * truncate the packet since it's probably very large (>2 GiB is common) */ - avpriv_request_sample(s, - "OPAtom misinterpreted as OP1a?" - "KLV for edit unit %i extending into " - "next edit unit", - mxf->current_edit_unit); - klv.length = next_ofs - avio_tell(s->pb); - } - - /* check for 8 channels AES3 element */ - if (klv.key[12] == 0x06 && klv.key[13] == 0x01 && klv.key[14] == 0x10) { - if (mxf_get_d10_aes3_packet(s->pb, s->streams[index], pkt, klv.length) < 0) { - av_log(s, AV_LOG_ERROR, "error reading D-10 aes3 frame\n"); - return AVERROR_INVALIDDATA; - } - } else { - ret = av_get_packet(s->pb, pkt, klv.length); - if (ret < 0) - return ret; - } - pkt->stream_index = index; - pkt->pos = klv.offset; - - codec = s->streams[index]->codec; - if (codec->codec_type == AVMEDIA_TYPE_VIDEO && next_ofs >= 0) { - /* mxf->current_edit_unit good - see if we have an index table to derive timestamps from */ - MXFIndexTable *t = &mxf->index_tables[0]; - - if (mxf->nb_index_tables >= 1 && mxf->current_edit_unit < t->nb_ptses) { - pkt->dts = mxf->current_edit_unit + t->first_dts; - pkt->pts = t->ptses[mxf->current_edit_unit]; - } else if (track->intra_only) { - /* intra-only -> PTS = EditUnit. - * let utils.c figure out DTS since it can be < PTS if low_delay = 0 (Sony IMX30) */ - pkt->pts = mxf->current_edit_unit; - } - } else if (codec->codec_type == AVMEDIA_TYPE_AUDIO) { - int ret = mxf_set_audio_pts(mxf, codec, pkt); - if (ret < 0) - return ret; - } - - /* seek for truncated packets */ - avio_seek(s->pb, next_klv, SEEK_SET); - - return 0; - } else - skip: - avio_skip(s->pb, klv.length); - } - return AVERROR_EOF; -} - -static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - MXFContext *mxf = s->priv_data; - int ret, size; - int64_t ret64, pos, next_pos; - AVStream *st; - MXFIndexTable *t; - int edit_units; - - if (mxf->op != OPAtom) - return mxf_read_packet_old(s, pkt); - - /* OPAtom - clip wrapped demuxing */ - /* NOTE: mxf_read_header() makes sure nb_index_tables > 0 for OPAtom */ - st = s->streams[0]; - t = &mxf->index_tables[0]; - - if (mxf->current_edit_unit >= st->duration) - return AVERROR_EOF; - - edit_units = FFMIN(mxf->edit_units_per_packet, st->duration - mxf->current_edit_unit); - - if ((ret = mxf_edit_unit_absolute_offset(mxf, t, mxf->current_edit_unit, NULL, &pos, 1)) < 0) - return ret; - - /* compute size by finding the next edit unit or the end of the essence container - * not pretty, but it works */ - if ((ret = mxf_edit_unit_absolute_offset(mxf, t, mxf->current_edit_unit + edit_units, NULL, &next_pos, 0)) < 0 && - (next_pos = mxf_essence_container_end(mxf, t->body_sid)) <= 0) { - av_log(s, AV_LOG_ERROR, "unable to compute the size of the last packet\n"); - return AVERROR_INVALIDDATA; - } - - if ((size = next_pos - pos) <= 0) { - av_log(s, AV_LOG_ERROR, "bad size: %i\n", size); - return AVERROR_INVALIDDATA; - } - - if ((ret64 = avio_seek(s->pb, pos, SEEK_SET)) < 0) - return ret64; - - if ((size = av_get_packet(s->pb, pkt, size)) < 0) - return size; - - pkt->stream_index = 0; - - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && t->ptses && - mxf->current_edit_unit >= 0 && mxf->current_edit_unit < t->nb_ptses) { - pkt->dts = mxf->current_edit_unit + t->first_dts; - pkt->pts = t->ptses[mxf->current_edit_unit]; - } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - int ret = mxf_set_audio_pts(mxf, st->codec, pkt); - if (ret < 0) - return ret; - } - - mxf->current_edit_unit += edit_units; - - return 0; -} - -static int mxf_read_close(AVFormatContext *s) -{ - MXFContext *mxf = s->priv_data; - MXFIndexTableSegment *seg; - int i; - - av_freep(&mxf->packages_refs); - - for (i = 0; i < s->nb_streams; i++) - s->streams[i]->priv_data = NULL; - - for (i = 0; i < mxf->metadata_sets_count; i++) { - switch (mxf->metadata_sets[i]->type) { - case Descriptor: - av_freep(&((MXFDescriptor *)mxf->metadata_sets[i])->extradata); - break; - case MultipleDescriptor: - av_freep(&((MXFDescriptor *)mxf->metadata_sets[i])->sub_descriptors_refs); - break; - case Sequence: - av_freep(&((MXFSequence *)mxf->metadata_sets[i])->structural_components_refs); - break; - case SourcePackage: - case MaterialPackage: - av_freep(&((MXFPackage *)mxf->metadata_sets[i])->tracks_refs); - break; - case IndexTableSegment: - seg = (MXFIndexTableSegment *)mxf->metadata_sets[i]; - av_freep(&seg->temporal_offset_entries); - av_freep(&seg->flag_entries); - av_freep(&seg->stream_offset_entries); - break; - default: - break; - } - av_freep(&mxf->metadata_sets[i]); - } - av_freep(&mxf->partitions); - av_freep(&mxf->metadata_sets); - av_freep(&mxf->aesc); - av_freep(&mxf->local_tags); - - if (mxf->index_tables) { - for (i = 0; i < mxf->nb_index_tables; i++) { - av_freep(&mxf->index_tables[i].segments); - av_freep(&mxf->index_tables[i].ptses); - av_freep(&mxf->index_tables[i].fake_index); - } - } - av_freep(&mxf->index_tables); - - return 0; -} - -static int mxf_probe(AVProbeData *p) { - const uint8_t *bufp = p->buf; - const uint8_t *end = p->buf + p->buf_size; - - if (p->buf_size < sizeof(mxf_header_partition_pack_key)) - return 0; - - /* Must skip Run-In Sequence and search for MXF header partition pack key SMPTE 377M 5.5 */ - end -= sizeof(mxf_header_partition_pack_key); - for (; bufp < end; bufp++) { - if (IS_KLV_KEY(bufp, mxf_header_partition_pack_key)) - return AVPROBE_SCORE_MAX; - } - return 0; -} - -/* rudimentary byte seek */ -/* XXX: use MXF Index */ -static int mxf_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags) -{ - AVStream *st = s->streams[stream_index]; - int64_t seconds; - MXFContext* mxf = s->priv_data; - int64_t seekpos; - int i, ret; - MXFIndexTable *t; - MXFTrack *source_track = st->priv_data; - - /* if audio then truncate sample_time to EditRate */ - if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) - sample_time = av_rescale_q(sample_time, st->time_base, av_inv_q(source_track->edit_rate)); - - if (mxf->nb_index_tables <= 0) { - if (!s->bit_rate) - return AVERROR_INVALIDDATA; - if (sample_time < 0) - sample_time = 0; - seconds = av_rescale(sample_time, st->time_base.num, st->time_base.den); - - if ((ret = avio_seek(s->pb, (s->bit_rate * seconds) >> 3, SEEK_SET)) < 0) - return ret; - ff_update_cur_dts(s, st, sample_time); - } else { - t = &mxf->index_tables[0]; - - /* clamp above zero, else ff_index_search_timestamp() returns negative - * this also means we allow seeking before the start */ - sample_time = FFMAX(sample_time, 0); - - if (t->fake_index) { - /* behave as if we have a proper index */ - if ((sample_time = ff_index_search_timestamp(t->fake_index, t->nb_ptses, sample_time, flags)) < 0) - return sample_time; - } else { - /* no IndexEntryArray (one or more CBR segments) - * make sure we don't seek past the end */ - sample_time = FFMIN(sample_time, source_track->original_duration - 1); - } - - if ((ret = mxf_edit_unit_absolute_offset(mxf, t, sample_time, &sample_time, &seekpos, 1)) << 0) - return ret; - - ff_update_cur_dts(s, st, sample_time); - mxf->current_edit_unit = sample_time; - avio_seek(s->pb, seekpos, SEEK_SET); - } - - // Update all tracks sample count - for (i = 0; i < s->nb_streams; i++) { - AVStream *cur_st = s->streams[i]; - MXFTrack *cur_track = cur_st->priv_data; - uint64_t current_sample_count = 0; - if (cur_st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - ret = mxf_compute_sample_count(mxf, i, ¤t_sample_count); - if (ret < 0) - return ret; - - cur_track->sample_count = current_sample_count; - } - } - return 0; -} - -AVInputFormat ff_mxf_demuxer = { - .name = "mxf", - .long_name = NULL_IF_CONFIG_SMALL("MXF (Material eXchange Format)"), - .priv_data_size = sizeof(MXFContext), - .read_probe = mxf_probe, - .read_header = mxf_read_header, - .read_packet = mxf_read_packet, - .read_close = mxf_read_close, - .read_seek = mxf_read_seek, -}; diff --git a/ffmpeg1/libavformat/mxfenc.c b/ffmpeg1/libavformat/mxfenc.c deleted file mode 100644 index cf9b77d..0000000 --- a/ffmpeg1/libavformat/mxfenc.c +++ /dev/null @@ -1,2173 +0,0 @@ -/* - * MXF muxer - * Copyright (c) 2008 GUCAS, Zhentan Feng - * Copyright (c) 2008 Baptiste Coudurier - * - * 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 - */ - -/* - * References - * SMPTE 336M KLV Data Encoding Protocol Using Key-Length-Value - * SMPTE 377M MXF File Format Specifications - * SMPTE 379M MXF Generic Container - * SMPTE 381M Mapping MPEG Streams into the MXF Generic Container - * SMPTE RP210: SMPTE Metadata Dictionary - * SMPTE RP224: Registry of SMPTE Universal Labels - */ - -//#define DEBUG - -#include -#include - -#include "libavutil/opt.h" -#include "libavutil/random_seed.h" -#include "libavutil/timecode.h" -#include "libavutil/avassert.h" -#include "libavcodec/bytestream.h" -#include "libavcodec/dnxhddata.h" -#include "audiointerleave.h" -#include "avformat.h" -#include "internal.h" -#include "mxf.h" -#include "config.h" - -extern AVOutputFormat ff_mxf_d10_muxer; - -#define EDIT_UNITS_PER_BODY 250 -#define KAG_SIZE 512 - -typedef struct { - int local_tag; - UID uid; -} MXFLocalTagPair; - -typedef struct { - uint8_t flags; - uint64_t offset; - unsigned slice_offset; ///< offset of audio slice - uint16_t temporal_ref; -} MXFIndexEntry; - -typedef struct { - AudioInterleaveContext aic; - UID track_essence_element_key; - int index; ///< index in mxf_essence_container_uls table - const UID *codec_ul; - int order; ///< interleaving order if dts are equal - int interlaced; ///< whether picture is interlaced - int field_dominance; ///< tff=1, bff=2 - int component_depth; - int temporal_reordering; - AVRational aspect_ratio; ///< display aspect ratio - int closed_gop; ///< gop is closed, used in mpeg-2 frame parsing -} MXFStreamContext; - -typedef struct { - UID container_ul; - UID element_ul; - UID codec_ul; - void (*write_desc)(AVFormatContext *, AVStream *); -} MXFContainerEssenceEntry; - -static const struct { - enum AVCodecID id; - int index; -} mxf_essence_mappings[] = { - { AV_CODEC_ID_MPEG2VIDEO, 0 }, - { AV_CODEC_ID_PCM_S24LE, 1 }, - { AV_CODEC_ID_PCM_S16LE, 1 }, - { AV_CODEC_ID_DVVIDEO, 15 }, - { AV_CODEC_ID_DNXHD, 24 }, - { AV_CODEC_ID_NONE } -}; - -static void mxf_write_wav_desc(AVFormatContext *s, AVStream *st); -static void mxf_write_aes3_desc(AVFormatContext *s, AVStream *st); -static void mxf_write_mpegvideo_desc(AVFormatContext *s, AVStream *st); -static void mxf_write_cdci_desc(AVFormatContext *s, AVStream *st); -static void mxf_write_generic_sound_desc(AVFormatContext *s, AVStream *st); - -static const MXFContainerEssenceEntry mxf_essence_container_uls[] = { - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x02,0x0D,0x01,0x03,0x01,0x02,0x04,0x60,0x01 }, - { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x00,0x00,0x00 }, - mxf_write_mpegvideo_desc }, - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x06,0x03,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x16,0x01,0x03,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 }, - mxf_write_aes3_desc }, - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x06,0x01,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x16,0x01,0x01,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 }, - mxf_write_wav_desc }, - // D-10 625/50 PAL 50mb/s - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x01,0x01 }, - { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x01 }, - mxf_write_cdci_desc }, - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x01,0x01 }, - { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 }, - mxf_write_generic_sound_desc }, - // D-10 525/60 NTSC 50mb/s - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x02,0x01 }, - { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x02 }, - mxf_write_cdci_desc }, - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x02,0x01 }, - { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 }, - mxf_write_generic_sound_desc }, - // D-10 625/50 PAL 40mb/s - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x03,0x01 }, - { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x03 }, - mxf_write_cdci_desc }, - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x03,0x01 }, - { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 }, - mxf_write_generic_sound_desc }, - // D-10 525/60 NTSC 40mb/s - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x04,0x01 }, - { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x04 }, - mxf_write_cdci_desc }, - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x04,0x01 }, - { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 }, - mxf_write_generic_sound_desc }, - // D-10 625/50 PAL 30mb/s - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x05,0x01 }, - { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x05 }, - mxf_write_cdci_desc }, - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x05,0x01 }, - { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 }, - mxf_write_generic_sound_desc }, - // D-10 525/60 NTSC 30mb/s - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x06,0x01 }, - { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x05,0x01,0x01,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x01,0x02,0x01,0x06 }, - mxf_write_cdci_desc }, - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x01,0x06,0x01 }, - { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x06,0x01,0x10,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x02,0x02,0x01,0x00,0x00,0x00,0x00 }, - mxf_write_generic_sound_desc }, - // DV Unknown - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x7F,0x01 }, - { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x00,0x00,0x00 }, - mxf_write_cdci_desc }, - // DV25 525/60 - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x40,0x01 }, - { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x01,0x00 }, - mxf_write_cdci_desc }, - // DV25 625/50 - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x41,0x01 }, - { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x02,0x00 }, - mxf_write_cdci_desc }, - // DV50 525/60 - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x50,0x01 }, - { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x03,0x00 }, - mxf_write_cdci_desc }, - // DV50 625/50 - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x51,0x01 }, - { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x04,0x00 }, - mxf_write_cdci_desc }, - // DV100 1080/60 - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x60,0x01 }, - { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x05,0x00 }, - mxf_write_cdci_desc }, - // DV100 1080/50 - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x61,0x01 }, - { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x06,0x00 }, - mxf_write_cdci_desc }, - // DV100 720/60 - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x62,0x01 }, - { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x07,0x00 }, - mxf_write_cdci_desc }, - // DV100 720/50 - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x02,0x63,0x01 }, - { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x18,0x01,0x01,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x04,0x01,0x02,0x02,0x02,0x02,0x08,0x00 }, - mxf_write_cdci_desc }, - // DNxHD 1080p 10bit high - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x11,0x01,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x01,0x00,0x00 }, - mxf_write_cdci_desc }, - // DNxHD 1080p 8bit medium - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x11,0x01,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x03,0x00,0x00 }, - mxf_write_cdci_desc }, - // DNxHD 1080p 8bit high - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x11,0x01,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x04,0x00,0x00 }, - mxf_write_cdci_desc }, - // DNxHD 1080i 10bit high - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x11,0x01,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x07,0x00,0x00 }, - mxf_write_cdci_desc }, - // DNxHD 1080i 8bit medium - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x11,0x01,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x08,0x00,0x00 }, - mxf_write_cdci_desc }, - // DNxHD 1080i 8bit high - { { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x03,0x01,0x02,0x11,0x01,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x01,0x02,0x01,0x01,0x0D,0x01,0x03,0x01,0x15,0x01,0x05,0x00 }, - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x09,0x00,0x00 }, - mxf_write_cdci_desc }, - // DNxHD 720p 10bit - { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x11,0x01,0x00 }, - { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01,0x15,0x01,0x05,0x00 }, - { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x10,0x00,0x00 }, - mxf_write_cdci_desc }, - // DNxHD 720p 8bit high - { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x11,0x01,0x00 }, - { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01,0x15,0x01,0x05,0x00 }, - { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x11,0x00,0x00 }, - mxf_write_cdci_desc }, - // DNxHD 720p 8bit medium - { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x11,0x01,0x00 }, - { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01,0x15,0x01,0x05,0x00 }, - { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x12,0x00,0x00 }, - mxf_write_cdci_desc }, - // DNxHD 720p 8bit low - { { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x01,0x0d,0x01,0x03,0x01,0x02,0x11,0x01,0x00 }, - { 0x06,0x0e,0x2b,0x34,0x01,0x02,0x01,0x01,0x0d,0x01,0x03,0x01,0x15,0x01,0x05,0x00 }, - { 0x06,0x0e,0x2b,0x34,0x04,0x01,0x01,0x0A,0x04,0x01,0x02,0x02,0x71,0x13,0x00,0x00 }, - mxf_write_cdci_desc }, - { { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }, - NULL }, -}; - -typedef struct MXFContext { - AVClass *av_class; - int64_t footer_partition_offset; - int essence_container_count; - AVRational time_base; - int header_written; - MXFIndexEntry *index_entries; - unsigned edit_units_count; - uint64_t timestamp; ///< timestamp, as year(16),month(8),day(8),hour(8),minutes(8),msec/4(8) - uint8_t slice_count; ///< index slice count minus 1 (1 if no audio, 0 otherwise) - int last_indexed_edit_unit; - uint64_t *body_partition_offset; - unsigned body_partitions_count; - int last_key_index; ///< index of last key frame - uint64_t duration; - AVTimecode tc; ///< timecode context - AVStream *timecode_track; - int timecode_base; ///< rounded time code base (25 or 30) - int edit_unit_byte_count; ///< fixed edit unit byte count - uint64_t body_offset; - uint32_t instance_number; - uint8_t umid[16]; ///< unique material identifier -} MXFContext; - -static const uint8_t uuid_base[] = { 0xAD,0xAB,0x44,0x24,0x2f,0x25,0x4d,0xc7,0x92,0xff,0x29,0xbd }; -static const uint8_t umid_ul[] = { 0x06,0x0A,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x01,0x0D,0x00,0x13 }; - -/** - * complete key for operation pattern, partitions, and primer pack - */ -static const uint8_t op1a_ul[] = { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x01,0x09,0x00 }; -static const uint8_t footer_partition_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x04,0x04,0x00 }; // ClosedComplete -static const uint8_t primer_pack_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x05,0x01,0x00 }; -static const uint8_t index_table_segment_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x02,0x01,0x01,0x10,0x01,0x00 }; -static const uint8_t random_index_pack_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x11,0x01,0x00 }; -static const uint8_t header_open_partition_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x02,0x01,0x00 }; // OpenIncomplete -static const uint8_t header_closed_partition_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x02,0x04,0x00 }; // ClosedComplete -static const uint8_t klv_fill_key[] = { 0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x03,0x01,0x02,0x10,0x01,0x00,0x00,0x00 }; -static const uint8_t body_partition_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x02,0x01,0x01,0x03,0x04,0x00 }; // ClosedComplete - -/** - * partial key for header metadata - */ -static const uint8_t header_metadata_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0D,0x01,0x01,0x01,0x01 }; -static const uint8_t multiple_desc_ul[] = { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x0D,0x01,0x03,0x01,0x02,0x7F,0x01,0x00 }; - -/** - * SMPTE RP210 http://www.smpte-ra.org/mdd/index.html - */ -static const MXFLocalTagPair mxf_local_tag_batch[] = { - // preface set - { 0x3C0A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x01,0x01,0x15,0x02,0x00,0x00,0x00,0x00}}, /* Instance UID */ - { 0x3B02, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x10,0x02,0x04,0x00,0x00}}, /* Last Modified Date */ - { 0x3B05, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x03,0x01,0x02,0x01,0x05,0x00,0x00,0x00}}, /* Version */ - { 0x3B06, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x06,0x04,0x00,0x00}}, /* Identifications reference */ - { 0x3B03, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x02,0x01,0x00,0x00}}, /* Content Storage reference */ - { 0x3B09, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x02,0x02,0x03,0x00,0x00,0x00,0x00}}, /* Operational Pattern UL */ - { 0x3B0A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x02,0x02,0x10,0x02,0x01,0x00,0x00}}, /* Essence Containers UL batch */ - { 0x3B0B, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x01,0x02,0x02,0x10,0x02,0x02,0x00,0x00}}, /* DM Schemes UL batch */ - // Identification - { 0x3C09, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x01,0x00,0x00,0x00}}, /* This Generation UID */ - { 0x3C01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x02,0x01,0x00,0x00}}, /* Company Name */ - { 0x3C02, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x03,0x01,0x00,0x00}}, /* Product Name */ - { 0x3C04, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x05,0x01,0x00,0x00}}, /* Version String */ - { 0x3C05, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x20,0x07,0x01,0x07,0x00,0x00,0x00}}, /* Product ID */ - { 0x3C06, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x10,0x02,0x03,0x00,0x00}}, /* Modification Date */ - // Content Storage - { 0x1901, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x05,0x01,0x00,0x00}}, /* Package strong reference batch */ - { 0x1902, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x05,0x02,0x00,0x00}}, /* Package strong reference batch */ - // Essence Container Data - { 0x2701, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x06,0x01,0x00,0x00,0x00}}, /* Linked Package UID */ - { 0x3F07, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x01,0x03,0x04,0x04,0x00,0x00,0x00,0x00}}, /* BodySID */ - // Package - { 0x4401, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x01,0x01,0x15,0x10,0x00,0x00,0x00,0x00}}, /* Package UID */ - { 0x4405, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x10,0x01,0x03,0x00,0x00}}, /* Package Creation Date */ - { 0x4404, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x10,0x02,0x05,0x00,0x00}}, /* Package Modified Date */ - { 0x4403, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x06,0x05,0x00,0x00}}, /* Tracks Strong reference array */ - { 0x4701, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x02,0x03,0x00,0x00}}, /* Descriptor */ - // Track - { 0x4801, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x01,0x07,0x01,0x01,0x00,0x00,0x00,0x00}}, /* Track ID */ - { 0x4804, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x01,0x04,0x01,0x03,0x00,0x00,0x00,0x00}}, /* Track Number */ - { 0x4B01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x05,0x30,0x04,0x05,0x00,0x00,0x00,0x00}}, /* Edit Rate */ - { 0x4B02, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x03,0x01,0x03,0x00,0x00}}, /* Origin */ - { 0x4803, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x02,0x04,0x00,0x00}}, /* Sequence reference */ - // Sequence - { 0x0201, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x07,0x01,0x00,0x00,0x00,0x00,0x00}}, /* Data Definition UL */ - { 0x0202, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x02,0x01,0x01,0x03,0x00,0x00}}, /* Duration */ - { 0x1001, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x06,0x09,0x00,0x00}}, /* Structural Components reference array */ - // Source Clip - { 0x1201, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x03,0x01,0x04,0x00,0x00}}, /* Start position */ - { 0x1101, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x03,0x01,0x00,0x00,0x00}}, /* SourcePackageID */ - { 0x1102, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x03,0x02,0x00,0x00,0x00}}, /* SourceTrackID */ - // Timecode Component - { 0x1501, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x07,0x02,0x01,0x03,0x01,0x05,0x00,0x00}}, /* Start Time Code */ - { 0x1502, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x04,0x01,0x01,0x02,0x06,0x00,0x00}}, /* Rounded Time Code Base */ - { 0x1503, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x04,0x01,0x01,0x05,0x00,0x00,0x00}}, /* Drop Frame */ - // File Descriptor - { 0x3F01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x06,0x01,0x01,0x04,0x06,0x0B,0x00,0x00}}, /* Sub Descriptors reference array */ - { 0x3006, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x06,0x01,0x01,0x03,0x05,0x00,0x00,0x00}}, /* Linked Track ID */ - { 0x3001, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x06,0x01,0x01,0x00,0x00,0x00,0x00}}, /* SampleRate */ - { 0x3004, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x06,0x01,0x01,0x04,0x01,0x02,0x00,0x00}}, /* Essence Container */ - // Generic Picture Essence Descriptor - { 0x320C, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x03,0x01,0x04,0x00,0x00,0x00}}, /* Frame Layout */ - { 0x320D, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x03,0x02,0x05,0x00,0x00,0x00}}, /* Video Line Map */ - { 0x3203, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x02,0x02,0x00,0x00,0x00}}, /* Stored Width */ - { 0x3202, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x02,0x01,0x00,0x00,0x00}}, /* Stored Height */ - { 0x3209, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x0C,0x00,0x00,0x00}}, /* Display Width */ - { 0x3208, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x0B,0x00,0x00,0x00}}, /* Display Height */ - { 0x320E, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x01,0x01,0x01,0x00,0x00,0x00}}, /* Aspect Ratio */ - { 0x3201, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x06,0x01,0x00,0x00,0x00,0x00}}, /* Picture Essence Coding */ - { 0x3212, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x03,0x01,0x06,0x00,0x00,0x00}}, /* Field Dominance (Opt) */ - // CDCI Picture Essence Descriptor - { 0x3301, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x01,0x05,0x03,0x0A,0x00,0x00,0x00}}, /* Component Depth */ - { 0x3302, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x01,0x04,0x01,0x05,0x01,0x05,0x00,0x00,0x00}}, /* Horizontal Subsampling */ - // Generic Sound Essence Descriptor - { 0x3D02, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x04,0x02,0x03,0x01,0x04,0x00,0x00,0x00}}, /* Locked/Unlocked */ - { 0x3D03, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x03,0x01,0x01,0x01,0x00,0x00}}, /* Audio sampling rate */ - { 0x3D07, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x01,0x01,0x04,0x00,0x00,0x00}}, /* ChannelCount */ - { 0x3D01, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x04,0x02,0x03,0x03,0x04,0x00,0x00,0x00}}, /* Quantization bits */ - { 0x3D06, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x02,0x04,0x02,0x04,0x02,0x00,0x00,0x00,0x00}}, /* Sound Essence Compression */ - // Index Table Segment - { 0x3F0B, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x05,0x30,0x04,0x06,0x00,0x00,0x00,0x00}}, /* Index Edit Rate */ - { 0x3F0C, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x07,0x02,0x01,0x03,0x01,0x0A,0x00,0x00}}, /* Index Start Position */ - { 0x3F0D, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x07,0x02,0x02,0x01,0x01,0x02,0x00,0x00}}, /* Index Duration */ - { 0x3F05, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x04,0x06,0x02,0x01,0x00,0x00,0x00,0x00}}, /* Edit Unit Byte Count */ - { 0x3F06, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x01,0x03,0x04,0x05,0x00,0x00,0x00,0x00}}, /* IndexSID */ - { 0x3F08, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x04,0x04,0x04,0x04,0x01,0x01,0x00,0x00,0x00}}, /* Slice Count */ - { 0x3F09, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x04,0x04,0x01,0x06,0x00,0x00,0x00}}, /* Delta Entry Array */ - { 0x3F0A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x04,0x04,0x02,0x05,0x00,0x00,0x00}}, /* Index Entry Array */ - // MPEG video Descriptor - { 0x8000, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x06,0x02,0x01,0x0B,0x00,0x00}}, /* BitRate */ - { 0x8007, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x01,0x06,0x02,0x01,0x0A,0x00,0x00}}, /* ProfileAndLevel */ - // Wave Audio Essence Descriptor - { 0x3D09, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x03,0x03,0x05,0x00,0x00,0x00}}, /* Average Bytes Per Second */ - { 0x3D0A, {0x06,0x0E,0x2B,0x34,0x01,0x01,0x01,0x05,0x04,0x02,0x03,0x02,0x01,0x00,0x00,0x00}}, /* Block Align */ -}; - -static void mxf_write_uuid(AVIOContext *pb, enum MXFMetadataSetType type, int value) -{ - avio_write(pb, uuid_base, 12); - avio_wb16(pb, type); - avio_wb16(pb, value); -} - -static void mxf_write_umid(AVFormatContext *s, int type) -{ - MXFContext *mxf = s->priv_data; - avio_write(s->pb, umid_ul, 13); - avio_wb24(s->pb, mxf->instance_number); - avio_write(s->pb, mxf->umid, 15); - avio_w8(s->pb, type); -} - -static void mxf_write_refs_count(AVIOContext *pb, int ref_count) -{ - avio_wb32(pb, ref_count); - avio_wb32(pb, 16); -} - -static int klv_ber_length(uint64_t len) -{ - if (len < 128) - return 1; - else - return (av_log2(len) >> 3) + 2; -} - -static int klv_encode_ber_length(AVIOContext *pb, uint64_t len) -{ - // Determine the best BER size - int size; - if (len < 128) { - //short form - avio_w8(pb, len); - return 1; - } - - size = (av_log2(len) >> 3) + 1; - - // long form - avio_w8(pb, 0x80 + size); - while(size) { - size--; - avio_w8(pb, len >> 8 * size & 0xff); - } - return 0; -} - -static void klv_encode_ber4_length(AVIOContext *pb, int len) -{ - avio_w8(pb, 0x80 + 3); - avio_wb24(pb, len); -} - -/* - * Get essence container ul index - */ -static int mxf_get_essence_container_ul_index(enum AVCodecID id) -{ - int i; - for (i = 0; mxf_essence_mappings[i].id; i++) - if (mxf_essence_mappings[i].id == id) - return mxf_essence_mappings[i].index; - return -1; -} - -static void mxf_write_primer_pack(AVFormatContext *s) -{ - AVIOContext *pb = s->pb; - int local_tag_number, i = 0; - - local_tag_number = FF_ARRAY_ELEMS(mxf_local_tag_batch); - - avio_write(pb, primer_pack_key, 16); - klv_encode_ber_length(pb, local_tag_number * 18 + 8); - - avio_wb32(pb, local_tag_number); // local_tag num - avio_wb32(pb, 18); // item size, always 18 according to the specs - - for (i = 0; i < local_tag_number; i++) { - avio_wb16(pb, mxf_local_tag_batch[i].local_tag); - avio_write(pb, mxf_local_tag_batch[i].uid, 16); - } -} - -static void mxf_write_local_tag(AVIOContext *pb, int size, int tag) -{ - avio_wb16(pb, tag); - avio_wb16(pb, size); -} - -static void mxf_write_metadata_key(AVIOContext *pb, unsigned int value) -{ - avio_write(pb, header_metadata_key, 13); - avio_wb24(pb, value); -} - -static void mxf_free(AVFormatContext *s) -{ - int i; - - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - av_freep(&st->priv_data); - } -} - -static const MXFCodecUL *mxf_get_data_definition_ul(int type) -{ - const MXFCodecUL *uls = ff_mxf_data_definition_uls; - while (uls->uid[0]) { - if (type == uls->id) - break; - uls++; - } - return uls; -} - -//one EC -> one descriptor. N ECs -> MultipleDescriptor + N descriptors -#define DESCRIPTOR_COUNT(essence_container_count) \ - (essence_container_count > 1 ? essence_container_count + 1 : essence_container_count) - -static void mxf_write_essence_container_refs(AVFormatContext *s) -{ - MXFContext *c = s->priv_data; - AVIOContext *pb = s->pb; - int i; - - mxf_write_refs_count(pb, DESCRIPTOR_COUNT(c->essence_container_count)); - av_log(s,AV_LOG_DEBUG, "essence container count:%d\n", c->essence_container_count); - for (i = 0; i < c->essence_container_count; i++) { - MXFStreamContext *sc = s->streams[i]->priv_data; - avio_write(pb, mxf_essence_container_uls[sc->index].container_ul, 16); - } - - if (c->essence_container_count > 1) - avio_write(pb, multiple_desc_ul, 16); -} - -static void mxf_write_preface(AVFormatContext *s) -{ - MXFContext *mxf = s->priv_data; - AVIOContext *pb = s->pb; - - mxf_write_metadata_key(pb, 0x012f00); - PRINT_KEY(s, "preface key", pb->buf_ptr - 16); - klv_encode_ber_length(pb, 130 + 16LL * DESCRIPTOR_COUNT(mxf->essence_container_count)); - - // write preface set uid - mxf_write_local_tag(pb, 16, 0x3C0A); - mxf_write_uuid(pb, Preface, 0); - PRINT_KEY(s, "preface uid", pb->buf_ptr - 16); - - // last modified date - mxf_write_local_tag(pb, 8, 0x3B02); - avio_wb64(pb, mxf->timestamp); - - // write version - mxf_write_local_tag(pb, 2, 0x3B05); - avio_wb16(pb, 258); // v1.2 - - // write identification_refs - mxf_write_local_tag(pb, 16 + 8, 0x3B06); - mxf_write_refs_count(pb, 1); - mxf_write_uuid(pb, Identification, 0); - - // write content_storage_refs - mxf_write_local_tag(pb, 16, 0x3B03); - mxf_write_uuid(pb, ContentStorage, 0); - - // operational pattern - mxf_write_local_tag(pb, 16, 0x3B09); - avio_write(pb, op1a_ul, 16); - - // write essence_container_refs - mxf_write_local_tag(pb, 8 + 16LL * DESCRIPTOR_COUNT(mxf->essence_container_count), 0x3B0A); - mxf_write_essence_container_refs(s); - - // write dm_scheme_refs - mxf_write_local_tag(pb, 8, 0x3B0B); - avio_wb64(pb, 0); -} - -/* - * Write a local tag containing an ascii string as utf-16 - */ -static void mxf_write_local_tag_utf16(AVIOContext *pb, int tag, const char *value) -{ - int i, size = strlen(value); - mxf_write_local_tag(pb, size*2, tag); - for (i = 0; i < size; i++) - avio_wb16(pb, value[i]); -} - -static void mxf_write_identification(AVFormatContext *s) -{ - MXFContext *mxf = s->priv_data; - AVIOContext *pb = s->pb; - const char *company = "FFmpeg"; - const char *product = "OP1a Muxer"; - const char *version; - int length; - - mxf_write_metadata_key(pb, 0x013000); - PRINT_KEY(s, "identification key", pb->buf_ptr - 16); - - version = s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT ? - "0.0.0" : AV_STRINGIFY(LIBAVFORMAT_VERSION); - length = 84 + (strlen(company)+strlen(product)+strlen(version))*2; // utf-16 - klv_encode_ber_length(pb, length); - - // write uid - mxf_write_local_tag(pb, 16, 0x3C0A); - mxf_write_uuid(pb, Identification, 0); - PRINT_KEY(s, "identification uid", pb->buf_ptr - 16); - - // write generation uid - mxf_write_local_tag(pb, 16, 0x3C09); - mxf_write_uuid(pb, Identification, 1); - - mxf_write_local_tag_utf16(pb, 0x3C01, company); // Company Name - mxf_write_local_tag_utf16(pb, 0x3C02, product); // Product Name - mxf_write_local_tag_utf16(pb, 0x3C04, version); // Version String - - // write product uid - mxf_write_local_tag(pb, 16, 0x3C05); - mxf_write_uuid(pb, Identification, 2); - - // modification date - mxf_write_local_tag(pb, 8, 0x3C06); - avio_wb64(pb, mxf->timestamp); -} - -static void mxf_write_content_storage(AVFormatContext *s) -{ - AVIOContext *pb = s->pb; - - mxf_write_metadata_key(pb, 0x011800); - PRINT_KEY(s, "content storage key", pb->buf_ptr - 16); - klv_encode_ber_length(pb, 92); - - // write uid - mxf_write_local_tag(pb, 16, 0x3C0A); - mxf_write_uuid(pb, ContentStorage, 0); - PRINT_KEY(s, "content storage uid", pb->buf_ptr - 16); - - // write package reference - mxf_write_local_tag(pb, 16 * 2 + 8, 0x1901); - mxf_write_refs_count(pb, 2); - mxf_write_uuid(pb, MaterialPackage, 0); - mxf_write_uuid(pb, SourcePackage, 0); - - // write essence container data - mxf_write_local_tag(pb, 8 + 16, 0x1902); - mxf_write_refs_count(pb, 1); - mxf_write_uuid(pb, EssenceContainerData, 0); -} - -static void mxf_write_track(AVFormatContext *s, AVStream *st, enum MXFMetadataSetType type) -{ - MXFContext *mxf = s->priv_data; - AVIOContext *pb = s->pb; - MXFStreamContext *sc = st->priv_data; - - mxf_write_metadata_key(pb, 0x013b00); - PRINT_KEY(s, "track key", pb->buf_ptr - 16); - klv_encode_ber_length(pb, 80); - - // write track uid - mxf_write_local_tag(pb, 16, 0x3C0A); - mxf_write_uuid(pb, type == MaterialPackage ? Track : Track + TypeBottom, st->index); - PRINT_KEY(s, "track uid", pb->buf_ptr - 16); - - // write track id - mxf_write_local_tag(pb, 4, 0x4801); - avio_wb32(pb, st->index+2); - - // write track number - mxf_write_local_tag(pb, 4, 0x4804); - if (type == MaterialPackage) - avio_wb32(pb, 0); // track number of material package is 0 - else - avio_write(pb, sc->track_essence_element_key + 12, 4); - - mxf_write_local_tag(pb, 8, 0x4B01); - avio_wb32(pb, mxf->time_base.den); - avio_wb32(pb, mxf->time_base.num); - - // write origin - mxf_write_local_tag(pb, 8, 0x4B02); - avio_wb64(pb, 0); - - // write sequence refs - mxf_write_local_tag(pb, 16, 0x4803); - mxf_write_uuid(pb, type == MaterialPackage ? Sequence: Sequence + TypeBottom, st->index); -} - -static const uint8_t smpte_12m_timecode_track_data_ul[] = { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x01,0x01,0x03,0x02,0x01,0x01,0x00,0x00,0x00 }; - -static void mxf_write_common_fields(AVFormatContext *s, AVStream *st) -{ - MXFContext *mxf = s->priv_data; - AVIOContext *pb = s->pb; - - // find data define uls - mxf_write_local_tag(pb, 16, 0x0201); - if (st == mxf->timecode_track) - avio_write(pb, smpte_12m_timecode_track_data_ul, 16); - else { - const MXFCodecUL *data_def_ul = mxf_get_data_definition_ul(st->codec->codec_type); - avio_write(pb, data_def_ul->uid, 16); - } - - // write duration - mxf_write_local_tag(pb, 8, 0x0202); - avio_wb64(pb, mxf->duration); -} - -static void mxf_write_sequence(AVFormatContext *s, AVStream *st, enum MXFMetadataSetType type) -{ - MXFContext *mxf = s->priv_data; - AVIOContext *pb = s->pb; - enum MXFMetadataSetType component; - - mxf_write_metadata_key(pb, 0x010f00); - PRINT_KEY(s, "sequence key", pb->buf_ptr - 16); - klv_encode_ber_length(pb, 80); - - mxf_write_local_tag(pb, 16, 0x3C0A); - mxf_write_uuid(pb, type == MaterialPackage ? Sequence: Sequence + TypeBottom, st->index); - - PRINT_KEY(s, "sequence uid", pb->buf_ptr - 16); - mxf_write_common_fields(s, st); - - // write structural component - mxf_write_local_tag(pb, 16 + 8, 0x1001); - mxf_write_refs_count(pb, 1); - if (st == mxf->timecode_track) - component = TimecodeComponent; - else - component = SourceClip; - if (type == SourcePackage) - component += TypeBottom; - mxf_write_uuid(pb, component, st->index); -} - -static void mxf_write_timecode_component(AVFormatContext *s, AVStream *st, enum MXFMetadataSetType type) -{ - MXFContext *mxf = s->priv_data; - AVIOContext *pb = s->pb; - - mxf_write_metadata_key(pb, 0x011400); - klv_encode_ber_length(pb, 75); - - // UID - mxf_write_local_tag(pb, 16, 0x3C0A); - mxf_write_uuid(pb, type == MaterialPackage ? TimecodeComponent : - TimecodeComponent + TypeBottom, st->index); - - mxf_write_common_fields(s, st); - - // Start Time Code - mxf_write_local_tag(pb, 8, 0x1501); - avio_wb64(pb, mxf->tc.start); - - // Rounded Time Code Base - mxf_write_local_tag(pb, 2, 0x1502); - avio_wb16(pb, mxf->timecode_base); - - // Drop Frame - mxf_write_local_tag(pb, 1, 0x1503); - avio_w8(pb, !!(mxf->tc.flags & AV_TIMECODE_FLAG_DROPFRAME)); -} - -static void mxf_write_structural_component(AVFormatContext *s, AVStream *st, enum MXFMetadataSetType type) -{ - AVIOContext *pb = s->pb; - int i; - - mxf_write_metadata_key(pb, 0x011100); - PRINT_KEY(s, "sturctural component key", pb->buf_ptr - 16); - klv_encode_ber_length(pb, 108); - - // write uid - mxf_write_local_tag(pb, 16, 0x3C0A); - mxf_write_uuid(pb, type == MaterialPackage ? SourceClip: SourceClip + TypeBottom, st->index); - - PRINT_KEY(s, "structural component uid", pb->buf_ptr - 16); - mxf_write_common_fields(s, st); - - // write start_position - mxf_write_local_tag(pb, 8, 0x1201); - avio_wb64(pb, 0); - - // write source package uid, end of the reference - mxf_write_local_tag(pb, 32, 0x1101); - if (type == SourcePackage) { - for (i = 0; i < 4; i++) - avio_wb64(pb, 0); - } else - mxf_write_umid(s, 1); - - // write source track id - mxf_write_local_tag(pb, 4, 0x1102); - if (type == SourcePackage) - avio_wb32(pb, 0); - else - avio_wb32(pb, st->index+2); -} - -static void mxf_write_multi_descriptor(AVFormatContext *s) -{ - MXFContext *mxf = s->priv_data; - AVIOContext *pb = s->pb; - const uint8_t *ul; - int i; - - mxf_write_metadata_key(pb, 0x014400); - PRINT_KEY(s, "multiple descriptor key", pb->buf_ptr - 16); - klv_encode_ber_length(pb, 64 + 16LL * s->nb_streams); - - mxf_write_local_tag(pb, 16, 0x3C0A); - mxf_write_uuid(pb, MultipleDescriptor, 0); - PRINT_KEY(s, "multi_desc uid", pb->buf_ptr - 16); - - // write sample rate - mxf_write_local_tag(pb, 8, 0x3001); - avio_wb32(pb, mxf->time_base.den); - avio_wb32(pb, mxf->time_base.num); - - // write essence container ul - mxf_write_local_tag(pb, 16, 0x3004); - if (mxf->essence_container_count > 1) - ul = multiple_desc_ul; - else { - MXFStreamContext *sc = s->streams[0]->priv_data; - ul = mxf_essence_container_uls[sc->index].container_ul; - } - avio_write(pb, ul, 16); - - // write sub descriptor refs - mxf_write_local_tag(pb, s->nb_streams * 16 + 8, 0x3F01); - mxf_write_refs_count(pb, s->nb_streams); - for (i = 0; i < s->nb_streams; i++) - mxf_write_uuid(pb, SubDescriptor, i); -} - -static void mxf_write_generic_desc(AVFormatContext *s, AVStream *st, const UID key, unsigned size) -{ - MXFContext *mxf = s->priv_data; - MXFStreamContext *sc = st->priv_data; - AVIOContext *pb = s->pb; - - avio_write(pb, key, 16); - klv_encode_ber4_length(pb, size+20+8+12+20); - - mxf_write_local_tag(pb, 16, 0x3C0A); - mxf_write_uuid(pb, SubDescriptor, st->index); - - mxf_write_local_tag(pb, 4, 0x3006); - avio_wb32(pb, st->index+2); - - mxf_write_local_tag(pb, 8, 0x3001); - avio_wb32(pb, mxf->time_base.den); - avio_wb32(pb, mxf->time_base.num); - - mxf_write_local_tag(pb, 16, 0x3004); - avio_write(pb, mxf_essence_container_uls[sc->index].container_ul, 16); -} - -static const UID mxf_mpegvideo_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x51,0x00 }; -static const UID mxf_wav_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x48,0x00 }; -static const UID mxf_aes3_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0d,0x01,0x01,0x01,0x01,0x01,0x47,0x00 }; -static const UID mxf_cdci_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0D,0x01,0x01,0x01,0x01,0x01,0x28,0x00 }; -static const UID mxf_generic_sound_descriptor_key = { 0x06,0x0E,0x2B,0x34,0x02,0x53,0x01,0x01,0x0D,0x01,0x01,0x01,0x01,0x01,0x42,0x00 }; - -static void mxf_write_cdci_common(AVFormatContext *s, AVStream *st, const UID key, unsigned size) -{ - MXFStreamContext *sc = st->priv_data; - AVIOContext *pb = s->pb; - int stored_height = (st->codec->height+15)/16*16; - int display_height; - int f1, f2; - unsigned desc_size = size+8+8+8+8+8+8+5+16+sc->interlaced*4+12+20; - if (sc->interlaced && sc->field_dominance) - desc_size += 5; - - mxf_write_generic_desc(s, st, key, desc_size); - - mxf_write_local_tag(pb, 4, 0x3203); - avio_wb32(pb, st->codec->width); - - mxf_write_local_tag(pb, 4, 0x3202); - avio_wb32(pb, stored_height>>sc->interlaced); - - mxf_write_local_tag(pb, 4, 0x3209); - avio_wb32(pb, st->codec->width); - - if (st->codec->height == 608) // PAL + VBI - display_height = 576; - else if (st->codec->height == 512) // NTSC + VBI - display_height = 486; - else - display_height = st->codec->height; - - mxf_write_local_tag(pb, 4, 0x3208); - avio_wb32(pb, display_height>>sc->interlaced); - - // component depth - mxf_write_local_tag(pb, 4, 0x3301); - avio_wb32(pb, sc->component_depth); - - // horizontal subsampling - mxf_write_local_tag(pb, 4, 0x3302); - avio_wb32(pb, 2); - - // frame layout - mxf_write_local_tag(pb, 1, 0x320C); - avio_w8(pb, sc->interlaced); - - // video line map - switch (st->codec->height) { - case 576: f1 = 23; f2 = st->codec->codec_id == AV_CODEC_ID_DVVIDEO ? 335 : 336; break; - case 608: f1 = 7; f2 = 320; break; - case 480: f1 = 20; f2 = st->codec->codec_id == AV_CODEC_ID_DVVIDEO ? 285 : 283; break; - case 512: f1 = 7; f2 = 270; break; - case 720: f1 = 26; f2 = 0; break; // progressive - case 1080: f1 = 21; f2 = 584; break; - default: f1 = 0; f2 = 0; break; - } - - if (!sc->interlaced) { - f2 = 0; - f1 *= 2; - } - - mxf_write_local_tag(pb, 12+sc->interlaced*4, 0x320D); - avio_wb32(pb, sc->interlaced ? 2 : 1); - avio_wb32(pb, 4); - avio_wb32(pb, f1); - if (sc->interlaced) - avio_wb32(pb, f2); - - mxf_write_local_tag(pb, 8, 0x320E); - avio_wb32(pb, sc->aspect_ratio.num); - avio_wb32(pb, sc->aspect_ratio.den); - - mxf_write_local_tag(pb, 16, 0x3201); - avio_write(pb, *sc->codec_ul, 16); - - if (sc->interlaced && sc->field_dominance) { - mxf_write_local_tag(pb, 1, 0x3212); - avio_w8(pb, sc->field_dominance); - } - -} - -static void mxf_write_cdci_desc(AVFormatContext *s, AVStream *st) -{ - mxf_write_cdci_common(s, st, mxf_cdci_descriptor_key, 0); -} - -static void mxf_write_mpegvideo_desc(AVFormatContext *s, AVStream *st) -{ - AVIOContext *pb = s->pb; - int profile_and_level = (st->codec->profile<<4) | st->codec->level; - - mxf_write_cdci_common(s, st, mxf_mpegvideo_descriptor_key, 8+5); - - // bit rate - mxf_write_local_tag(pb, 4, 0x8000); - avio_wb32(pb, st->codec->bit_rate); - - // profile and level - mxf_write_local_tag(pb, 1, 0x8007); - if (!st->codec->profile) - profile_and_level |= 0x80; // escape bit - avio_w8(pb, profile_and_level); -} - -static void mxf_write_generic_sound_common(AVFormatContext *s, AVStream *st, const UID key, unsigned size) -{ - AVIOContext *pb = s->pb; - - mxf_write_generic_desc(s, st, key, size+5+12+8+8); - - // audio locked - mxf_write_local_tag(pb, 1, 0x3D02); - avio_w8(pb, 1); - - // write audio sampling rate - mxf_write_local_tag(pb, 8, 0x3D03); - avio_wb32(pb, st->codec->sample_rate); - avio_wb32(pb, 1); - - mxf_write_local_tag(pb, 4, 0x3D07); - avio_wb32(pb, st->codec->channels); - - mxf_write_local_tag(pb, 4, 0x3D01); - avio_wb32(pb, av_get_bits_per_sample(st->codec->codec_id)); -} - -static void mxf_write_wav_common(AVFormatContext *s, AVStream *st, const UID key, unsigned size) -{ - AVIOContext *pb = s->pb; - - mxf_write_generic_sound_common(s, st, key, size+6+8); - - mxf_write_local_tag(pb, 2, 0x3D0A); - avio_wb16(pb, st->codec->block_align); - - // avg bytes per sec - mxf_write_local_tag(pb, 4, 0x3D09); - avio_wb32(pb, st->codec->block_align*st->codec->sample_rate); -} - -static void mxf_write_wav_desc(AVFormatContext *s, AVStream *st) -{ - mxf_write_wav_common(s, st, mxf_wav_descriptor_key, 0); -} - -static void mxf_write_aes3_desc(AVFormatContext *s, AVStream *st) -{ - mxf_write_wav_common(s, st, mxf_aes3_descriptor_key, 0); -} - -static void mxf_write_generic_sound_desc(AVFormatContext *s, AVStream *st) -{ - mxf_write_generic_sound_common(s, st, mxf_generic_sound_descriptor_key, 0); -} - -static void mxf_write_package(AVFormatContext *s, enum MXFMetadataSetType type) -{ - MXFContext *mxf = s->priv_data; - AVIOContext *pb = s->pb; - int i, track_count = s->nb_streams+1; - - if (type == MaterialPackage) { - mxf_write_metadata_key(pb, 0x013600); - PRINT_KEY(s, "Material Package key", pb->buf_ptr - 16); - klv_encode_ber_length(pb, 92 + 16*track_count); - } else { - mxf_write_metadata_key(pb, 0x013700); - PRINT_KEY(s, "Source Package key", pb->buf_ptr - 16); - klv_encode_ber_length(pb, 112 + 16*track_count); // 20 bytes length for descriptor reference - } - - // write uid - mxf_write_local_tag(pb, 16, 0x3C0A); - mxf_write_uuid(pb, type, 0); - av_log(s,AV_LOG_DEBUG, "package type:%d\n", type); - PRINT_KEY(s, "package uid", pb->buf_ptr - 16); - - // write package umid - mxf_write_local_tag(pb, 32, 0x4401); - mxf_write_umid(s, type == SourcePackage); - PRINT_KEY(s, "package umid second part", pb->buf_ptr - 16); - - // package creation date - mxf_write_local_tag(pb, 8, 0x4405); - avio_wb64(pb, mxf->timestamp); - - // package modified date - mxf_write_local_tag(pb, 8, 0x4404); - avio_wb64(pb, mxf->timestamp); - - // write track refs - mxf_write_local_tag(pb, track_count*16 + 8, 0x4403); - mxf_write_refs_count(pb, track_count); - mxf_write_uuid(pb, type == MaterialPackage ? Track : - Track + TypeBottom, -1); // timecode track - for (i = 0; i < s->nb_streams; i++) - mxf_write_uuid(pb, type == MaterialPackage ? Track : Track + TypeBottom, i); - - // write multiple descriptor reference - if (type == SourcePackage) { - mxf_write_local_tag(pb, 16, 0x4701); - if (s->nb_streams > 1) { - mxf_write_uuid(pb, MultipleDescriptor, 0); - mxf_write_multi_descriptor(s); - } else - mxf_write_uuid(pb, SubDescriptor, 0); - } - - // write timecode track - mxf_write_track(s, mxf->timecode_track, type); - mxf_write_sequence(s, mxf->timecode_track, type); - mxf_write_timecode_component(s, mxf->timecode_track, type); - - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - mxf_write_track(s, st, type); - mxf_write_sequence(s, st, type); - mxf_write_structural_component(s, st, type); - - if (type == SourcePackage) { - MXFStreamContext *sc = st->priv_data; - mxf_essence_container_uls[sc->index].write_desc(s, st); - } - } -} - -static int mxf_write_essence_container_data(AVFormatContext *s) -{ - AVIOContext *pb = s->pb; - - mxf_write_metadata_key(pb, 0x012300); - klv_encode_ber_length(pb, 72); - - mxf_write_local_tag(pb, 16, 0x3C0A); // Instance UID - mxf_write_uuid(pb, EssenceContainerData, 0); - - mxf_write_local_tag(pb, 32, 0x2701); // Linked Package UID - mxf_write_umid(s, 1); - - mxf_write_local_tag(pb, 4, 0x3F07); // BodySID - avio_wb32(pb, 1); - - mxf_write_local_tag(pb, 4, 0x3F06); // IndexSID - avio_wb32(pb, 2); - - return 0; -} - -static int mxf_write_header_metadata_sets(AVFormatContext *s) -{ - mxf_write_preface(s); - mxf_write_identification(s); - mxf_write_content_storage(s); - mxf_write_package(s, MaterialPackage); - mxf_write_package(s, SourcePackage); - mxf_write_essence_container_data(s); - return 0; -} - -static unsigned klv_fill_size(uint64_t size) -{ - unsigned pad = KAG_SIZE - (size & (KAG_SIZE-1)); - if (pad < 20) // smallest fill item possible - return pad + KAG_SIZE; - else - return pad & (KAG_SIZE-1); -} - -static void mxf_write_index_table_segment(AVFormatContext *s) -{ - MXFContext *mxf = s->priv_data; - AVIOContext *pb = s->pb; - int i, j, temporal_reordering = 0; - int key_index = mxf->last_key_index; - - av_log(s, AV_LOG_DEBUG, "edit units count %d\n", mxf->edit_units_count); - - if (!mxf->edit_units_count && !mxf->edit_unit_byte_count) - return; - - avio_write(pb, index_table_segment_key, 16); - - if (mxf->edit_unit_byte_count) { - klv_encode_ber_length(pb, 80); - } else { - klv_encode_ber_length(pb, 85 + 12+(s->nb_streams+1LL)*6 + - 12+mxf->edit_units_count*(11+mxf->slice_count*4LL)); - } - - // instance id - mxf_write_local_tag(pb, 16, 0x3C0A); - mxf_write_uuid(pb, IndexTableSegment, 0); - - // index edit rate - mxf_write_local_tag(pb, 8, 0x3F0B); - avio_wb32(pb, mxf->time_base.den); - avio_wb32(pb, mxf->time_base.num); - - // index start position - mxf_write_local_tag(pb, 8, 0x3F0C); - avio_wb64(pb, mxf->last_indexed_edit_unit); - - // index duration - mxf_write_local_tag(pb, 8, 0x3F0D); - if (mxf->edit_unit_byte_count) - avio_wb64(pb, 0); // index table covers whole container - else - avio_wb64(pb, mxf->edit_units_count); - - // edit unit byte count - mxf_write_local_tag(pb, 4, 0x3F05); - avio_wb32(pb, mxf->edit_unit_byte_count); - - // index sid - mxf_write_local_tag(pb, 4, 0x3F06); - avio_wb32(pb, 2); - - // body sid - mxf_write_local_tag(pb, 4, 0x3F07); - avio_wb32(pb, 1); - - if (!mxf->edit_unit_byte_count) { - // real slice count - 1 - mxf_write_local_tag(pb, 1, 0x3F08); - avio_w8(pb, mxf->slice_count); - - // delta entry array - mxf_write_local_tag(pb, 8 + (s->nb_streams+1)*6, 0x3F09); - avio_wb32(pb, s->nb_streams+1); // num of entries - avio_wb32(pb, 6); // size of one entry - // write system item delta entry - avio_w8(pb, 0); - avio_w8(pb, 0); // slice entry - avio_wb32(pb, 0); // element delta - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - MXFStreamContext *sc = st->priv_data; - avio_w8(pb, sc->temporal_reordering); - if (sc->temporal_reordering) - temporal_reordering = 1; - if (i == 0) { // video track - avio_w8(pb, 0); // slice number - avio_wb32(pb, KAG_SIZE); // system item size including klv fill - } else { // audio track - unsigned audio_frame_size = sc->aic.samples[0]*sc->aic.sample_size; - audio_frame_size += klv_fill_size(audio_frame_size); - avio_w8(pb, 1); - avio_wb32(pb, (i-1)*audio_frame_size); // element delta - } - } - - mxf_write_local_tag(pb, 8 + mxf->edit_units_count*(11+mxf->slice_count*4), 0x3F0A); - avio_wb32(pb, mxf->edit_units_count); // num of entries - avio_wb32(pb, 11+mxf->slice_count*4); // size of one entry - - for (i = 0; i < mxf->edit_units_count; i++) { - int temporal_offset = 0; - - if (!(mxf->index_entries[i].flags & 0x33)) { // I frame - mxf->last_key_index = key_index; - key_index = i; - } - - if (temporal_reordering) { - int pic_num_in_gop = i - key_index; - if (pic_num_in_gop != mxf->index_entries[i].temporal_ref) { - for (j = key_index; j < mxf->edit_units_count; j++) { - if (pic_num_in_gop == mxf->index_entries[j].temporal_ref) - break; - } - if (j == mxf->edit_units_count) - av_log(s, AV_LOG_WARNING, "missing frames\n"); - temporal_offset = j - key_index - pic_num_in_gop; - } - } - avio_w8(pb, temporal_offset); - - if ((mxf->index_entries[i].flags & 0x30) == 0x30) { // back and forward prediction - avio_w8(pb, mxf->last_key_index - i); - } else { - avio_w8(pb, key_index - i); // key frame offset - if ((mxf->index_entries[i].flags & 0x20) == 0x20) // only forward - mxf->last_key_index = key_index; - } - - if (!(mxf->index_entries[i].flags & 0x33) && // I frame - mxf->index_entries[i].flags & 0x40 && !temporal_offset) - mxf->index_entries[i].flags |= 0x80; // random access - avio_w8(pb, mxf->index_entries[i].flags); - // stream offset - avio_wb64(pb, mxf->index_entries[i].offset); - if (s->nb_streams > 1) - avio_wb32(pb, mxf->index_entries[i].slice_offset); - } - - mxf->last_key_index = key_index - mxf->edit_units_count; - mxf->last_indexed_edit_unit += mxf->edit_units_count; - mxf->edit_units_count = 0; - } -} - -static void mxf_write_klv_fill(AVFormatContext *s) -{ - unsigned pad = klv_fill_size(avio_tell(s->pb)); - if (pad) { - avio_write(s->pb, klv_fill_key, 16); - pad -= 16 + 4; - klv_encode_ber4_length(s->pb, pad); - for (; pad; pad--) - avio_w8(s->pb, 0); - av_assert1(!(avio_tell(s->pb) & (KAG_SIZE-1))); - } -} - -static void mxf_write_partition(AVFormatContext *s, int bodysid, - int indexsid, - const uint8_t *key, int write_metadata) -{ - MXFContext *mxf = s->priv_data; - AVIOContext *pb = s->pb; - int64_t header_byte_count_offset; - unsigned index_byte_count = 0; - uint64_t partition_offset = avio_tell(pb); - - if (!mxf->edit_unit_byte_count && mxf->edit_units_count) - index_byte_count = 85 + 12+(s->nb_streams+1)*6 + - 12+mxf->edit_units_count*(11+mxf->slice_count*4); - else if (mxf->edit_unit_byte_count && indexsid) - index_byte_count = 80; - - if (index_byte_count) { - // add encoded ber length - index_byte_count += 16 + klv_ber_length(index_byte_count); - index_byte_count += klv_fill_size(index_byte_count); - } - - if (!memcmp(key, body_partition_key, 16)) { - mxf->body_partition_offset = - av_realloc(mxf->body_partition_offset, - (mxf->body_partitions_count+1)* - sizeof(*mxf->body_partition_offset)); - mxf->body_partition_offset[mxf->body_partitions_count++] = partition_offset; - } - - // write klv - avio_write(pb, key, 16); - klv_encode_ber_length(pb, 88 + 16LL * DESCRIPTOR_COUNT(mxf->essence_container_count)); - - // write partition value - avio_wb16(pb, 1); // majorVersion - avio_wb16(pb, 2); // minorVersion - avio_wb32(pb, KAG_SIZE); // KAGSize - - avio_wb64(pb, partition_offset); // ThisPartition - - if (!memcmp(key, body_partition_key, 16) && mxf->body_partitions_count > 1) - avio_wb64(pb, mxf->body_partition_offset[mxf->body_partitions_count-2]); // PreviousPartition - else if (!memcmp(key, footer_partition_key, 16) && mxf->body_partitions_count) - avio_wb64(pb, mxf->body_partition_offset[mxf->body_partitions_count-1]); // PreviousPartition - else - avio_wb64(pb, 0); - - avio_wb64(pb, mxf->footer_partition_offset); // footerPartition - - // set offset - header_byte_count_offset = avio_tell(pb); - avio_wb64(pb, 0); // headerByteCount, update later - - // indexTable - avio_wb64(pb, index_byte_count); // indexByteCount - avio_wb32(pb, index_byte_count ? indexsid : 0); // indexSID - - // BodyOffset - if (bodysid && mxf->edit_units_count && mxf->body_partitions_count) { - avio_wb64(pb, mxf->body_offset); - } else - avio_wb64(pb, 0); - - avio_wb32(pb, bodysid); // bodySID - - // operational pattern - avio_write(pb, op1a_ul, 16); - - // essence container - mxf_write_essence_container_refs(s); - - if (write_metadata) { - // mark the start of the headermetadata and calculate metadata size - int64_t pos, start; - unsigned header_byte_count; - - mxf_write_klv_fill(s); - start = avio_tell(s->pb); - mxf_write_primer_pack(s); - mxf_write_header_metadata_sets(s); - pos = avio_tell(s->pb); - header_byte_count = pos - start + klv_fill_size(pos); - - // update header_byte_count - avio_seek(pb, header_byte_count_offset, SEEK_SET); - avio_wb64(pb, header_byte_count); - avio_seek(pb, pos, SEEK_SET); - } - - avio_flush(pb); -} - -static int mxf_parse_dnxhd_frame(AVFormatContext *s, AVStream *st, -AVPacket *pkt) -{ - MXFContext *mxf = s->priv_data; - MXFStreamContext *sc = st->priv_data; - int i, cid; - uint8_t* header_cid; - int frame_size = 0; - - if (mxf->header_written) - return 1; - - if (pkt->size < 43) - return -1; - - header_cid = pkt->data + 0x28; - cid = header_cid[0] << 24 | header_cid[1] << 16 | header_cid[2] << 8 | header_cid[3]; - - if ((frame_size = avpriv_dnxhd_get_frame_size(cid)) < 0) - return -1; - - switch (cid) { - case 1235: - sc->index = 24; - sc->component_depth = 10; - break; - case 1237: - sc->index = 25; - break; - case 1238: - sc->index = 26; - break; - case 1241: - sc->index = 27; - sc->component_depth = 10; - break; - case 1242: - sc->index = 28; - break; - case 1243: - sc->index = 29; - break; - case 1250: - sc->index = 30; - sc->component_depth = 10; - break; - case 1251: - sc->index = 31; - break; - case 1252: - sc->index = 32; - break; - case 1253: - sc->index = 33; - break; - default: - return -1; - } - - sc->codec_ul = &mxf_essence_container_uls[sc->index].codec_ul; - sc->aspect_ratio = (AVRational){ 16, 9 }; - - mxf->edit_unit_byte_count = KAG_SIZE; - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - MXFStreamContext *sc = st->priv_data; - if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - mxf->edit_unit_byte_count += 16 + 4 + sc->aic.samples[0]*sc->aic.sample_size; - mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count); - } else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { - mxf->edit_unit_byte_count += 16 + 4 + frame_size; - mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count); - } - } - - return 1; -} - -static int mxf_parse_dv_frame(AVFormatContext *s, AVStream *st, AVPacket *pkt) -{ - MXFContext *mxf = s->priv_data; - MXFStreamContext *sc = st->priv_data; - uint8_t *vs_pack, *vsc_pack; - int i, ul_index, frame_size, stype, pal; - - if (mxf->header_written) - return 1; - - // Check for minimal frame size - if (pkt->size < 120000) - return -1; - - vs_pack = pkt->data + 80*5 + 48; - vsc_pack = pkt->data + 80*5 + 53; - stype = vs_pack[3] & 0x1f; - pal = (vs_pack[3] >> 5) & 0x1; - - if ((vs_pack[2] & 0x07) == 0x02) - sc->aspect_ratio = (AVRational){ 16, 9 }; - else - sc->aspect_ratio = (AVRational){ 4, 3 }; - - sc->interlaced = (vsc_pack[3] >> 4) & 0x01; - // TODO: fix dv encoder to set proper FF/FS value in VSC pack - // and set field dominance accordingly - // av_log(s, AV_LOG_DEBUG, "DV vsc pack ff/ss = %x\n", vsc_pack[2] >> 6); - - switch (stype) { - case 0x18: // DV100 720p - ul_index = 6 + pal; - frame_size = pal ? 288000 : 240000; - if (sc->interlaced) { - av_log(s, AV_LOG_ERROR, "source marked as interlaced but codec profile is progressive\n"); - sc->interlaced = 0; - } - break; - case 0x14: // DV100 1080i - ul_index = 4 + pal; - frame_size = pal ? 576000 : 480000; - break; - case 0x04: // DV50 - ul_index = 2 + pal; - frame_size = pal ? 288000 : 240000; - break; - default: // DV25 - ul_index = 0 + pal; - frame_size = pal ? 144000 : 120000; - } - - sc->index = ul_index + 16; - sc->codec_ul = &mxf_essence_container_uls[sc->index].codec_ul; - - mxf->edit_unit_byte_count = KAG_SIZE; - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - MXFStreamContext *sc = st->priv_data; - if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - mxf->edit_unit_byte_count += 16 + 4 + sc->aic.samples[0]*sc->aic.sample_size; - mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count); - } else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { - mxf->edit_unit_byte_count += 16 + 4 + frame_size; - mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count); - } - } - - return 1; -} - -static const UID mxf_mpeg2_codec_uls[] = { - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x01,0x10,0x00 }, // MP-ML I-Frame - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x01,0x11,0x00 }, // MP-ML Long GOP - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x02,0x02,0x00 }, // 422P-ML I-Frame - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x02,0x03,0x00 }, // 422P-ML Long GOP - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x03,0x02,0x00 }, // MP-HL I-Frame - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x03,0x03,0x00 }, // MP-HL Long GOP - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x04,0x02,0x00 }, // 422P-HL I-Frame - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x04,0x03,0x00 }, // 422P-HL Long GOP - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x05,0x02,0x00 }, // MP@H-14 I-Frame - { 0x06,0x0E,0x2B,0x34,0x04,0x01,0x01,0x03,0x04,0x01,0x02,0x02,0x01,0x05,0x03,0x00 }, // MP@H-14 Long GOP -}; - -static const UID *mxf_get_mpeg2_codec_ul(AVCodecContext *avctx) -{ - int long_gop = avctx->gop_size > 1 || avctx->has_b_frames; - - if (avctx->profile == 4) { // Main - if (avctx->level == 8) // Main - return &mxf_mpeg2_codec_uls[0+long_gop]; - else if (avctx->level == 4) // High - return &mxf_mpeg2_codec_uls[4+long_gop]; - else if (avctx->level == 6) // High 14 - return &mxf_mpeg2_codec_uls[8+long_gop]; - } else if (avctx->profile == 0) { // 422 - if (avctx->level == 5) // Main - return &mxf_mpeg2_codec_uls[2+long_gop]; - else if (avctx->level == 2) // High - return &mxf_mpeg2_codec_uls[6+long_gop]; - } - return NULL; -} - -static int mxf_parse_mpeg2_frame(AVFormatContext *s, AVStream *st, - AVPacket *pkt, MXFIndexEntry *e) -{ - MXFStreamContext *sc = st->priv_data; - uint32_t c = -1; - int i; - - for(i = 0; i < pkt->size - 4; i++) { - c = (c<<8) + pkt->data[i]; - if (c == 0x1b5) { - if ((pkt->data[i+1] & 0xf0) == 0x10) { // seq ext - st->codec->profile = pkt->data[i+1] & 0x07; - st->codec->level = pkt->data[i+2] >> 4; - } else if (i + 5 < pkt->size && (pkt->data[i+1] & 0xf0) == 0x80) { // pict coding ext - sc->interlaced = !(pkt->data[i+5] & 0x80); // progressive frame - if (sc->interlaced) - sc->field_dominance = 1 + !(pkt->data[i+4] & 0x80); // top field first - break; - } - } else if (c == 0x1b8) { // gop - if (pkt->data[i+4]>>6 & 0x01) { // closed - sc->closed_gop = 1; - if (e->flags & 0x40) // sequence header present - e->flags |= 0x80; // random access - } - } else if (c == 0x1b3) { // seq - e->flags |= 0x40; - switch ((pkt->data[i+4]>>4) & 0xf) { - case 2: sc->aspect_ratio = (AVRational){ 4, 3}; break; - case 3: sc->aspect_ratio = (AVRational){ 16, 9}; break; - case 4: sc->aspect_ratio = (AVRational){221,100}; break; - default: - av_reduce(&sc->aspect_ratio.num, &sc->aspect_ratio.den, - st->codec->width, st->codec->height, 1024*1024); - } - } else if (c == 0x100) { // pic - int pict_type = (pkt->data[i+2]>>3) & 0x07; - e->temporal_ref = (pkt->data[i+1]<<2) | (pkt->data[i+2]>>6); - if (pict_type == 2) { // P frame - e->flags |= 0x22; - sc->closed_gop = 0; // reset closed gop, don't matter anymore - } else if (pict_type == 3) { // B frame - if (sc->closed_gop) - e->flags |= 0x13; // only backward prediction - else - e->flags |= 0x33; - sc->temporal_reordering = -1; - } else if (!pict_type) { - av_log(s, AV_LOG_ERROR, "error parsing mpeg2 frame\n"); - return 0; - } - } - } - if (s->oformat != &ff_mxf_d10_muxer) - sc->codec_ul = mxf_get_mpeg2_codec_ul(st->codec); - return !!sc->codec_ul; -} - -static uint64_t mxf_parse_timestamp(time_t timestamp) -{ - struct tm *time = gmtime(×tamp); - if (!time) - return 0; - return (uint64_t)(time->tm_year+1900) << 48 | - (uint64_t)(time->tm_mon+1) << 40 | - (uint64_t) time->tm_mday << 32 | - time->tm_hour << 24 | - time->tm_min << 16 | - time->tm_sec << 8; -} - -static void mxf_gen_umid(AVFormatContext *s) -{ - MXFContext *mxf = s->priv_data; - uint32_t seed = av_get_random_seed(); - uint64_t umid = seed + 0x5294713400000000LL; - - AV_WB64(mxf->umid , umid); - AV_WB64(mxf->umid+8, umid>>8); - - mxf->instance_number = seed; -} - -static int mxf_write_header(AVFormatContext *s) -{ - MXFContext *mxf = s->priv_data; - int i, ret; - uint8_t present[FF_ARRAY_ELEMS(mxf_essence_container_uls)] = {0}; - const MXFSamplesPerFrame *spf = NULL; - AVDictionaryEntry *t; - int64_t timestamp = 0; - AVDictionaryEntry *tcr = av_dict_get(s->metadata, "timecode", NULL, 0); - - if (!s->nb_streams) - return -1; - - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - MXFStreamContext *sc = av_mallocz(sizeof(*sc)); - if (!sc) - return AVERROR(ENOMEM); - st->priv_data = sc; - - if ((i == 0) ^ (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)) { - av_log(s, AV_LOG_ERROR, "there must be exactly one video stream and it must be the first one\n"); - return -1; - } - - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { - AVRational rate, tbc = st->codec->time_base; - // Default component depth to 8 - sc->component_depth = 8; - mxf->timecode_base = (tbc.den + tbc.num/2) / tbc.num; - spf = ff_mxf_get_samples_per_frame(s, tbc); - if (!spf) { - av_log(s, AV_LOG_ERROR, "Unsupported video frame rate %d/%d\n", - tbc.den, tbc.num); - return AVERROR(EINVAL); - } - mxf->time_base = spf->time_base; - rate = av_inv_q(mxf->time_base); - avpriv_set_pts_info(st, 64, mxf->time_base.num, mxf->time_base.den); - if (!tcr) - tcr = av_dict_get(st->metadata, "timecode", NULL, 0); - if (tcr) - ret = av_timecode_init_from_string(&mxf->tc, rate, tcr->value, s); - else - ret = av_timecode_init(&mxf->tc, rate, 0, 0, s); - if (ret < 0) - return ret; - if (s->oformat == &ff_mxf_d10_muxer) { - if (st->codec->bit_rate == 50000000) { - if (mxf->time_base.den == 25) sc->index = 3; - else sc->index = 5; - } else if (st->codec->bit_rate == 40000000) { - if (mxf->time_base.den == 25) sc->index = 7; - else sc->index = 9; - } else if (st->codec->bit_rate == 30000000) { - if (mxf->time_base.den == 25) sc->index = 11; - else sc->index = 13; - } else { - av_log(s, AV_LOG_ERROR, "error MXF D-10 only support 30/40/50 mbit/s\n"); - return -1; - } - - mxf->edit_unit_byte_count = KAG_SIZE; // system element - mxf->edit_unit_byte_count += 16 + 4 + (uint64_t)st->codec->bit_rate * - mxf->time_base.num / (8*mxf->time_base.den); - mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count); - mxf->edit_unit_byte_count += 16 + 4 + 4 + spf->samples_per_frame[0]*8*4; - mxf->edit_unit_byte_count += klv_fill_size(mxf->edit_unit_byte_count); - } - } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - if (st->codec->sample_rate != 48000) { - av_log(s, AV_LOG_ERROR, "only 48khz is implemented\n"); - return -1; - } - avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); - if (s->oformat == &ff_mxf_d10_muxer) { - if (st->index != 1) { - av_log(s, AV_LOG_ERROR, "MXF D-10 only support one audio track\n"); - return -1; - } - if (st->codec->codec_id != AV_CODEC_ID_PCM_S16LE && - st->codec->codec_id != AV_CODEC_ID_PCM_S24LE) { - av_log(s, AV_LOG_ERROR, "MXF D-10 only support 16 or 24 bits le audio\n"); - } - sc->index = ((MXFStreamContext*)s->streams[0]->priv_data)->index + 1; - } else - mxf->slice_count = 1; - } - - if (!sc->index) { - sc->index = mxf_get_essence_container_ul_index(st->codec->codec_id); - if (sc->index == -1) { - av_log(s, AV_LOG_ERROR, "track %d: could not find essence container ul, " - "codec not currently supported in container\n", i); - return -1; - } - } - - sc->codec_ul = &mxf_essence_container_uls[sc->index].codec_ul; - - memcpy(sc->track_essence_element_key, mxf_essence_container_uls[sc->index].element_ul, 15); - sc->track_essence_element_key[15] = present[sc->index]; - PRINT_KEY(s, "track essence element key", sc->track_essence_element_key); - - if (!present[sc->index]) - mxf->essence_container_count++; - present[sc->index]++; - } - - if (s->oformat == &ff_mxf_d10_muxer) { - mxf->essence_container_count = 1; - } - - if (!(s->streams[0]->codec->flags & CODEC_FLAG_BITEXACT)) - mxf_gen_umid(s); - - for (i = 0; i < s->nb_streams; i++) { - MXFStreamContext *sc = s->streams[i]->priv_data; - // update element count - sc->track_essence_element_key[13] = present[sc->index]; - if (!memcmp(sc->track_essence_element_key, mxf_essence_container_uls[15].element_ul, 13)) // DV - sc->order = (0x15 << 24) | AV_RB32(sc->track_essence_element_key+13); - else - sc->order = AV_RB32(sc->track_essence_element_key+12); - } - - if (t = av_dict_get(s->metadata, "creation_time", NULL, 0)) - timestamp = ff_iso8601_to_unix_time(t->value); - if (timestamp) - mxf->timestamp = mxf_parse_timestamp(timestamp); - mxf->duration = -1; - - mxf->timecode_track = av_mallocz(sizeof(*mxf->timecode_track)); - if (!mxf->timecode_track) - return AVERROR(ENOMEM); - mxf->timecode_track->priv_data = av_mallocz(sizeof(MXFStreamContext)); - if (!mxf->timecode_track->priv_data) - return AVERROR(ENOMEM); - mxf->timecode_track->index = -1; - - if (!spf) - spf = ff_mxf_get_samples_per_frame(s, (AVRational){ 1, 25 }); - - if (ff_audio_interleave_init(s, spf->samples_per_frame, mxf->time_base) < 0) - return -1; - - return 0; -} - -static const uint8_t system_metadata_pack_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x05,0x01,0x01,0x0D,0x01,0x03,0x01,0x04,0x01,0x01,0x00 }; -static const uint8_t system_metadata_package_set_key[] = { 0x06,0x0E,0x2B,0x34,0x02,0x43,0x01,0x01,0x0D,0x01,0x03,0x01,0x04,0x01,0x02,0x01 }; - -static void mxf_write_system_item(AVFormatContext *s) -{ - MXFContext *mxf = s->priv_data; - AVIOContext *pb = s->pb; - unsigned frame; - uint32_t time_code; - - frame = mxf->last_indexed_edit_unit + mxf->edit_units_count; - - // write system metadata pack - avio_write(pb, system_metadata_pack_key, 16); - klv_encode_ber4_length(pb, 57); - avio_w8(pb, 0x5c); // UL, user date/time stamp, picture and sound item present - avio_w8(pb, 0x04); // content package rate - avio_w8(pb, 0x00); // content package type - avio_wb16(pb, 0x00); // channel handle - avio_wb16(pb, (mxf->tc.start + frame) & 0xFFFF); // continuity count, supposed to overflow - if (mxf->essence_container_count > 1) - avio_write(pb, multiple_desc_ul, 16); - else { - MXFStreamContext *sc = s->streams[0]->priv_data; - avio_write(pb, mxf_essence_container_uls[sc->index].container_ul, 16); - } - avio_w8(pb, 0); - avio_wb64(pb, 0); - avio_wb64(pb, 0); // creation date/time stamp - - avio_w8(pb, 0x81); // SMPTE 12M time code - time_code = av_timecode_get_smpte_from_framenum(&mxf->tc, frame); - avio_wb32(pb, time_code); - avio_wb32(pb, 0); // binary group data - avio_wb64(pb, 0); - - // write system metadata package set - avio_write(pb, system_metadata_package_set_key, 16); - klv_encode_ber4_length(pb, 35); - avio_w8(pb, 0x83); // UMID - avio_wb16(pb, 0x20); - mxf_write_umid(s, 1); -} - -static void mxf_write_d10_video_packet(AVFormatContext *s, AVStream *st, AVPacket *pkt) -{ - MXFContext *mxf = s->priv_data; - AVIOContext *pb = s->pb; - int packet_size = (uint64_t)st->codec->bit_rate*mxf->time_base.num / - (8*mxf->time_base.den); // frame size - int pad; - - packet_size += 16 + 4; - packet_size += klv_fill_size(packet_size); - - klv_encode_ber4_length(pb, pkt->size); - avio_write(pb, pkt->data, pkt->size); - - // ensure CBR muxing by padding to correct video frame size - pad = packet_size - pkt->size - 16 - 4; - if (pad > 20) { - avio_write(s->pb, klv_fill_key, 16); - pad -= 16 + 4; - klv_encode_ber4_length(s->pb, pad); - for (; pad; pad--) - avio_w8(s->pb, 0); - av_assert1(!(avio_tell(s->pb) & (KAG_SIZE-1))); - } else { - av_log(s, AV_LOG_WARNING, "cannot fill d-10 video packet\n"); - for (; pad > 0; pad--) - avio_w8(s->pb, 0); - } -} - -static void mxf_write_d10_audio_packet(AVFormatContext *s, AVStream *st, AVPacket *pkt) -{ - MXFContext *mxf = s->priv_data; - AVIOContext *pb = s->pb; - int frame_size = pkt->size / st->codec->block_align; - uint8_t *samples = pkt->data; - uint8_t *end = pkt->data + pkt->size; - int i; - - klv_encode_ber4_length(pb, 4 + frame_size*4*8); - - avio_w8(pb, (frame_size == 1920 ? 0 : (mxf->edit_units_count-1) % 5 + 1)); - avio_wl16(pb, frame_size); - avio_w8(pb, (1<codec->channels)-1); - - while (samples < end) { - for (i = 0; i < st->codec->channels; i++) { - uint32_t sample; - if (st->codec->codec_id == AV_CODEC_ID_PCM_S24LE) { - sample = AV_RL24(samples)<< 4; - samples += 3; - } else { - sample = AV_RL16(samples)<<12; - samples += 2; - } - avio_wl32(pb, sample | i); - } - for (; i < 8; i++) - avio_wl32(pb, i); - } -} - -static int mxf_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - MXFContext *mxf = s->priv_data; - AVIOContext *pb = s->pb; - AVStream *st = s->streams[pkt->stream_index]; - MXFStreamContext *sc = st->priv_data; - MXFIndexEntry ie = {0}; - - if (!mxf->edit_unit_byte_count && !(mxf->edit_units_count % EDIT_UNITS_PER_BODY)) { - mxf->index_entries = av_realloc(mxf->index_entries, - (mxf->edit_units_count + EDIT_UNITS_PER_BODY)*sizeof(*mxf->index_entries)); - if (!mxf->index_entries) { - av_log(s, AV_LOG_ERROR, "could not allocate index entries\n"); - return -1; - } - } - - if (st->codec->codec_id == AV_CODEC_ID_MPEG2VIDEO) { - if (!mxf_parse_mpeg2_frame(s, st, pkt, &ie)) { - av_log(s, AV_LOG_ERROR, "could not get mpeg2 profile and level\n"); - return -1; - } - } else if (st->codec->codec_id == AV_CODEC_ID_DNXHD) { - if (!mxf_parse_dnxhd_frame(s, st, pkt)) { - av_log(s, AV_LOG_ERROR, "could not get dnxhd profile\n"); - return -1; - } - } else if (st->codec->codec_id == AV_CODEC_ID_DVVIDEO) { - if (!mxf_parse_dv_frame(s, st, pkt)) { - av_log(s, AV_LOG_ERROR, "could not get dv profile\n"); - return -1; - } - } - - if (!mxf->header_written) { - if (mxf->edit_unit_byte_count) { - mxf_write_partition(s, 1, 2, header_open_partition_key, 1); - mxf_write_klv_fill(s); - mxf_write_index_table_segment(s); - } else { - mxf_write_partition(s, 0, 0, header_open_partition_key, 1); - } - mxf->header_written = 1; - } - - if (st->index == 0) { - if (!mxf->edit_unit_byte_count && - (!mxf->edit_units_count || mxf->edit_units_count > EDIT_UNITS_PER_BODY) && - !(ie.flags & 0x33)) { // I frame, Gop start - mxf_write_klv_fill(s); - mxf_write_partition(s, 1, 2, body_partition_key, 0); - - mxf_write_klv_fill(s); - mxf_write_index_table_segment(s); - } - - mxf_write_klv_fill(s); - mxf_write_system_item(s); - - if (!mxf->edit_unit_byte_count) { - mxf->index_entries[mxf->edit_units_count].offset = mxf->body_offset; - mxf->index_entries[mxf->edit_units_count].flags = ie.flags; - mxf->index_entries[mxf->edit_units_count].temporal_ref = ie.temporal_ref; - mxf->body_offset += KAG_SIZE; // size of system element - } - mxf->edit_units_count++; - } else if (!mxf->edit_unit_byte_count && st->index == 1) { - mxf->index_entries[mxf->edit_units_count-1].slice_offset = - mxf->body_offset - mxf->index_entries[mxf->edit_units_count-1].offset; - } - - mxf_write_klv_fill(s); - avio_write(pb, sc->track_essence_element_key, 16); // write key - if (s->oformat == &ff_mxf_d10_muxer) { - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) - mxf_write_d10_video_packet(s, st, pkt); - else - mxf_write_d10_audio_packet(s, st, pkt); - } else { - klv_encode_ber4_length(pb, pkt->size); // write length - avio_write(pb, pkt->data, pkt->size); - mxf->body_offset += 16+4+pkt->size + klv_fill_size(16+4+pkt->size); - } - - avio_flush(pb); - - return 0; -} - -static void mxf_write_random_index_pack(AVFormatContext *s) -{ - MXFContext *mxf = s->priv_data; - AVIOContext *pb = s->pb; - uint64_t pos = avio_tell(pb); - int i; - - avio_write(pb, random_index_pack_key, 16); - klv_encode_ber_length(pb, 28 + 12LL*mxf->body_partitions_count); - - if (mxf->edit_unit_byte_count) - avio_wb32(pb, 1); // BodySID of header partition - else - avio_wb32(pb, 0); - avio_wb64(pb, 0); // offset of header partition - - for (i = 0; i < mxf->body_partitions_count; i++) { - avio_wb32(pb, 1); // BodySID - avio_wb64(pb, mxf->body_partition_offset[i]); - } - - avio_wb32(pb, 0); // BodySID of footer partition - avio_wb64(pb, mxf->footer_partition_offset); - - avio_wb32(pb, avio_tell(pb) - pos + 4); -} - -static int mxf_write_footer(AVFormatContext *s) -{ - MXFContext *mxf = s->priv_data; - AVIOContext *pb = s->pb; - - mxf->duration = mxf->last_indexed_edit_unit + mxf->edit_units_count; - - mxf_write_klv_fill(s); - mxf->footer_partition_offset = avio_tell(pb); - if (mxf->edit_unit_byte_count) { // no need to repeat index - mxf_write_partition(s, 0, 0, footer_partition_key, 0); - } else { - mxf_write_partition(s, 0, 2, footer_partition_key, 0); - - mxf_write_klv_fill(s); - mxf_write_index_table_segment(s); - } - - mxf_write_klv_fill(s); - mxf_write_random_index_pack(s); - - if (s->pb->seekable) { - avio_seek(pb, 0, SEEK_SET); - if (mxf->edit_unit_byte_count) { - mxf_write_partition(s, 1, 2, header_closed_partition_key, 1); - mxf_write_klv_fill(s); - mxf_write_index_table_segment(s); - } else { - mxf_write_partition(s, 0, 0, header_closed_partition_key, 1); - } - } - - ff_audio_interleave_close(s); - - av_freep(&mxf->index_entries); - av_freep(&mxf->body_partition_offset); - av_freep(&mxf->timecode_track->priv_data); - av_freep(&mxf->timecode_track); - - mxf_free(s); - - return 0; -} - -static int mxf_interleave_get_packet(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush) -{ - int i, stream_count = 0; - - for (i = 0; i < s->nb_streams; i++) - stream_count += !!s->streams[i]->last_in_packet_buffer; - - if (stream_count && (s->nb_streams == stream_count || flush)) { - AVPacketList *pktl = s->packet_buffer; - if (s->nb_streams != stream_count) { - AVPacketList *last = NULL; - // find last packet in edit unit - while (pktl) { - if (!stream_count || pktl->pkt.stream_index == 0) - break; - last = pktl; - pktl = pktl->next; - stream_count--; - } - // purge packet queue - while (pktl) { - AVPacketList *next = pktl->next; - - if(s->streams[pktl->pkt.stream_index]->last_in_packet_buffer == pktl) - s->streams[pktl->pkt.stream_index]->last_in_packet_buffer= NULL; - av_free_packet(&pktl->pkt); - av_freep(&pktl); - pktl = next; - } - if (last) - last->next = NULL; - else { - s->packet_buffer = NULL; - s->packet_buffer_end= NULL; - goto out; - } - pktl = s->packet_buffer; - } - - *out = pktl->pkt; - av_dlog(s, "out st:%d dts:%"PRId64"\n", (*out).stream_index, (*out).dts); - s->packet_buffer = pktl->next; - if(s->streams[pktl->pkt.stream_index]->last_in_packet_buffer == pktl) - s->streams[pktl->pkt.stream_index]->last_in_packet_buffer= NULL; - if(!s->packet_buffer) - s->packet_buffer_end= NULL; - av_freep(&pktl); - return 1; - } else { - out: - av_init_packet(out); - return 0; - } -} - -static int mxf_compare_timestamps(AVFormatContext *s, AVPacket *next, AVPacket *pkt) -{ - MXFStreamContext *sc = s->streams[pkt ->stream_index]->priv_data; - MXFStreamContext *sc2 = s->streams[next->stream_index]->priv_data; - - return next->dts > pkt->dts || - (next->dts == pkt->dts && sc->order < sc2->order); -} - -static int mxf_interleave(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush) -{ - return ff_audio_rechunk_interleave(s, out, pkt, flush, - mxf_interleave_get_packet, mxf_compare_timestamps); -} - -AVOutputFormat ff_mxf_muxer = { - .name = "mxf", - .long_name = NULL_IF_CONFIG_SMALL("MXF (Material eXchange Format)"), - .mime_type = "application/mxf", - .extensions = "mxf", - .priv_data_size = sizeof(MXFContext), - .audio_codec = AV_CODEC_ID_PCM_S16LE, - .video_codec = AV_CODEC_ID_MPEG2VIDEO, - .write_header = mxf_write_header, - .write_packet = mxf_write_packet, - .write_trailer = mxf_write_footer, - .flags = AVFMT_NOTIMESTAMPS, - .interleave_packet = mxf_interleave, -}; - -AVOutputFormat ff_mxf_d10_muxer = { - .name = "mxf_d10", - .long_name = NULL_IF_CONFIG_SMALL("MXF (Material eXchange Format) D-10 Mapping"), - .mime_type = "application/mxf", - .priv_data_size = sizeof(MXFContext), - .audio_codec = AV_CODEC_ID_PCM_S16LE, - .video_codec = AV_CODEC_ID_MPEG2VIDEO, - .write_header = mxf_write_header, - .write_packet = mxf_write_packet, - .write_trailer = mxf_write_footer, - .flags = AVFMT_NOTIMESTAMPS, - .interleave_packet = mxf_interleave, -}; diff --git a/ffmpeg1/libavformat/mxg.c b/ffmpeg1/libavformat/mxg.c deleted file mode 100644 index 604be78..0000000 --- a/ffmpeg1/libavformat/mxg.c +++ /dev/null @@ -1,260 +0,0 @@ -/* - * MxPEG clip file demuxer - * Copyright (c) 2010 Anatoly Nenashev - * - * 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 "libavutil/channel_layout.h" -#include "libavutil/intreadwrite.h" -#include "libavcodec/mjpeg.h" -#include "avformat.h" -#include "internal.h" -#include "avio.h" - -#define DEFAULT_PACKET_SIZE 1024 -#define OVERREAD_SIZE 3 - -typedef struct MXGContext { - uint8_t *buffer; - uint8_t *buffer_ptr; - uint8_t *soi_ptr; - unsigned int buffer_size; - int64_t dts; - unsigned int cache_size; -} MXGContext; - -static int mxg_read_header(AVFormatContext *s) -{ - AVStream *video_st, *audio_st; - MXGContext *mxg = s->priv_data; - - /* video parameters will be extracted from the compressed bitstream */ - video_st = avformat_new_stream(s, NULL); - if (!video_st) - return AVERROR(ENOMEM); - video_st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - video_st->codec->codec_id = AV_CODEC_ID_MXPEG; - avpriv_set_pts_info(video_st, 64, 1, 1000000); - - audio_st = avformat_new_stream(s, NULL); - if (!audio_st) - return AVERROR(ENOMEM); - audio_st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - audio_st->codec->codec_id = AV_CODEC_ID_PCM_ALAW; - audio_st->codec->channels = 1; - audio_st->codec->channel_layout = AV_CH_LAYOUT_MONO; - audio_st->codec->sample_rate = 8000; - audio_st->codec->bits_per_coded_sample = 8; - audio_st->codec->block_align = 1; - avpriv_set_pts_info(audio_st, 64, 1, 1000000); - - mxg->soi_ptr = mxg->buffer_ptr = mxg->buffer = 0; - mxg->buffer_size = 0; - mxg->dts = AV_NOPTS_VALUE; - mxg->cache_size = 0; - - return 0; -} - -static uint8_t* mxg_find_startmarker(uint8_t *p, uint8_t *end) -{ - for (; p < end - 3; p += 4) { - uint32_t x = *(uint32_t*)p; - - if (x & (~(x+0x01010101)) & 0x80808080) { - if (p[0] == 0xff) { - return p; - } else if (p[1] == 0xff) { - return p+1; - } else if (p[2] == 0xff) { - return p+2; - } else if (p[3] == 0xff) { - return p+3; - } - } - } - - for (; p < end; ++p) { - if (*p == 0xff) return p; - } - - return end; -} - -static int mxg_update_cache(AVFormatContext *s, unsigned int cache_size) -{ - MXGContext *mxg = s->priv_data; - unsigned int current_pos = mxg->buffer_ptr - mxg->buffer; - unsigned int soi_pos; - uint8_t *buffer; - int ret; - - /* reallocate internal buffer */ - if (current_pos > current_pos + cache_size) - return AVERROR(ENOMEM); - soi_pos = mxg->soi_ptr - mxg->buffer; - buffer = av_fast_realloc(mxg->buffer, &mxg->buffer_size, - current_pos + cache_size + - FF_INPUT_BUFFER_PADDING_SIZE); - if (!buffer) - return AVERROR(ENOMEM); - mxg->buffer = buffer; - mxg->buffer_ptr = mxg->buffer + current_pos; - if (mxg->soi_ptr) mxg->soi_ptr = mxg->buffer + soi_pos; - - /* get data */ - ret = avio_read(s->pb, mxg->buffer_ptr + mxg->cache_size, - cache_size - mxg->cache_size); - if (ret < 0) - return ret; - - mxg->cache_size += ret; - - return ret; -} - -static int mxg_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - int ret; - unsigned int size; - uint8_t *startmarker_ptr, *end, *search_end, marker; - MXGContext *mxg = s->priv_data; - - while (!url_feof(s->pb) && !s->pb->error){ - if (mxg->cache_size <= OVERREAD_SIZE) { - /* update internal buffer */ - ret = mxg_update_cache(s, DEFAULT_PACKET_SIZE + OVERREAD_SIZE); - if (ret < 0) - return ret; - } - end = mxg->buffer_ptr + mxg->cache_size; - - /* find start marker - 0xff */ - if (mxg->cache_size > OVERREAD_SIZE) { - search_end = end - OVERREAD_SIZE; - startmarker_ptr = mxg_find_startmarker(mxg->buffer_ptr, search_end); - } else { - search_end = end; - startmarker_ptr = mxg_find_startmarker(mxg->buffer_ptr, search_end); - if (startmarker_ptr >= search_end - 1 || - *(startmarker_ptr + 1) != EOI) break; - } - - if (startmarker_ptr != search_end) { /* start marker found */ - marker = *(startmarker_ptr + 1); - mxg->buffer_ptr = startmarker_ptr + 2; - mxg->cache_size = end - mxg->buffer_ptr; - - if (marker == SOI) { - mxg->soi_ptr = startmarker_ptr; - } else if (marker == EOI) { - if (!mxg->soi_ptr) { - av_log(s, AV_LOG_WARNING, "Found EOI before SOI, skipping\n"); - continue; - } - - pkt->pts = pkt->dts = mxg->dts; - pkt->stream_index = 0; -#if FF_API_DESTRUCT_PACKET - pkt->destruct = NULL; -#endif - pkt->buf = NULL; - pkt->size = mxg->buffer_ptr - mxg->soi_ptr; - pkt->data = mxg->soi_ptr; - - if (mxg->soi_ptr - mxg->buffer > mxg->cache_size) { - if (mxg->cache_size > 0) { - memcpy(mxg->buffer, mxg->buffer_ptr, mxg->cache_size); - } - - mxg->buffer_ptr = mxg->buffer; - } - mxg->soi_ptr = 0; - - return pkt->size; - } else if ( (SOF0 <= marker && marker <= SOF15) || - (SOS <= marker && marker <= COM) ) { - /* all other markers that start marker segment also contain - length value (see specification for JPEG Annex B.1) */ - size = AV_RB16(mxg->buffer_ptr); - if (size < 2) - return AVERROR(EINVAL); - - if (mxg->cache_size < size) { - ret = mxg_update_cache(s, size); - if (ret < 0) - return ret; - startmarker_ptr = mxg->buffer_ptr - 2; - mxg->cache_size = 0; - } else { - mxg->cache_size -= size; - } - - mxg->buffer_ptr += size; - - if (marker == APP13 && size >= 16) { /* audio data */ - /* time (GMT) of first sample in usec since 1970, little-endian */ - pkt->pts = pkt->dts = AV_RL64(startmarker_ptr + 8); - pkt->stream_index = 1; -#if FF_API_DESTRUCT_PACKET - pkt->destruct = NULL; -#endif - pkt->buf = NULL; - pkt->size = size - 14; - pkt->data = startmarker_ptr + 16; - - if (startmarker_ptr - mxg->buffer > mxg->cache_size) { - if (mxg->cache_size > 0) { - memcpy(mxg->buffer, mxg->buffer_ptr, mxg->cache_size); - } - mxg->buffer_ptr = mxg->buffer; - } - - return pkt->size; - } else if (marker == COM && size >= 18 && - !strncmp(startmarker_ptr + 4, "MXF", 3)) { - /* time (GMT) of video frame in usec since 1970, little-endian */ - mxg->dts = AV_RL64(startmarker_ptr + 12); - } - } - } else { - /* start marker not found */ - mxg->buffer_ptr = search_end; - mxg->cache_size = OVERREAD_SIZE; - } - } - - return AVERROR_EOF; -} - -static int mxg_close(struct AVFormatContext *s) -{ - MXGContext *mxg = s->priv_data; - av_freep(&mxg->buffer); - return 0; -} - -AVInputFormat ff_mxg_demuxer = { - .name = "mxg", - .long_name = NULL_IF_CONFIG_SMALL("MxPEG clip"), - .priv_data_size = sizeof(MXGContext), - .read_header = mxg_read_header, - .read_packet = mxg_read_packet, - .read_close = mxg_close, - .extensions = "mxg", -}; diff --git a/ffmpeg1/libavformat/ncdec.c b/ffmpeg1/libavformat/ncdec.c deleted file mode 100644 index 8cb7ed4..0000000 --- a/ffmpeg1/libavformat/ncdec.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * NC camera feed demuxer - * Copyright (c) 2009 Nicolas Martin (martinic at iro dot umontreal dot ca) - * Edouard Auvinet - * - * 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 "libavutil/intreadwrite.h" -#include "avformat.h" -#include "internal.h" - -#define NC_VIDEO_FLAG 0x1A5 - -static int nc_probe(AVProbeData *probe_packet) -{ - int size; - - if (AV_RB32(probe_packet->buf) != NC_VIDEO_FLAG) - return 0; - - size = AV_RL16(probe_packet->buf + 5); - - if (size + 20 > probe_packet->buf_size) - return AVPROBE_SCORE_MAX/4; - - if (AV_RB32(probe_packet->buf+16+size) == NC_VIDEO_FLAG) - return AVPROBE_SCORE_MAX; - - return 0; -} - -static int nc_read_header(AVFormatContext *s) -{ - AVStream *st = avformat_new_stream(s, NULL); - - if (!st) - return AVERROR(ENOMEM); - - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = AV_CODEC_ID_MPEG4; - st->need_parsing = AVSTREAM_PARSE_FULL; - - avpriv_set_pts_info(st, 64, 1, 100); - - return 0; -} - -static int nc_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - int size; - int ret; - - uint32_t state=-1; - while (state != NC_VIDEO_FLAG) { - if (url_feof(s->pb)) - return AVERROR(EIO); - state = (state<<8) + avio_r8(s->pb); - } - - avio_r8(s->pb); - size = avio_rl16(s->pb); - avio_skip(s->pb, 9); - - if (size == 0) { - av_log(s, AV_LOG_DEBUG, "Next packet size is zero\n"); - return AVERROR(EAGAIN); - } - - ret = av_get_packet(s->pb, pkt, size); - if (ret != size) { - if (ret > 0) av_free_packet(pkt); - return AVERROR(EIO); - } - - pkt->stream_index = 0; - return size; -} - -AVInputFormat ff_nc_demuxer = { - .name = "nc", - .long_name = NULL_IF_CONFIG_SMALL("NC camera feed"), - .read_probe = nc_probe, - .read_header = nc_read_header, - .read_packet = nc_read_packet, - .extensions = "v", -}; diff --git a/ffmpeg1/libavformat/network.c b/ffmpeg1/libavformat/network.c deleted file mode 100644 index ceed719..0000000 --- a/ffmpeg1/libavformat/network.c +++ /dev/null @@ -1,214 +0,0 @@ -/* - * Copyright (c) 2007 The Libav Project - * - * 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 - */ - -#include "libavutil/avutil.h" -#include "network.h" -#include "libavcodec/internal.h" -#include "libavutil/mem.h" -#include "url.h" -#include "libavutil/time.h" - -#if HAVE_THREADS -#if HAVE_PTHREADS -#include -#elif HAVE_OS2THREADS -#include "libavcodec/os2threads.h" -#else -#include "libavcodec/w32pthreads.h" -#endif -#endif - -#if CONFIG_OPENSSL -#include -static int openssl_init; -#if HAVE_THREADS -#include -#include "libavutil/avutil.h" -pthread_mutex_t *openssl_mutexes; -static void openssl_lock(int mode, int type, const char *file, int line) -{ - if (mode & CRYPTO_LOCK) - pthread_mutex_lock(&openssl_mutexes[type]); - else - pthread_mutex_unlock(&openssl_mutexes[type]); -} -#if !defined(WIN32) && OPENSSL_VERSION_NUMBER < 0x10000000 -static unsigned long openssl_thread_id(void) -{ - return (intptr_t) pthread_self(); -} -#endif -#endif -#endif -#if CONFIG_GNUTLS -#include -#if HAVE_THREADS && GNUTLS_VERSION_NUMBER <= 0x020b00 -#include -#include -GCRY_THREAD_OPTION_PTHREAD_IMPL; -#endif -#endif - -void ff_tls_init(void) -{ - avpriv_lock_avformat(); -#if CONFIG_OPENSSL - if (!openssl_init) { - SSL_library_init(); - SSL_load_error_strings(); -#if HAVE_THREADS - if (!CRYPTO_get_locking_callback()) { - int i; - openssl_mutexes = av_malloc(sizeof(pthread_mutex_t) * CRYPTO_num_locks()); - for (i = 0; i < CRYPTO_num_locks(); i++) - pthread_mutex_init(&openssl_mutexes[i], NULL); - CRYPTO_set_locking_callback(openssl_lock); -#if !defined(WIN32) && OPENSSL_VERSION_NUMBER < 0x10000000 - CRYPTO_set_id_callback(openssl_thread_id); -#endif - } -#endif - } - openssl_init++; -#endif -#if CONFIG_GNUTLS -#if HAVE_THREADS && GNUTLS_VERSION_NUMBER < 0x020b00 - if (gcry_control(GCRYCTL_ANY_INITIALIZATION_P) == 0) - gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread); -#endif - gnutls_global_init(); -#endif - avpriv_unlock_avformat(); -} - -void ff_tls_deinit(void) -{ - avpriv_lock_avformat(); -#if CONFIG_OPENSSL - openssl_init--; - if (!openssl_init) { -#if HAVE_THREADS - if (CRYPTO_get_locking_callback() == openssl_lock) { - int i; - CRYPTO_set_locking_callback(NULL); - for (i = 0; i < CRYPTO_num_locks(); i++) - pthread_mutex_destroy(&openssl_mutexes[i]); - av_free(openssl_mutexes); - } -#endif - } -#endif -#if CONFIG_GNUTLS - gnutls_global_deinit(); -#endif - avpriv_unlock_avformat(); -} - -int ff_network_inited_globally; - -int ff_network_init(void) -{ -#if HAVE_WINSOCK2_H - WSADATA wsaData; -#endif - - if (!ff_network_inited_globally) - av_log(NULL, AV_LOG_WARNING, "Using network protocols without global " - "network initialization. Please use " - "avformat_network_init(), this will " - "become mandatory later.\n"); -#if HAVE_WINSOCK2_H - if (WSAStartup(MAKEWORD(1,1), &wsaData)) - return 0; -#endif - return 1; -} - -int ff_network_wait_fd(int fd, int write) -{ - int ev = write ? POLLOUT : POLLIN; - struct pollfd p = { .fd = fd, .events = ev, .revents = 0 }; - int ret; - ret = poll(&p, 1, 100); - return ret < 0 ? ff_neterrno() : p.revents & (ev | POLLERR | POLLHUP) ? 0 : AVERROR(EAGAIN); -} - -int ff_network_wait_fd_timeout(int fd, int write, int64_t timeout, AVIOInterruptCB *int_cb) -{ - int ret; - int64_t wait_start = 0; - - while (1) { - ret = ff_network_wait_fd(fd, write); - if (ret != AVERROR(EAGAIN)) - return ret; - if (ff_check_interrupt(int_cb)) - return AVERROR_EXIT; - if (timeout) { - if (!wait_start) - wait_start = av_gettime(); - else if (av_gettime() - wait_start > timeout) - return AVERROR(ETIMEDOUT); - } - } -} - -void ff_network_close(void) -{ -#if HAVE_WINSOCK2_H - WSACleanup(); -#endif -} - -#if HAVE_WINSOCK2_H -int ff_neterrno(void) -{ - int err = WSAGetLastError(); - switch (err) { - case WSAEWOULDBLOCK: - return AVERROR(EAGAIN); - case WSAEINTR: - return AVERROR(EINTR); - case WSAEPROTONOSUPPORT: - return AVERROR(EPROTONOSUPPORT); - case WSAETIMEDOUT: - return AVERROR(ETIMEDOUT); - case WSAECONNREFUSED: - return AVERROR(ECONNREFUSED); - case WSAEINPROGRESS: - return AVERROR(EINPROGRESS); - } - return -err; -} -#endif - -int ff_is_multicast_address(struct sockaddr *addr) -{ - if (addr->sa_family == AF_INET) { - return IN_MULTICAST(ntohl(((struct sockaddr_in *)addr)->sin_addr.s_addr)); - } -#if HAVE_STRUCT_SOCKADDR_IN6 - if (addr->sa_family == AF_INET6) { - return IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6 *)addr)->sin6_addr); - } -#endif - - return 0; -} diff --git a/ffmpeg1/libavformat/network.h b/ffmpeg1/libavformat/network.h deleted file mode 100644 index f8b4dee..0000000 --- a/ffmpeg1/libavformat/network.h +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Copyright (c) 2007 The FFmpeg Project - * - * 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 AVFORMAT_NETWORK_H -#define AVFORMAT_NETWORK_H - -#include -#include - -#include "config.h" -#include "libavutil/error.h" -#include "os_support.h" -#include "avio.h" - -#if HAVE_UNISTD_H -#include -#endif - -#if HAVE_WINSOCK2_H -#include -#include - -#ifndef EPROTONOSUPPORT -#define EPROTONOSUPPORT WSAEPROTONOSUPPORT -#endif -#ifndef ETIMEDOUT -#define ETIMEDOUT WSAETIMEDOUT -#endif -#ifndef ECONNREFUSED -#define ECONNREFUSED WSAECONNREFUSED -#endif -#ifndef EINPROGRESS -#define EINPROGRESS WSAEINPROGRESS -#endif - -#define getsockopt(a, b, c, d, e) getsockopt(a, b, c, (char*) d, e) -#define setsockopt(a, b, c, d, e) setsockopt(a, b, c, (const char*) d, e) - -int ff_neterrno(void); -#else -#include -#include -#include -#include - -#define ff_neterrno() AVERROR(errno) -#endif - -#if HAVE_ARPA_INET_H -#include -#endif - -#if HAVE_POLL_H -#include -#endif - -int ff_socket_nonblock(int socket, int enable); - -extern int ff_network_inited_globally; -int ff_network_init(void); -void ff_network_close(void); - -void ff_tls_init(void); -void ff_tls_deinit(void); - -int ff_network_wait_fd(int fd, int write); - -/** - * This works similarly to ff_network_wait_fd, but waits up to 'timeout' microseconds - * Uses ff_network_wait_fd in a loop - * - * @fd Socket descriptor - * @write Set 1 to wait for socket able to be read, 0 to be written - * @timeout Timeout interval, in microseconds. Actual precision is 100000 mcs, due to ff_network_wait_fd usage - * @param int_cb Interrupt callback, is checked after each ff_network_wait_fd call - * @return 0 if data can be read/written, AVERROR(ETIMEDOUT) if timeout expired, or negative error code - */ -int ff_network_wait_fd_timeout(int fd, int write, int64_t timeout, AVIOInterruptCB *int_cb); - -int ff_inet_aton (const char * str, struct in_addr * add); - -#if !HAVE_STRUCT_SOCKADDR_STORAGE -struct sockaddr_storage { -#if HAVE_STRUCT_SOCKADDR_SA_LEN - uint8_t ss_len; - uint8_t ss_family; -#else - uint16_t ss_family; -#endif - char ss_pad1[6]; - int64_t ss_align; - char ss_pad2[112]; -}; -#endif - -#if !HAVE_STRUCT_ADDRINFO -struct addrinfo { - int ai_flags; - int ai_family; - int ai_socktype; - int ai_protocol; - int ai_addrlen; - struct sockaddr *ai_addr; - char *ai_canonname; - struct addrinfo *ai_next; -}; -#endif - -/* getaddrinfo constants */ -#ifndef EAI_AGAIN -#define EAI_AGAIN 2 -#endif -#ifndef EAI_BADFLAGS -#define EAI_BADFLAGS 3 -#endif -#ifndef EAI_FAIL -#define EAI_FAIL 4 -#endif -#ifndef EAI_FAMILY -#define EAI_FAMILY 5 -#endif -#ifndef EAI_MEMORY -#define EAI_MEMORY 6 -#endif -#ifndef EAI_NODATA -#define EAI_NODATA 7 -#endif -#ifndef EAI_NONAME -#define EAI_NONAME 8 -#endif -#ifndef EAI_SERVICE -#define EAI_SERVICE 9 -#endif -#ifndef EAI_SOCKTYPE -#define EAI_SOCKTYPE 10 -#endif - -#ifndef AI_PASSIVE -#define AI_PASSIVE 1 -#endif - -#ifndef AI_CANONNAME -#define AI_CANONNAME 2 -#endif - -#ifndef AI_NUMERICHOST -#define AI_NUMERICHOST 4 -#endif - -#ifndef NI_NOFQDN -#define NI_NOFQDN 1 -#endif - -#ifndef NI_NUMERICHOST -#define NI_NUMERICHOST 2 -#endif - -#ifndef NI_NAMERQD -#define NI_NAMERQD 4 -#endif - -#ifndef NI_NUMERICSERV -#define NI_NUMERICSERV 8 -#endif - -#ifndef NI_DGRAM -#define NI_DGRAM 16 -#endif - -#if !HAVE_GETADDRINFO -int ff_getaddrinfo(const char *node, const char *service, - const struct addrinfo *hints, struct addrinfo **res); -void ff_freeaddrinfo(struct addrinfo *res); -int ff_getnameinfo(const struct sockaddr *sa, int salen, - char *host, int hostlen, - char *serv, int servlen, int flags); -#define getaddrinfo ff_getaddrinfo -#define freeaddrinfo ff_freeaddrinfo -#define getnameinfo ff_getnameinfo -#endif -#if !HAVE_GETADDRINFO || HAVE_WINSOCK2_H -const char *ff_gai_strerror(int ecode); -#undef gai_strerror -#define gai_strerror ff_gai_strerror -#endif - -#ifndef INADDR_LOOPBACK -#define INADDR_LOOPBACK 0x7f000001 -#endif - -#ifndef INET_ADDRSTRLEN -#define INET_ADDRSTRLEN 16 -#endif - -#ifndef INET6_ADDRSTRLEN -#define INET6_ADDRSTRLEN INET_ADDRSTRLEN -#endif - -#ifndef IN_MULTICAST -#define IN_MULTICAST(a) ((((uint32_t)(a)) & 0xf0000000) == 0xe0000000) -#endif -#ifndef IN6_IS_ADDR_MULTICAST -#define IN6_IS_ADDR_MULTICAST(a) (((uint8_t *) (a))[0] == 0xff) -#endif - -int ff_is_multicast_address(struct sockaddr *addr); - -#endif /* AVFORMAT_NETWORK_H */ diff --git a/ffmpeg1/libavformat/nistspheredec.c b/ffmpeg1/libavformat/nistspheredec.c deleted file mode 100644 index c09df9c..0000000 --- a/ffmpeg1/libavformat/nistspheredec.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * NIST Sphere demuxer - * Copyright (c) 2012 Paul B Mahol - * - * 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 "libavutil/avstring.h" -#include "libavutil/intreadwrite.h" -#include "avformat.h" -#include "internal.h" -#include "pcm.h" - -static int nist_probe(AVProbeData *p) -{ - if (AV_RL64(p->buf) == AV_RL64("NIST_1A\x0a")) - return AVPROBE_SCORE_MAX; - return 0; -} - -static int nist_read_header(AVFormatContext *s) -{ - char buffer[32], coding[32] = "pcm", format[32] = "01"; - int bps = 0, be = 0; - int32_t header_size; - AVStream *st; - - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - - ff_get_line(s->pb, buffer, sizeof(buffer)); - ff_get_line(s->pb, buffer, sizeof(buffer)); - sscanf(buffer, "%"SCNd32, &header_size); - if (header_size <= 0) - return AVERROR_INVALIDDATA; - - while (!url_feof(s->pb)) { - ff_get_line(s->pb, buffer, sizeof(buffer)); - - if (avio_tell(s->pb) >= header_size) - return AVERROR_INVALIDDATA; - - if (!memcmp(buffer, "end_head", 8)) { - if (!st->codec->bits_per_coded_sample) - st->codec->bits_per_coded_sample = bps << 3; - - if (!av_strcasecmp(coding, "pcm")) { - st->codec->codec_id = ff_get_pcm_codec_id(st->codec->bits_per_coded_sample, - 0, be, 0xFFFF); - } else if (!av_strcasecmp(coding, "alaw")) { - st->codec->codec_id = AV_CODEC_ID_PCM_ALAW; - } else if (!av_strcasecmp(coding, "ulaw") || - !av_strcasecmp(coding, "mu-law")) { - st->codec->codec_id = AV_CODEC_ID_PCM_MULAW; - } else { - avpriv_request_sample(s, "coding %s", coding); - } - - avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); - - st->codec->block_align = st->codec->bits_per_coded_sample * st->codec->channels / 8; - - if (avio_tell(s->pb) > header_size) - return AVERROR_INVALIDDATA; - - avio_skip(s->pb, header_size - avio_tell(s->pb)); - - return 0; - } else if (!memcmp(buffer, "channel_count", 13)) { - sscanf(buffer, "%*s %*s %"SCNd32, &st->codec->channels); - } else if (!memcmp(buffer, "sample_byte_format", 18)) { - sscanf(buffer, "%*s %*s %31s", format); - - if (!av_strcasecmp(format, "01")) { - be = 0; - } else if (!av_strcasecmp(format, "10")) { - be = 1; - } else if (av_strcasecmp(format, "1")) { - avpriv_request_sample(s, "sample byte format %s", format); - return AVERROR_PATCHWELCOME; - } - } else if (!memcmp(buffer, "sample_coding", 13)) { - sscanf(buffer, "%*s %*s %31s", coding); - } else if (!memcmp(buffer, "sample_count", 12)) { - sscanf(buffer, "%*s %*s %"SCNd64, &st->duration); - } else if (!memcmp(buffer, "sample_n_bytes", 14)) { - sscanf(buffer, "%*s %*s %"SCNd32, &bps); - } else if (!memcmp(buffer, "sample_rate", 11)) { - sscanf(buffer, "%*s %*s %"SCNd32, &st->codec->sample_rate); - } else if (!memcmp(buffer, "sample_sig_bits", 15)) { - sscanf(buffer, "%*s %*s %"SCNd32, &st->codec->bits_per_coded_sample); - } else { - char key[32], value[32]; - sscanf(buffer, "%31s %*s %31s", key, value); - av_dict_set(&s->metadata, key, value, AV_DICT_APPEND); - } - } - - return AVERROR_EOF; -} - -AVInputFormat ff_nistsphere_demuxer = { - .name = "nistsphere", - .long_name = NULL_IF_CONFIG_SMALL("NIST SPeech HEader REsources"), - .read_probe = nist_probe, - .read_header = nist_read_header, - .read_packet = ff_pcm_read_packet, - .read_seek = ff_pcm_read_seek, - .extensions = "nist,sph", - .flags = AVFMT_GENERIC_INDEX, -}; diff --git a/ffmpeg1/libavformat/noproxy-test.c b/ffmpeg1/libavformat/noproxy-test.c deleted file mode 100644 index a156620..0000000 --- a/ffmpeg1/libavformat/noproxy-test.c +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2013 Martin Storsjo - * - * 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 "internal.h" - -static void test(const char *pattern, const char *host) -{ - int res = ff_http_match_no_proxy(pattern, host); - printf("The pattern \"%s\" %s the hostname %s\n", - pattern ? pattern : "(null)", res ? "matches" : "does not match", - host); -} - -int main(void) -{ - test(NULL, "domain.com"); - test("example.com domain.com", "domain.com"); - test("example.com other.com", "domain.com"); - test("example.com,domain.com", "domain.com"); - test("example.com,domain.com", "otherdomain.com"); - test("example.com, *.domain.com", "sub.domain.com"); - test("example.com, *.domain.com", "domain.com"); - test("example.com, .domain.com", "domain.com"); - test("*", "domain.com"); - return 0; -} diff --git a/ffmpeg1/libavformat/nsvdec.c b/ffmpeg1/libavformat/nsvdec.c deleted file mode 100644 index bcc2180..0000000 --- a/ffmpeg1/libavformat/nsvdec.c +++ /dev/null @@ -1,802 +0,0 @@ -/* - * NSV demuxer - * Copyright (c) 2004 The FFmpeg Project - * - * 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 "libavutil/attributes.h" -#include "libavutil/mathematics.h" -#include "avformat.h" -#include "internal.h" -#include "libavutil/dict.h" -#include "libavutil/intreadwrite.h" - -//#define DEBUG_DUMP_INDEX // XXX dumbdriving-271.nsv breaks with it commented!! -#define CHECK_SUBSEQUENT_NSVS -//#define DISABLE_AUDIO - -/* max bytes to crawl for trying to resync - * stupid streaming servers don't start at chunk boundaries... - */ -#define NSV_MAX_RESYNC (500*1024) -#define NSV_MAX_RESYNC_TRIES 300 - -/* - * First version by Francois Revol - revol@free.fr - * References: - * (1) http://www.multimedia.cx/nsv-format.txt - * seems someone came to the same conclusions as me, and updated it: - * (2) http://www.stud.ktu.lt/~vitslav/nsv/nsv-format.txt - * http://www.stud.ktu.lt/~vitslav/nsv/ - * official docs - * (3) http://ultravox.aol.com/NSVFormat.rtf - * Sample files: - * (S1) http://www.nullsoft.com/nsv/samples/ - * http://www.nullsoft.com/nsv/samples/faster.nsv - * http://streamripper.sourceforge.net/openbb/read.php?TID=492&page=4 - */ - -/* - * notes on the header (Francois Revol): - * - * It is followed by strings, then a table, but nothing tells - * where the table begins according to (1). After checking faster.nsv, - * I believe NVSf[16-19] gives the size of the strings data - * (that is the offset of the data table after the header). - * After checking all samples from (S1) all confirms this. - * - * Then, about NSVf[12-15], faster.nsf has 179700. When veiwing it in VLC, - * I noticed there was about 1 NVSs chunk/s, so I ran - * strings faster.nsv | grep NSVs | wc -l - * which gave me 180. That leads me to think that NSVf[12-15] might be the - * file length in milliseconds. - * Let's try that: - * for f in *.nsv; do HTIME="$(od -t x4 "$f" | head -1 | sed 's/.* //')"; echo "'$f' $((0x$HTIME))s = $((0x$HTIME/1000/60)):$((0x$HTIME/1000%60))"; done - * except for nstrailer (which doesn't have an NSVf header), it repports correct time. - * - * nsvtrailer.nsv (S1) does not have any NSVf header, only NSVs chunks, - * so the header seems to not be mandatory. (for streaming). - * - * index slice duration check (excepts nsvtrailer.nsv): - * for f in [^n]*.nsv; do DUR="$(ffmpeg -i "$f" 2>/dev/null | grep 'NSVf duration' | cut -d ' ' -f 4)"; IC="$(ffmpeg -i "$f" 2>/dev/null | grep 'INDEX ENTRIES' | cut -d ' ' -f 2)"; echo "duration $DUR, slite time $(($DUR/$IC))"; done - */ - -/* - * TODO: - * - handle timestamps !!! - * - use index - * - mime-type in probe() - * - seek - */ - -#if 0 -struct NSVf_header { - uint32_t chunk_tag; /* 'NSVf' */ - uint32_t chunk_size; - uint32_t file_size; /* max 4GB ??? no one learns anything it seems :^) */ - uint32_t file_length; //unknown1; /* what about MSB of file_size ? */ - uint32_t info_strings_size; /* size of the info strings */ //unknown2; - uint32_t table_entries; - uint32_t table_entries_used; /* the left ones should be -1 */ -}; - -struct NSVs_header { - uint32_t chunk_tag; /* 'NSVs' */ - uint32_t v4cc; /* or 'NONE' */ - uint32_t a4cc; /* or 'NONE' */ - uint16_t vwidth; /* av_assert(vwidth%16==0) */ - uint16_t vheight; /* av_assert(vheight%16==0) */ - uint8_t framerate; /* value = (framerate&0x80)?frtable[frameratex0x7f]:framerate */ - uint16_t unknown; -}; - -struct nsv_avchunk_header { - uint8_t vchunk_size_lsb; - uint16_t vchunk_size_msb; /* value = (vchunk_size_msb << 4) | (vchunk_size_lsb >> 4) */ - uint16_t achunk_size; -}; - -struct nsv_pcm_header { - uint8_t bits_per_sample; - uint8_t channel_count; - uint16_t sample_rate; -}; -#endif - -/* variation from avi.h */ -/*typedef struct CodecTag { - int id; - unsigned int tag; -} CodecTag;*/ - -/* tags */ - -#define T_NSVF MKTAG('N', 'S', 'V', 'f') /* file header */ -#define T_NSVS MKTAG('N', 'S', 'V', 's') /* chunk header */ -#define T_TOC2 MKTAG('T', 'O', 'C', '2') /* extra index marker */ -#define T_NONE MKTAG('N', 'O', 'N', 'E') /* null a/v 4CC */ -#define T_SUBT MKTAG('S', 'U', 'B', 'T') /* subtitle aux data */ -#define T_ASYN MKTAG('A', 'S', 'Y', 'N') /* async a/v aux marker */ -#define T_KEYF MKTAG('K', 'E', 'Y', 'F') /* video keyframe aux marker (addition) */ - -#define TB_NSVF MKBETAG('N', 'S', 'V', 'f') -#define TB_NSVS MKBETAG('N', 'S', 'V', 's') - -/* hardcoded stream indexes */ -#define NSV_ST_VIDEO 0 -#define NSV_ST_AUDIO 1 -#define NSV_ST_SUBT 2 - -enum NSVStatus { - NSV_UNSYNC, - NSV_FOUND_NSVF, - NSV_HAS_READ_NSVF, - NSV_FOUND_NSVS, - NSV_HAS_READ_NSVS, - NSV_FOUND_BEEF, - NSV_GOT_VIDEO, - NSV_GOT_AUDIO, -}; - -typedef struct NSVStream { - int frame_offset; /* current frame (video) or byte (audio) counter - (used to compute the pts) */ - int scale; - int rate; - int sample_size; /* audio only data */ - int start; - - int new_frame_offset; /* temporary storage (used during seek) */ - int cum_len; /* temporary storage (used during seek) */ -} NSVStream; - -typedef struct { - int base_offset; - int NSVf_end; - uint32_t *nsvs_file_offset; - int index_entries; - enum NSVStatus state; - AVPacket ahead[2]; /* [v, a] if .data is !NULL there is something */ - /* cached */ - int64_t duration; - uint32_t vtag, atag; - uint16_t vwidth, vheight; - int16_t avsync; - AVRational framerate; - uint32_t *nsvs_timestamps; - //DVDemuxContext* dv_demux; -} NSVContext; - -static const AVCodecTag nsv_codec_video_tags[] = { - { AV_CODEC_ID_VP3, MKTAG('V', 'P', '3', ' ') }, - { AV_CODEC_ID_VP3, MKTAG('V', 'P', '3', '0') }, - { AV_CODEC_ID_VP3, MKTAG('V', 'P', '3', '1') }, - { AV_CODEC_ID_VP5, MKTAG('V', 'P', '5', ' ') }, - { AV_CODEC_ID_VP5, MKTAG('V', 'P', '5', '0') }, - { AV_CODEC_ID_VP6, MKTAG('V', 'P', '6', ' ') }, - { AV_CODEC_ID_VP6, MKTAG('V', 'P', '6', '0') }, - { AV_CODEC_ID_VP6, MKTAG('V', 'P', '6', '1') }, - { AV_CODEC_ID_VP6, MKTAG('V', 'P', '6', '2') }, - { AV_CODEC_ID_VP8, MKTAG('V', 'P', '8', '0') }, -/* - { AV_CODEC_ID_VP4, MKTAG('V', 'P', '4', ' ') }, - { AV_CODEC_ID_VP4, MKTAG('V', 'P', '4', '0') }, -*/ - { AV_CODEC_ID_MPEG4, MKTAG('X', 'V', 'I', 'D') }, /* cf sample xvid decoder from nsv_codec_sdk.zip */ - { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', '3') }, - { AV_CODEC_ID_NONE, 0 }, -}; - -static const AVCodecTag nsv_codec_audio_tags[] = { - { AV_CODEC_ID_MP3, MKTAG('M', 'P', '3', ' ') }, - { AV_CODEC_ID_AAC, MKTAG('A', 'A', 'C', ' ') }, - { AV_CODEC_ID_AAC, MKTAG('A', 'A', 'C', 'P') }, - { AV_CODEC_ID_AAC, MKTAG('V', 'L', 'B', ' ') }, - { AV_CODEC_ID_SPEEX, MKTAG('S', 'P', 'X', ' ') }, - { AV_CODEC_ID_PCM_U16LE, MKTAG('P', 'C', 'M', ' ') }, - { AV_CODEC_ID_NONE, 0 }, -}; - -//static int nsv_load_index(AVFormatContext *s); -static int nsv_read_chunk(AVFormatContext *s, int fill_header); - -#define print_tag(str, tag, size) \ - av_dlog(NULL, "%s: tag=%c%c%c%c\n", \ - str, tag & 0xff, \ - (tag >> 8) & 0xff, \ - (tag >> 16) & 0xff, \ - (tag >> 24) & 0xff); - -/* try to find something we recognize, and set the state accordingly */ -static int nsv_resync(AVFormatContext *s) -{ - NSVContext *nsv = s->priv_data; - AVIOContext *pb = s->pb; - uint32_t v = 0; - int i; - - av_dlog(s, "%s(), offset = %"PRId64", state = %d\n", __FUNCTION__, avio_tell(pb), nsv->state); - - //nsv->state = NSV_UNSYNC; - - for (i = 0; i < NSV_MAX_RESYNC; i++) { - if (url_feof(pb)) { - av_dlog(s, "NSV EOF\n"); - nsv->state = NSV_UNSYNC; - return -1; - } - v <<= 8; - v |= avio_r8(pb); - if (i < 8) { - av_dlog(s, "NSV resync: [%d] = %02x\n", i, v & 0x0FF); - } - - if ((v & 0x0000ffff) == 0xefbe) { /* BEEF */ - av_dlog(s, "NSV resynced on BEEF after %d bytes\n", i+1); - nsv->state = NSV_FOUND_BEEF; - return 0; - } - /* we read as big-endian, thus the MK*BE* */ - if (v == TB_NSVF) { /* NSVf */ - av_dlog(s, "NSV resynced on NSVf after %d bytes\n", i+1); - nsv->state = NSV_FOUND_NSVF; - return 0; - } - if (v == MKBETAG('N', 'S', 'V', 's')) { /* NSVs */ - av_dlog(s, "NSV resynced on NSVs after %d bytes\n", i+1); - nsv->state = NSV_FOUND_NSVS; - return 0; - } - - } - av_dlog(s, "NSV sync lost\n"); - return -1; -} - -static int nsv_parse_NSVf_header(AVFormatContext *s) -{ - NSVContext *nsv = s->priv_data; - AVIOContext *pb = s->pb; - unsigned int av_unused file_size; - unsigned int size; - int64_t duration; - int strings_size; - int table_entries; - int table_entries_used; - - av_dlog(s, "%s()\n", __FUNCTION__); - - nsv->state = NSV_UNSYNC; /* in case we fail */ - - size = avio_rl32(pb); - if (size < 28) - return -1; - nsv->NSVf_end = size; - - //s->file_size = (uint32_t)avio_rl32(pb); - file_size = (uint32_t)avio_rl32(pb); - av_dlog(s, "NSV NSVf chunk_size %u\n", size); - av_dlog(s, "NSV NSVf file_size %u\n", file_size); - - nsv->duration = duration = avio_rl32(pb); /* in ms */ - av_dlog(s, "NSV NSVf duration %"PRId64" ms\n", duration); - // XXX: store it in AVStreams - - strings_size = avio_rl32(pb); - table_entries = avio_rl32(pb); - table_entries_used = avio_rl32(pb); - av_dlog(s, "NSV NSVf info-strings size: %d, table entries: %d, bis %d\n", - strings_size, table_entries, table_entries_used); - if (url_feof(pb)) - return -1; - - av_dlog(s, "NSV got header; filepos %"PRId64"\n", avio_tell(pb)); - - if (strings_size > 0) { - char *strings; /* last byte will be '\0' to play safe with str*() */ - char *p, *endp; - char *token, *value; - char quote; - - p = strings = av_mallocz((size_t)strings_size + 1); - if (!p) - return AVERROR(ENOMEM); - endp = strings + strings_size; - avio_read(pb, strings, strings_size); - while (p < endp) { - while (*p == ' ') - p++; /* strip out spaces */ - if (p >= endp-2) - break; - token = p; - p = strchr(p, '='); - if (!p || p >= endp-2) - break; - *p++ = '\0'; - quote = *p++; - value = p; - p = strchr(p, quote); - if (!p || p >= endp) - break; - *p++ = '\0'; - av_dlog(s, "NSV NSVf INFO: %s='%s'\n", token, value); - av_dict_set(&s->metadata, token, value, 0); - } - av_free(strings); - } - if (url_feof(pb)) - return -1; - - av_dlog(s, "NSV got infos; filepos %"PRId64"\n", avio_tell(pb)); - - if (table_entries_used > 0) { - int i; - nsv->index_entries = table_entries_used; - if((unsigned)table_entries_used >= UINT_MAX / sizeof(uint32_t)) - return -1; - nsv->nsvs_file_offset = av_malloc((unsigned)table_entries_used * sizeof(uint32_t)); - if (!nsv->nsvs_file_offset) - return AVERROR(ENOMEM); - - for(i=0;insvs_file_offset[i] = avio_rl32(pb) + size; - - if(table_entries > table_entries_used && - avio_rl32(pb) == MKTAG('T','O','C','2')) { - nsv->nsvs_timestamps = av_malloc((unsigned)table_entries_used*sizeof(uint32_t)); - if (!nsv->nsvs_timestamps) - return AVERROR(ENOMEM); - for(i=0;insvs_timestamps[i] = avio_rl32(pb); - } - } - } - - av_dlog(s, "NSV got index; filepos %"PRId64"\n", avio_tell(pb)); - -#ifdef DEBUG_DUMP_INDEX -#define V(v) ((v<0x20 || v > 127)?'.':v) - /* dump index */ - av_dlog(s, "NSV %d INDEX ENTRIES:\n", table_entries); - av_dlog(s, "NSV [dataoffset][fileoffset]\n", table_entries); - for (i = 0; i < table_entries; i++) { - unsigned char b[8]; - avio_seek(pb, size + nsv->nsvs_file_offset[i], SEEK_SET); - avio_read(pb, b, 8); - av_dlog(s, "NSV [0x%08lx][0x%08lx]: %02x %02x %02x %02x %02x %02x %02x %02x" - "%c%c%c%c%c%c%c%c\n", - nsv->nsvs_file_offset[i], size + nsv->nsvs_file_offset[i], - b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], - V(b[0]), V(b[1]), V(b[2]), V(b[3]), V(b[4]), V(b[5]), V(b[6]), V(b[7]) ); - } - //avio_seek(pb, size, SEEK_SET); /* go back to end of header */ -#undef V -#endif - - avio_seek(pb, nsv->base_offset + size, SEEK_SET); /* required for dumbdriving-271.nsv (2 extra bytes) */ - - if (url_feof(pb)) - return -1; - nsv->state = NSV_HAS_READ_NSVF; - return 0; -} - -static int nsv_parse_NSVs_header(AVFormatContext *s) -{ - NSVContext *nsv = s->priv_data; - AVIOContext *pb = s->pb; - uint32_t vtag, atag; - uint16_t vwidth, vheight; - AVRational framerate; - int i; - AVStream *st; - NSVStream *nst; - av_dlog(s, "%s()\n", __FUNCTION__); - - vtag = avio_rl32(pb); - atag = avio_rl32(pb); - vwidth = avio_rl16(pb); - vheight = avio_rl16(pb); - i = avio_r8(pb); - - av_dlog(s, "NSV NSVs framerate code %2x\n", i); - if(i&0x80) { /* odd way of giving native framerates from docs */ - int t=(i & 0x7F)>>2; - if(t<16) framerate = (AVRational){1, t+1}; - else framerate = (AVRational){t-15, 1}; - - if(i&1){ - framerate.num *= 1000; - framerate.den *= 1001; - } - - if((i&3)==3) framerate.num *= 24; - else if((i&3)==2) framerate.num *= 25; - else framerate.num *= 30; - } - else - framerate= (AVRational){i, 1}; - - nsv->avsync = avio_rl16(pb); - nsv->framerate = framerate; - - print_tag("NSV NSVs vtag", vtag, 0); - print_tag("NSV NSVs atag", atag, 0); - av_dlog(s, "NSV NSVs vsize %dx%d\n", vwidth, vheight); - - /* XXX change to ap != NULL ? */ - if (s->nb_streams == 0) { /* streams not yet published, let's do that */ - nsv->vtag = vtag; - nsv->atag = atag; - nsv->vwidth = vwidth; - nsv->vheight = vwidth; - if (vtag != T_NONE) { - int i; - st = avformat_new_stream(s, NULL); - if (!st) - goto fail; - - st->id = NSV_ST_VIDEO; - nst = av_mallocz(sizeof(NSVStream)); - if (!nst) - goto fail; - st->priv_data = nst; - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_tag = vtag; - st->codec->codec_id = ff_codec_get_id(nsv_codec_video_tags, vtag); - st->codec->width = vwidth; - st->codec->height = vheight; - st->codec->bits_per_coded_sample = 24; /* depth XXX */ - - avpriv_set_pts_info(st, 64, framerate.den, framerate.num); - st->start_time = 0; - st->duration = av_rescale(nsv->duration, framerate.num, 1000*framerate.den); - - for(i=0;iindex_entries;i++) { - if(nsv->nsvs_timestamps) { - av_add_index_entry(st, nsv->nsvs_file_offset[i], nsv->nsvs_timestamps[i], - 0, 0, AVINDEX_KEYFRAME); - } else { - int64_t ts = av_rescale(i*nsv->duration/nsv->index_entries, framerate.num, 1000*framerate.den); - av_add_index_entry(st, nsv->nsvs_file_offset[i], ts, 0, 0, AVINDEX_KEYFRAME); - } - } - } - if (atag != T_NONE) { -#ifndef DISABLE_AUDIO - st = avformat_new_stream(s, NULL); - if (!st) - goto fail; - - st->id = NSV_ST_AUDIO; - nst = av_mallocz(sizeof(NSVStream)); - if (!nst) - goto fail; - st->priv_data = nst; - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_tag = atag; - st->codec->codec_id = ff_codec_get_id(nsv_codec_audio_tags, atag); - - st->need_parsing = AVSTREAM_PARSE_FULL; /* for PCM we will read a chunk later and put correct info */ - - /* set timebase to common denominator of ms and framerate */ - avpriv_set_pts_info(st, 64, 1, framerate.num*1000); - st->start_time = 0; - st->duration = (int64_t)nsv->duration * framerate.num; -#endif - } -#ifdef CHECK_SUBSEQUENT_NSVS - } else { - if (nsv->vtag != vtag || nsv->atag != atag || nsv->vwidth != vwidth || nsv->vheight != vwidth) { - av_dlog(s, "NSV NSVs header values differ from the first one!!!\n"); - //return -1; - } -#endif /* CHECK_SUBSEQUENT_NSVS */ - } - - nsv->state = NSV_HAS_READ_NSVS; - return 0; -fail: - /* XXX */ - nsv->state = NSV_UNSYNC; - return -1; -} - -static int nsv_read_header(AVFormatContext *s) -{ - NSVContext *nsv = s->priv_data; - int i, err; - - av_dlog(s, "%s()\n", __FUNCTION__); - av_dlog(s, "filename '%s'\n", s->filename); - - nsv->state = NSV_UNSYNC; - nsv->ahead[0].data = nsv->ahead[1].data = NULL; - - for (i = 0; i < NSV_MAX_RESYNC_TRIES; i++) { - if (nsv_resync(s) < 0) - return -1; - if (nsv->state == NSV_FOUND_NSVF) { - err = nsv_parse_NSVf_header(s); - if (err < 0) - return err; - } - /* we need the first NSVs also... */ - if (nsv->state == NSV_FOUND_NSVS) { - err = nsv_parse_NSVs_header(s); - if (err < 0) - return err; - break; /* we just want the first one */ - } - } - if (s->nb_streams < 1) /* no luck so far */ - return -1; - /* now read the first chunk, so we can attempt to decode more info */ - err = nsv_read_chunk(s, 1); - - av_dlog(s, "parsed header\n"); - return err; -} - -static int nsv_read_chunk(AVFormatContext *s, int fill_header) -{ - NSVContext *nsv = s->priv_data; - AVIOContext *pb = s->pb; - AVStream *st[2] = {NULL, NULL}; - NSVStream *nst; - AVPacket *pkt; - int i, err = 0; - uint8_t auxcount; /* number of aux metadata, also 4 bits of vsize */ - uint32_t vsize; - uint16_t asize; - uint16_t auxsize; - - av_dlog(s, "%s(%d)\n", __FUNCTION__, fill_header); - - if (nsv->ahead[0].data || nsv->ahead[1].data) - return 0; //-1; /* hey! eat what you've in your plate first! */ - -null_chunk_retry: - if (url_feof(pb)) - return -1; - - for (i = 0; i < NSV_MAX_RESYNC_TRIES && nsv->state < NSV_FOUND_NSVS && !err; i++) - err = nsv_resync(s); - if (err < 0) - return err; - if (nsv->state == NSV_FOUND_NSVS) - err = nsv_parse_NSVs_header(s); - if (err < 0) - return err; - if (nsv->state != NSV_HAS_READ_NSVS && nsv->state != NSV_FOUND_BEEF) - return -1; - - auxcount = avio_r8(pb); - vsize = avio_rl16(pb); - asize = avio_rl16(pb); - vsize = (vsize << 4) | (auxcount >> 4); - auxcount &= 0x0f; - av_dlog(s, "NSV CHUNK %d aux, %u bytes video, %d bytes audio\n", auxcount, vsize, asize); - /* skip aux stuff */ - for (i = 0; i < auxcount; i++) { - uint32_t av_unused auxtag; - auxsize = avio_rl16(pb); - auxtag = avio_rl32(pb); - av_dlog(s, "NSV aux data: '%c%c%c%c', %d bytes\n", - (auxtag & 0x0ff), - ((auxtag >> 8) & 0x0ff), - ((auxtag >> 16) & 0x0ff), - ((auxtag >> 24) & 0x0ff), - auxsize); - avio_skip(pb, auxsize); - vsize -= auxsize + sizeof(uint16_t) + sizeof(uint32_t); /* that's becoming braindead */ - } - - if (url_feof(pb)) - return -1; - if (!vsize && !asize) { - nsv->state = NSV_UNSYNC; - goto null_chunk_retry; - } - - /* map back streams to v,a */ - if (s->nb_streams > 0) - st[s->streams[0]->id] = s->streams[0]; - if (s->nb_streams > 1) - st[s->streams[1]->id] = s->streams[1]; - - if (vsize && st[NSV_ST_VIDEO]) { - nst = st[NSV_ST_VIDEO]->priv_data; - pkt = &nsv->ahead[NSV_ST_VIDEO]; - av_get_packet(pb, pkt, vsize); - pkt->stream_index = st[NSV_ST_VIDEO]->index;//NSV_ST_VIDEO; - pkt->dts = nst->frame_offset; - pkt->flags |= nsv->state == NSV_HAS_READ_NSVS ? AV_PKT_FLAG_KEY : 0; /* keyframe only likely on a sync frame */ - for (i = 0; i < FFMIN(8, vsize); i++) - av_dlog(s, "NSV video: [%d] = %02x\n", i, pkt->data[i]); - } - if(st[NSV_ST_VIDEO]) - ((NSVStream*)st[NSV_ST_VIDEO]->priv_data)->frame_offset++; - - if (asize && st[NSV_ST_AUDIO]) { - nst = st[NSV_ST_AUDIO]->priv_data; - pkt = &nsv->ahead[NSV_ST_AUDIO]; - /* read raw audio specific header on the first audio chunk... */ - /* on ALL audio chunks ?? seems so! */ - if (asize && st[NSV_ST_AUDIO]->codec->codec_tag == MKTAG('P', 'C', 'M', ' ')/* && fill_header*/) { - uint8_t bps; - uint8_t channels; - uint16_t samplerate; - bps = avio_r8(pb); - channels = avio_r8(pb); - samplerate = avio_rl16(pb); - asize-=4; - av_dlog(s, "NSV RAWAUDIO: bps %d, nchan %d, srate %d\n", bps, channels, samplerate); - if (fill_header) { - st[NSV_ST_AUDIO]->need_parsing = AVSTREAM_PARSE_NONE; /* we know everything */ - if (bps != 16) { - av_dlog(s, "NSV AUDIO bit/sample != 16 (%d)!!!\n", bps); - } - if(channels) - bps /= channels; // ??? - else - av_log(s, AV_LOG_WARNING, "Channels is 0\n"); - if (bps == 8) - st[NSV_ST_AUDIO]->codec->codec_id = AV_CODEC_ID_PCM_U8; - samplerate /= 4;/* UGH ??? XXX */ - channels = 1; - st[NSV_ST_AUDIO]->codec->channels = channels; - st[NSV_ST_AUDIO]->codec->sample_rate = samplerate; - av_dlog(s, "NSV RAWAUDIO: bps %d, nchan %d, srate %d\n", bps, channels, samplerate); - } - } - av_get_packet(pb, pkt, asize); - pkt->stream_index = st[NSV_ST_AUDIO]->index;//NSV_ST_AUDIO; - pkt->flags |= nsv->state == NSV_HAS_READ_NSVS ? AV_PKT_FLAG_KEY : 0; /* keyframe only likely on a sync frame */ - if( nsv->state == NSV_HAS_READ_NSVS && st[NSV_ST_VIDEO] ) { - /* on a nsvs frame we have new information on a/v sync */ - pkt->dts = (((NSVStream*)st[NSV_ST_VIDEO]->priv_data)->frame_offset-1); - pkt->dts *= (int64_t)1000 * nsv->framerate.den; - pkt->dts += (int64_t)nsv->avsync * nsv->framerate.num; - av_dlog(s, "NSV AUDIO: sync:%d, dts:%"PRId64, nsv->avsync, pkt->dts); - } - nst->frame_offset++; - } - - nsv->state = NSV_UNSYNC; - return 0; -} - - -static int nsv_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - NSVContext *nsv = s->priv_data; - int i, err = 0; - - av_dlog(s, "%s()\n", __FUNCTION__); - - /* in case we don't already have something to eat ... */ - if (nsv->ahead[0].data == NULL && nsv->ahead[1].data == NULL) - err = nsv_read_chunk(s, 0); - if (err < 0) - return err; - - /* now pick one of the plates */ - for (i = 0; i < 2; i++) { - if (nsv->ahead[i].data) { - av_dlog(s, "%s: using cached packet[%d]\n", __FUNCTION__, i); - /* avoid the cost of new_packet + memcpy(->data) */ - memcpy(pkt, &nsv->ahead[i], sizeof(AVPacket)); - nsv->ahead[i].data = NULL; /* we ate that one */ - return pkt->size; - } - } - - /* this restaurant is not approvisionned :^] */ - return -1; -} - -static int nsv_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) -{ - NSVContext *nsv = s->priv_data; - AVStream *st = s->streams[stream_index]; - NSVStream *nst = st->priv_data; - int index; - - index = av_index_search_timestamp(st, timestamp, flags); - if(index < 0) - return -1; - - if (avio_seek(s->pb, st->index_entries[index].pos, SEEK_SET) < 0) - return -1; - - nst->frame_offset = st->index_entries[index].timestamp; - nsv->state = NSV_UNSYNC; - return 0; -} - -static int nsv_read_close(AVFormatContext *s) -{ -/* int i; */ - NSVContext *nsv = s->priv_data; - - av_freep(&nsv->nsvs_file_offset); - av_freep(&nsv->nsvs_timestamps); - if (nsv->ahead[0].data) - av_free_packet(&nsv->ahead[0]); - if (nsv->ahead[1].data) - av_free_packet(&nsv->ahead[1]); - -#if 0 - - for(i=0;inb_streams;i++) { - AVStream *st = s->streams[i]; - NSVStream *ast = st->priv_data; - if(ast){ - av_free(ast->index_entries); - av_free(ast); - } - av_free(st->codec->palctrl); - } - -#endif - return 0; -} - -static int nsv_probe(AVProbeData *p) -{ - int i, score = 0; - - av_dlog(NULL, "nsv_probe(), buf_size %d\n", p->buf_size); - /* check file header */ - /* streamed files might not have any header */ - if (p->buf[0] == 'N' && p->buf[1] == 'S' && - p->buf[2] == 'V' && (p->buf[3] == 'f' || p->buf[3] == 's')) - return AVPROBE_SCORE_MAX; - /* XXX: do streamed files always start at chunk boundary ?? */ - /* or do we need to search NSVs in the byte stream ? */ - /* seems the servers don't bother starting clean chunks... */ - /* sometimes even the first header is at 9KB or something :^) */ - for (i = 1; i < p->buf_size - 3; i++) { - if (AV_RL32(p->buf + i) == AV_RL32("NSVs")) { - /* Get the chunk size and check if at the end we are getting 0xBEEF */ - int vsize = AV_RL24(p->buf+i+19) >> 4; - int asize = AV_RL16(p->buf+i+22); - int offset = i + 23 + asize + vsize + 1; - if (offset <= p->buf_size - 2 && AV_RL16(p->buf + offset) == 0xBEEF) - return 4*AVPROBE_SCORE_MAX/5; - score = AVPROBE_SCORE_MAX/5; - } - } - /* so we'll have more luck on extension... */ - if (av_match_ext(p->filename, "nsv")) - return AVPROBE_SCORE_MAX/2; - /* FIXME: add mime-type check */ - return score; -} - -AVInputFormat ff_nsv_demuxer = { - .name = "nsv", - .long_name = NULL_IF_CONFIG_SMALL("Nullsoft Streaming Video"), - .priv_data_size = sizeof(NSVContext), - .read_probe = nsv_probe, - .read_header = nsv_read_header, - .read_packet = nsv_read_packet, - .read_close = nsv_read_close, - .read_seek = nsv_read_seek, -}; diff --git a/ffmpeg1/libavformat/nullenc.c b/ffmpeg1/libavformat/nullenc.c deleted file mode 100644 index 7da297b..0000000 --- a/ffmpeg1/libavformat/nullenc.c +++ /dev/null @@ -1,36 +0,0 @@ -/* - * RAW null muxer - * Copyright (c) 2002 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" - -static int null_write_packet(struct AVFormatContext *s, AVPacket *pkt) -{ - return 0; -} - -AVOutputFormat ff_null_muxer = { - .name = "null", - .long_name = NULL_IF_CONFIG_SMALL("raw null video"), - .audio_codec = AV_NE(AV_CODEC_ID_PCM_S16BE, AV_CODEC_ID_PCM_S16LE), - .video_codec = AV_CODEC_ID_RAWVIDEO, - .write_packet = null_write_packet, - .flags = AVFMT_NOFILE | AVFMT_NOTIMESTAMPS | AVFMT_RAWPICTURE, -}; diff --git a/ffmpeg1/libavformat/nut.c b/ffmpeg1/libavformat/nut.c deleted file mode 100644 index 2abe969..0000000 --- a/ffmpeg1/libavformat/nut.c +++ /dev/null @@ -1,264 +0,0 @@ -/* - * nut - * Copyright (c) 2004-2007 Michael Niedermayer - * - * 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 "libavutil/mathematics.h" -#include "libavutil/tree.h" -#include "nut.h" -#include "riff.h" -#include "internal.h" - -const AVCodecTag ff_nut_subtitle_tags[] = { - { AV_CODEC_ID_TEXT , MKTAG('U', 'T', 'F', '8') }, - { AV_CODEC_ID_SSA , MKTAG('S', 'S', 'A', 0 ) }, - { AV_CODEC_ID_DVD_SUBTITLE, MKTAG('D', 'V', 'D', 'S') }, - { AV_CODEC_ID_DVB_SUBTITLE, MKTAG('D', 'V', 'B', 'S') }, - { AV_CODEC_ID_DVB_TELETEXT, MKTAG('D', 'V', 'B', 'T') }, - { AV_CODEC_ID_NONE , 0 } -}; - -const AVCodecTag ff_nut_data_tags[] = { - { AV_CODEC_ID_TEXT , MKTAG('U', 'T', 'F', '8') }, - { AV_CODEC_ID_NONE , 0 } -}; - -const AVCodecTag ff_nut_video_tags[] = { - { AV_CODEC_ID_VP9, MKTAG('V', 'P', '9', '0') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 15 ) }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 15 ) }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 16 ) }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 16 ) }, - { AV_CODEC_ID_RAWVIDEO, MKTAG(15 , 'B', 'G', 'R') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG(15 , 'R', 'G', 'B') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG(16 , 'B', 'G', 'R') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG(16 , 'R', 'G', 'B') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 12 ) }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 12 ) }, - { AV_CODEC_ID_RAWVIDEO, MKTAG(12 , 'B', 'G', 'R') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG(12 , 'R', 'G', 'B') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 'A') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 0 ) }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 'A') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 0 ) }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('A', 'B', 'G', 'R') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG( 0 , 'B', 'G', 'R') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('A', 'R', 'G', 'B') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG( 0 , 'R', 'G', 'B') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 24 ) }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 24 ) }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('4', '1', '1', 'P') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('4', '2', '2', 'P') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('4', '2', '2', 'P') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('4', '4', '0', 'P') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('4', '4', '0', 'P') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('4', '4', '4', 'P') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('4', '4', '4', 'P') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('B', '1', 'W', '0') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('B', '0', 'W', '1') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 8 ) }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 8 ) }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 4 ) }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 4 ) }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('B', '4', 'B', 'Y') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('R', '4', 'B', 'Y') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'G', 'R', 48 ) }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', 48 ) }, - { AV_CODEC_ID_RAWVIDEO, MKTAG(48 , 'B', 'G', 'R') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG(48 , 'R', 'G', 'B') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('B', 'R', 'A', 64 ) }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('R', 'B', 'A', 64 ) }, - { AV_CODEC_ID_RAWVIDEO, MKTAG(64 , 'B', 'R', 'A') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG(64 , 'R', 'B', 'A') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 11 , 10 ) }, - { AV_CODEC_ID_RAWVIDEO, MKTAG(10 , 11 , '3', 'Y') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 10 , 10 ) }, - { AV_CODEC_ID_RAWVIDEO, MKTAG(10 , 10 , '3', 'Y') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 0 , 10 ) }, - { AV_CODEC_ID_RAWVIDEO, MKTAG(10 , 0 , '3', 'Y') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 11 , 12 ) }, - { AV_CODEC_ID_RAWVIDEO, MKTAG(12 , 11 , '3', 'Y') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 10 , 12 ) }, - { AV_CODEC_ID_RAWVIDEO, MKTAG(12 , 10 , '3', 'Y') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 0 , 12 ) }, - { AV_CODEC_ID_RAWVIDEO, MKTAG(12 , 0 , '3', 'Y') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 11 , 14 ) }, - { AV_CODEC_ID_RAWVIDEO, MKTAG(14 , 11 , '3', 'Y') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 10 , 14 ) }, - { AV_CODEC_ID_RAWVIDEO, MKTAG(14 , 10 , '3', 'Y') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 0 , 14 ) }, - { AV_CODEC_ID_RAWVIDEO, MKTAG(14 , 0 , '3', 'Y') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '1', 0 , 16 ) }, - { AV_CODEC_ID_RAWVIDEO, MKTAG(16 , 0 , '1', 'Y') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 11 , 16 ) }, - { AV_CODEC_ID_RAWVIDEO, MKTAG(16 , 11 , '3', 'Y') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 10 , 16 ) }, - { AV_CODEC_ID_RAWVIDEO, MKTAG(16 , 10 , '3', 'Y') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '3', 0 , 16 ) }, - { AV_CODEC_ID_RAWVIDEO, MKTAG(16 , 0 , '3', 'Y') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 11 , 8 ) }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 10 , 8 ) }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 0 , 8 ) }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '2', 0 , 8 ) }, - - { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '1', 0 , 9 ) }, - { AV_CODEC_ID_RAWVIDEO, MKTAG( 9 , 0 , '1', 'Y') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 11 , 9 ) }, - { AV_CODEC_ID_RAWVIDEO, MKTAG( 9 , 11 , '4', 'Y') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 10 , 9 ) }, - { AV_CODEC_ID_RAWVIDEO, MKTAG( 9 , 10 , '4', 'Y') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 0 , 9 ) }, - { AV_CODEC_ID_RAWVIDEO, MKTAG( 9 , 0 , '4', 'Y') }, - - { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '1', 0 , 10 ) }, - { AV_CODEC_ID_RAWVIDEO, MKTAG(10 , 0 , '1', 'Y') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 11 , 10 ) }, - { AV_CODEC_ID_RAWVIDEO, MKTAG(10 , 11 , '4', 'Y') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 10 , 10 ) }, - { AV_CODEC_ID_RAWVIDEO, MKTAG(10 , 10 , '4', 'Y') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 0 , 10 ) }, - { AV_CODEC_ID_RAWVIDEO, MKTAG(10 , 0 , '4', 'Y') }, - - { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '1', 0 , 16 ) }, - { AV_CODEC_ID_RAWVIDEO, MKTAG(16 , 0 , '1', 'Y') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 11 , 16 ) }, - { AV_CODEC_ID_RAWVIDEO, MKTAG(16 , 11 , '4', 'Y') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 10 , 16 ) }, - { AV_CODEC_ID_RAWVIDEO, MKTAG(16 , 10 , '4', 'Y') }, - { AV_CODEC_ID_RAWVIDEO, MKTAG('Y', '4', 0 , 16 ) }, - { AV_CODEC_ID_RAWVIDEO, MKTAG(16 , 0 , '4', 'Y') }, - - { AV_CODEC_ID_NONE , 0 } -}; - -static const AVCodecTag nut_audio_extra_tags[] = { - { AV_CODEC_ID_PCM_ALAW, MKTAG('A', 'L', 'A', 'W') }, - { AV_CODEC_ID_PCM_MULAW, MKTAG('U', 'L', 'A', 'W') }, - { AV_CODEC_ID_MP3, MKTAG('M', 'P', '3', ' ') }, - { AV_CODEC_ID_NONE, 0 } -}; - -const AVCodecTag ff_nut_audio_tags[] = { - { AV_CODEC_ID_PCM_F32BE, MKTAG(32 , 'D', 'F', 'P') }, - { AV_CODEC_ID_PCM_F32LE, MKTAG('P', 'F', 'D', 32 ) }, - { AV_CODEC_ID_PCM_F64BE, MKTAG(64 , 'D', 'F', 'P') }, - { AV_CODEC_ID_PCM_F64LE, MKTAG('P', 'F', 'D', 64 ) }, - { AV_CODEC_ID_PCM_S16BE, MKTAG(16 , 'D', 'S', 'P') }, - { AV_CODEC_ID_PCM_S16LE, MKTAG('P', 'S', 'D', 16 ) }, - { AV_CODEC_ID_PCM_S24BE, MKTAG(24 , 'D', 'S', 'P') }, - { AV_CODEC_ID_PCM_S24LE, MKTAG('P', 'S', 'D', 24 ) }, - { AV_CODEC_ID_PCM_S32BE, MKTAG(32 , 'D', 'S', 'P') }, - { AV_CODEC_ID_PCM_S32LE, MKTAG('P', 'S', 'D', 32 ) }, - { AV_CODEC_ID_PCM_S8, MKTAG('P', 'S', 'D', 8 ) }, - { AV_CODEC_ID_PCM_U16BE, MKTAG(16 , 'D', 'U', 'P') }, - { AV_CODEC_ID_PCM_U16LE, MKTAG('P', 'U', 'D', 16 ) }, - { AV_CODEC_ID_PCM_U24BE, MKTAG(24 , 'D', 'U', 'P') }, - { AV_CODEC_ID_PCM_U24LE, MKTAG('P', 'U', 'D', 24 ) }, - { AV_CODEC_ID_PCM_U32BE, MKTAG(32 , 'D', 'U', 'P') }, - { AV_CODEC_ID_PCM_U32LE, MKTAG('P', 'U', 'D', 32 ) }, - { AV_CODEC_ID_PCM_U8, MKTAG('P', 'U', 'D', 8 ) }, - { AV_CODEC_ID_PCM_S8_PLANAR, MKTAG('P', 'S', 'P', 8 ) }, - { AV_CODEC_ID_PCM_S16BE_PLANAR, MKTAG(16 , 'P', 'S', 'P') }, - { AV_CODEC_ID_PCM_S16LE_PLANAR, MKTAG('P', 'S', 'P', 16 ) }, - { AV_CODEC_ID_PCM_S24LE_PLANAR, MKTAG('P', 'S', 'P', 24 ) }, - { AV_CODEC_ID_PCM_S32LE_PLANAR, MKTAG('P', 'S', 'P', 32 ) }, - { AV_CODEC_ID_NONE, 0 } -}; - -const AVCodecTag * const ff_nut_codec_tags[] = { - ff_nut_video_tags, ff_nut_audio_tags, ff_nut_subtitle_tags, - ff_codec_bmp_tags, ff_codec_wav_tags, nut_audio_extra_tags, ff_nut_data_tags, 0 -}; - -void ff_nut_reset_ts(NUTContext *nut, AVRational time_base, int64_t val){ - int i; - for(i=0; iavf->nb_streams; i++){ - nut->stream[i].last_pts= av_rescale_rnd( - val, - time_base.num * (int64_t)nut->stream[i].time_base->den, - time_base.den * (int64_t)nut->stream[i].time_base->num, - AV_ROUND_DOWN); - } -} - -int64_t ff_lsb2full(StreamContext *stream, int64_t lsb){ - int64_t mask = (1ULL<msb_pts_shift)-1; - int64_t delta= stream->last_pts - mask/2; - return ((lsb - delta)&mask) + delta; -} - -int ff_nut_sp_pos_cmp(const Syncpoint *a, const Syncpoint *b){ - return ((a->pos - b->pos) >> 32) - ((b->pos - a->pos) >> 32); -} - -int ff_nut_sp_pts_cmp(const Syncpoint *a, const Syncpoint *b){ - return ((a->ts - b->ts) >> 32) - ((b->ts - a->ts) >> 32); -} - -void ff_nut_add_sp(NUTContext *nut, int64_t pos, int64_t back_ptr, int64_t ts){ - Syncpoint *sp= av_mallocz(sizeof(Syncpoint)); - struct AVTreeNode *node = av_tree_node_alloc(); - - nut->sp_count++; - - sp->pos= pos; - sp->back_ptr= back_ptr; - sp->ts= ts; - av_tree_insert(&nut->syncpoints, sp, (void *) ff_nut_sp_pos_cmp, &node); - if(node){ - av_free(sp); - av_free(node); - } -} - -static int enu_free(void *opaque, void *elem) -{ - av_free(elem); - return 0; -} - -void ff_nut_free_sp(NUTContext *nut) -{ - av_tree_enumerate(nut->syncpoints, NULL, NULL, enu_free); - av_tree_destroy(nut->syncpoints); -} - -const Dispositions ff_nut_dispositions[] = { - {"default" , AV_DISPOSITION_DEFAULT}, - {"dub" , AV_DISPOSITION_DUB}, - {"original" , AV_DISPOSITION_ORIGINAL}, - {"comment" , AV_DISPOSITION_COMMENT}, - {"lyrics" , AV_DISPOSITION_LYRICS}, - {"karaoke" , AV_DISPOSITION_KARAOKE}, - {"" , 0} -}; - -const AVMetadataConv ff_nut_metadata_conv[] = { - { "Author", "artist" }, - { "X-CreationTime", "date" }, - { "CreationTime", "date" }, - { "SourceFilename", "filename" }, - { "X-Language", "language" }, - { "X-Disposition", "disposition" }, - { "X-Replaces", "replaces" }, - { "X-Depends", "depends" }, - { "X-Uses", "uses" }, - { "X-UsesFont", "usesfont" }, - { 0 }, -}; diff --git a/ffmpeg1/libavformat/nut.h b/ffmpeg1/libavformat/nut.h deleted file mode 100644 index ab31c27..0000000 --- a/ffmpeg1/libavformat/nut.h +++ /dev/null @@ -1,133 +0,0 @@ -/* - * "NUT" Container Format (de)muxer - * Copyright (c) 2006 Michael Niedermayer - * - * 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 AVFORMAT_NUT_H -#define AVFORMAT_NUT_H - -//#include -//#include "libavutil/adler32.h" -//#include "libavcodec/mpegaudio.h" -#include "avformat.h" -#include "internal.h" -#include "metadata.h" - -#define MAIN_STARTCODE (0x7A561F5F04ADULL + (((uint64_t)('N'<<8) + 'M')<<48)) -#define STREAM_STARTCODE (0x11405BF2F9DBULL + (((uint64_t)('N'<<8) + 'S')<<48)) -#define SYNCPOINT_STARTCODE (0xE4ADEECA4569ULL + (((uint64_t)('N'<<8) + 'K')<<48)) -#define INDEX_STARTCODE (0xDD672F23E64EULL + (((uint64_t)('N'<<8) + 'X')<<48)) -#define INFO_STARTCODE (0xAB68B596BA78ULL + (((uint64_t)('N'<<8) + 'I')<<48)) - -#define ID_STRING "nut/multimedia container\0" - -#define MAX_DISTANCE (1024*32-1) - -typedef enum{ - FLAG_KEY = 1, /// maxlen) { - avio_r8(bc); - len--; - } - - if (maxlen) - string[FFMIN(len, maxlen - 1)] = 0; - - if (maxlen == len) - return -1; - else - return 0; -} - -static int64_t get_s(AVIOContext *bc) -{ - int64_t v = ffio_read_varlen(bc) + 1; - - if (v & 1) - return -(v >> 1); - else - return (v >> 1); -} - -static uint64_t get_fourcc(AVIOContext *bc) -{ - unsigned int len = ffio_read_varlen(bc); - - if (len == 2) - return avio_rl16(bc); - else if (len == 4) - return avio_rl32(bc); - else { - av_log(NULL, AV_LOG_ERROR, "Unsupported fourcc length %d\n", len); - return -1; - } -} - -#ifdef TRACE -static inline uint64_t get_v_trace(AVIOContext *bc, const char *file, - const char *func, int line) -{ - uint64_t v = ffio_read_varlen(bc); - - av_log(NULL, AV_LOG_DEBUG, "get_v %5"PRId64" / %"PRIX64" in %s %s:%d\n", - v, v, file, func, line); - return v; -} - -static inline int64_t get_s_trace(AVIOContext *bc, const char *file, - const char *func, int line) -{ - int64_t v = get_s(bc); - - av_log(NULL, AV_LOG_DEBUG, "get_s %5"PRId64" / %"PRIX64" in %s %s:%d\n", - v, v, file, func, line); - return v; -} - -static inline uint64_t get_4cc_trace(AVIOContext *bc, char *file, - char *func, int line) -{ - uint64_t v = get_fourcc(bc); - - av_log(NULL, AV_LOG_DEBUG, "get_fourcc %5"PRId64" / %"PRIX64" in %s %s:%d\n", - v, v, file, func, line); - return v; -} -#define ffio_read_varlen(bc) get_v_trace(bc, __FILE__, __PRETTY_FUNCTION__, __LINE__) -#define get_s(bc) get_s_trace(bc, __FILE__, __PRETTY_FUNCTION__, __LINE__) -#define get_fourcc(bc) get_4cc_trace(bc, __FILE__, __PRETTY_FUNCTION__, __LINE__) -#endif - -static int get_packetheader(NUTContext *nut, AVIOContext *bc, - int calculate_checksum, uint64_t startcode) -{ - int64_t size; -// start = avio_tell(bc) - 8; - - startcode = av_be2ne64(startcode); - startcode = ff_crc04C11DB7_update(0, (uint8_t*) &startcode, 8); - - ffio_init_checksum(bc, ff_crc04C11DB7_update, startcode); - size = ffio_read_varlen(bc); - if (size > 4096) - avio_rb32(bc); - if (ffio_get_checksum(bc) && size > 4096) - return -1; - - ffio_init_checksum(bc, calculate_checksum ? ff_crc04C11DB7_update : NULL, 0); - - return size; -} - -static uint64_t find_any_startcode(AVIOContext *bc, int64_t pos) -{ - uint64_t state = 0; - - if (pos >= 0) - /* Note, this may fail if the stream is not seekable, but that should - * not matter, as in this case we simply start where we currently are */ - avio_seek(bc, pos, SEEK_SET); - while (!url_feof(bc)) { - state = (state << 8) | avio_r8(bc); - if ((state >> 56) != 'N') - continue; - switch (state) { - case MAIN_STARTCODE: - case STREAM_STARTCODE: - case SYNCPOINT_STARTCODE: - case INFO_STARTCODE: - case INDEX_STARTCODE: - return state; - } - } - - return 0; -} - -/** - * Find the given startcode. - * @param code the startcode - * @param pos the start position of the search, or -1 if the current position - * @return the position of the startcode or -1 if not found - */ -static int64_t find_startcode(AVIOContext *bc, uint64_t code, int64_t pos) -{ - for (;;) { - uint64_t startcode = find_any_startcode(bc, pos); - if (startcode == code) - return avio_tell(bc) - 8; - else if (startcode == 0) - return -1; - pos = -1; - } -} - -static int nut_probe(AVProbeData *p) -{ - int i; - uint64_t code = 0; - - for (i = 0; i < p->buf_size; i++) { - code = (code << 8) | p->buf[i]; - if (code == MAIN_STARTCODE) - return AVPROBE_SCORE_MAX; - } - return 0; -} - -#define GET_V(dst, check) \ - do { \ - tmp = ffio_read_varlen(bc); \ - if (!(check)) { \ - av_log(s, AV_LOG_ERROR, "Error " #dst " is (%"PRId64")\n", tmp); \ - return -1; \ - } \ - dst = tmp; \ - } while (0) - -static int skip_reserved(AVIOContext *bc, int64_t pos) -{ - pos -= avio_tell(bc); - if (pos < 0) { - avio_seek(bc, pos, SEEK_CUR); - return -1; - } else { - while (pos--) - avio_r8(bc); - return 0; - } -} - -static int decode_main_header(NUTContext *nut) -{ - AVFormatContext *s = nut->avf; - AVIOContext *bc = s->pb; - uint64_t tmp, end; - unsigned int stream_count; - int i, j, count; - int tmp_stream, tmp_mul, tmp_pts, tmp_size, tmp_res, tmp_head_idx; - - end = get_packetheader(nut, bc, 1, MAIN_STARTCODE); - end += avio_tell(bc); - - GET_V(tmp, tmp >= 2 && tmp <= 3); - GET_V(stream_count, tmp > 0 && tmp <= NUT_MAX_STREAMS); - - nut->max_distance = ffio_read_varlen(bc); - if (nut->max_distance > 65536) { - av_log(s, AV_LOG_DEBUG, "max_distance %d\n", nut->max_distance); - nut->max_distance = 65536; - } - - GET_V(nut->time_base_count, tmp > 0 && tmp < INT_MAX / sizeof(AVRational)); - nut->time_base = av_malloc(nut->time_base_count * sizeof(AVRational)); - - for (i = 0; i < nut->time_base_count; i++) { - GET_V(nut->time_base[i].num, tmp > 0 && tmp < (1ULL << 31)); - GET_V(nut->time_base[i].den, tmp > 0 && tmp < (1ULL << 31)); - if (av_gcd(nut->time_base[i].num, nut->time_base[i].den) != 1) { - av_log(s, AV_LOG_ERROR, "time base invalid\n"); - return AVERROR_INVALIDDATA; - } - } - tmp_pts = 0; - tmp_mul = 1; - tmp_stream = 0; - tmp_head_idx = 0; - for (i = 0; i < 256;) { - int tmp_flags = ffio_read_varlen(bc); - int tmp_fields = ffio_read_varlen(bc); - - if (tmp_fields > 0) - tmp_pts = get_s(bc); - if (tmp_fields > 1) - tmp_mul = ffio_read_varlen(bc); - if (tmp_fields > 2) - tmp_stream = ffio_read_varlen(bc); - if (tmp_fields > 3) - tmp_size = ffio_read_varlen(bc); - else - tmp_size = 0; - if (tmp_fields > 4) - tmp_res = ffio_read_varlen(bc); - else - tmp_res = 0; - if (tmp_fields > 5) - count = ffio_read_varlen(bc); - else - count = tmp_mul - tmp_size; - if (tmp_fields > 6) - get_s(bc); - if (tmp_fields > 7) - tmp_head_idx = ffio_read_varlen(bc); - - while (tmp_fields-- > 8) - ffio_read_varlen(bc); - - if (count == 0 || i + count > 256) { - av_log(s, AV_LOG_ERROR, "illegal count %d at %d\n", count, i); - return AVERROR_INVALIDDATA; - } - if (tmp_stream >= stream_count) { - av_log(s, AV_LOG_ERROR, "illegal stream number\n"); - return AVERROR_INVALIDDATA; - } - - for (j = 0; j < count; j++, i++) { - if (i == 'N') { - nut->frame_code[i].flags = FLAG_INVALID; - j--; - continue; - } - nut->frame_code[i].flags = tmp_flags; - nut->frame_code[i].pts_delta = tmp_pts; - nut->frame_code[i].stream_id = tmp_stream; - nut->frame_code[i].size_mul = tmp_mul; - nut->frame_code[i].size_lsb = tmp_size + j; - nut->frame_code[i].reserved_count = tmp_res; - nut->frame_code[i].header_idx = tmp_head_idx; - } - } - av_assert0(nut->frame_code['N'].flags == FLAG_INVALID); - - if (end > avio_tell(bc) + 4) { - int rem = 1024; - GET_V(nut->header_count, tmp < 128U); - nut->header_count++; - for (i = 1; i < nut->header_count; i++) { - uint8_t *hdr; - GET_V(nut->header_len[i], tmp > 0 && tmp < 256); - rem -= nut->header_len[i]; - if (rem < 0) { - av_log(s, AV_LOG_ERROR, "invalid elision header\n"); - return AVERROR_INVALIDDATA; - } - hdr = av_malloc(nut->header_len[i]); - if (!hdr) - return AVERROR(ENOMEM); - avio_read(bc, hdr, nut->header_len[i]); - nut->header[i] = hdr; - } - av_assert0(nut->header_len[0] == 0); - } - - if (skip_reserved(bc, end) || ffio_get_checksum(bc)) { - av_log(s, AV_LOG_ERROR, "main header checksum mismatch\n"); - return AVERROR_INVALIDDATA; - } - - nut->stream = av_mallocz(sizeof(StreamContext) * stream_count); - for (i = 0; i < stream_count; i++) - avformat_new_stream(s, NULL); - - return 0; -} - -static int decode_stream_header(NUTContext *nut) -{ - AVFormatContext *s = nut->avf; - AVIOContext *bc = s->pb; - StreamContext *stc; - int class, stream_id; - uint64_t tmp, end; - AVStream *st; - - end = get_packetheader(nut, bc, 1, STREAM_STARTCODE); - end += avio_tell(bc); - - GET_V(stream_id, tmp < s->nb_streams && !nut->stream[tmp].time_base); - stc = &nut->stream[stream_id]; - st = s->streams[stream_id]; - if (!st) - return AVERROR(ENOMEM); - - class = ffio_read_varlen(bc); - tmp = get_fourcc(bc); - st->codec->codec_tag = tmp; - switch (class) { - case 0: - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = av_codec_get_id((const AVCodecTag * const []) { - ff_nut_video_tags, - ff_codec_bmp_tags, - 0 - }, - tmp); - break; - case 1: - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = av_codec_get_id((const AVCodecTag * const []) { - ff_nut_audio_tags, - ff_codec_wav_tags, - 0 - }, - tmp); - break; - case 2: - st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE; - st->codec->codec_id = ff_codec_get_id(ff_nut_subtitle_tags, tmp); - break; - case 3: - st->codec->codec_type = AVMEDIA_TYPE_DATA; - st->codec->codec_id = ff_codec_get_id(ff_nut_data_tags, tmp); - break; - default: - av_log(s, AV_LOG_ERROR, "unknown stream class (%d)\n", class); - return -1; - } - if (class < 3 && st->codec->codec_id == AV_CODEC_ID_NONE) - av_log(s, AV_LOG_ERROR, - "Unknown codec tag '0x%04x' for stream number %d\n", - (unsigned int) tmp, stream_id); - - GET_V(stc->time_base_id, tmp < nut->time_base_count); - GET_V(stc->msb_pts_shift, tmp < 16); - stc->max_pts_distance = ffio_read_varlen(bc); - GET_V(stc->decode_delay, tmp < 1000); // sanity limit, raise this if Moore's law is true - st->codec->has_b_frames = stc->decode_delay; - ffio_read_varlen(bc); // stream flags - - GET_V(st->codec->extradata_size, tmp < (1 << 30)); - if (st->codec->extradata_size) { - st->codec->extradata = av_mallocz(st->codec->extradata_size + - FF_INPUT_BUFFER_PADDING_SIZE); - avio_read(bc, st->codec->extradata, st->codec->extradata_size); - } - - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { - GET_V(st->codec->width, tmp > 0); - GET_V(st->codec->height, tmp > 0); - st->sample_aspect_ratio.num = ffio_read_varlen(bc); - st->sample_aspect_ratio.den = ffio_read_varlen(bc); - if ((!st->sample_aspect_ratio.num) != (!st->sample_aspect_ratio.den)) { - av_log(s, AV_LOG_ERROR, "invalid aspect ratio %d/%d\n", - st->sample_aspect_ratio.num, st->sample_aspect_ratio.den); - return -1; - } - ffio_read_varlen(bc); /* csp type */ - } else if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - GET_V(st->codec->sample_rate, tmp > 0); - ffio_read_varlen(bc); // samplerate_den - GET_V(st->codec->channels, tmp > 0); - } - if (skip_reserved(bc, end) || ffio_get_checksum(bc)) { - av_log(s, AV_LOG_ERROR, - "stream header %d checksum mismatch\n", stream_id); - return -1; - } - stc->time_base = &nut->time_base[stc->time_base_id]; - avpriv_set_pts_info(s->streams[stream_id], 63, stc->time_base->num, - stc->time_base->den); - return 0; -} - -static void set_disposition_bits(AVFormatContext *avf, char *value, - int stream_id) -{ - int flag = 0, i; - - for (i = 0; ff_nut_dispositions[i].flag; ++i) - if (!strcmp(ff_nut_dispositions[i].str, value)) - flag = ff_nut_dispositions[i].flag; - if (!flag) - av_log(avf, AV_LOG_INFO, "unknown disposition type '%s'\n", value); - for (i = 0; i < avf->nb_streams; ++i) - if (stream_id == i || stream_id == -1) - avf->streams[i]->disposition |= flag; -} - -static int decode_info_header(NUTContext *nut) -{ - AVFormatContext *s = nut->avf; - AVIOContext *bc = s->pb; - uint64_t tmp, chapter_start, chapter_len; - unsigned int stream_id_plus1, count; - int chapter_id, i; - int64_t value, end; - char name[256], str_value[1024], type_str[256]; - const char *type; - AVChapter *chapter = NULL; - AVStream *st = NULL; - AVDictionary **metadata = NULL; - - end = get_packetheader(nut, bc, 1, INFO_STARTCODE); - end += avio_tell(bc); - - GET_V(stream_id_plus1, tmp <= s->nb_streams); - chapter_id = get_s(bc); - chapter_start = ffio_read_varlen(bc); - chapter_len = ffio_read_varlen(bc); - count = ffio_read_varlen(bc); - - if (chapter_id && !stream_id_plus1) { - int64_t start = chapter_start / nut->time_base_count; - chapter = avpriv_new_chapter(s, chapter_id, - nut->time_base[chapter_start % - nut->time_base_count], - start, start + chapter_len, NULL); - metadata = &chapter->metadata; - } else if (stream_id_plus1) { - st = s->streams[stream_id_plus1 - 1]; - metadata = &st->metadata; - } else - metadata = &s->metadata; - - for (i = 0; i < count; i++) { - get_str(bc, name, sizeof(name)); - value = get_s(bc); - if (value == -1) { - type = "UTF-8"; - get_str(bc, str_value, sizeof(str_value)); - } else if (value == -2) { - get_str(bc, type_str, sizeof(type_str)); - type = type_str; - get_str(bc, str_value, sizeof(str_value)); - } else if (value == -3) { - type = "s"; - value = get_s(bc); - } else if (value == -4) { - type = "t"; - value = ffio_read_varlen(bc); - } else if (value < -4) { - type = "r"; - get_s(bc); - } else { - type = "v"; - } - - if (stream_id_plus1 > s->nb_streams) { - av_log(s, AV_LOG_ERROR, "invalid stream id for info packet\n"); - continue; - } - - if (!strcmp(type, "UTF-8")) { - if (chapter_id == 0 && !strcmp(name, "Disposition")) { - set_disposition_bits(s, str_value, stream_id_plus1 - 1); - continue; - } - - if (stream_id_plus1 && !strcmp(name, "r_frame_rate")) { - sscanf(str_value, "%d/%d", &st->r_frame_rate.num, &st->r_frame_rate.den); - if (st->r_frame_rate.num >= 1000LL*st->r_frame_rate.den) - st->r_frame_rate.num = st->r_frame_rate.den = 0; - continue; - } - - if (metadata && av_strcasecmp(name, "Uses") && - av_strcasecmp(name, "Depends") && av_strcasecmp(name, "Replaces")) - av_dict_set(metadata, name, str_value, 0); - } - } - - if (skip_reserved(bc, end) || ffio_get_checksum(bc)) { - av_log(s, AV_LOG_ERROR, "info header checksum mismatch\n"); - return -1; - } - return 0; -} - -static int decode_syncpoint(NUTContext *nut, int64_t *ts, int64_t *back_ptr) -{ - AVFormatContext *s = nut->avf; - AVIOContext *bc = s->pb; - int64_t end; - uint64_t tmp; - - nut->last_syncpoint_pos = avio_tell(bc) - 8; - - end = get_packetheader(nut, bc, 1, SYNCPOINT_STARTCODE); - end += avio_tell(bc); - - tmp = ffio_read_varlen(bc); - *back_ptr = nut->last_syncpoint_pos - 16 * ffio_read_varlen(bc); - if (*back_ptr < 0) - return AVERROR_INVALIDDATA; - - ff_nut_reset_ts(nut, nut->time_base[tmp % nut->time_base_count], - tmp / nut->time_base_count); - - if (skip_reserved(bc, end) || ffio_get_checksum(bc)) { - av_log(s, AV_LOG_ERROR, "sync point checksum mismatch\n"); - return AVERROR_INVALIDDATA; - } - - *ts = tmp / nut->time_base_count * - av_q2d(nut->time_base[tmp % nut->time_base_count]) * AV_TIME_BASE; - ff_nut_add_sp(nut, nut->last_syncpoint_pos, *back_ptr, *ts); - - return 0; -} - -//FIXME calculate exactly, this is just a good approximation. -static int64_t find_duration(NUTContext *nut, int64_t filesize) -{ - AVFormatContext *s = nut->avf; - int64_t duration = 0; - - int64_t pos = FFMAX(0, filesize - 2*nut->max_distance); - for(;;){ - int64_t ts = nut_read_timestamp(s, -1, &pos, INT64_MAX); - if(ts < 0) - break; - duration = FFMAX(duration, ts); - pos++; - } - if(duration > 0) - s->duration_estimation_method = AVFMT_DURATION_FROM_PTS; - return duration; -} - -static int find_and_decode_index(NUTContext *nut) -{ - AVFormatContext *s = nut->avf; - AVIOContext *bc = s->pb; - uint64_t tmp, end; - int i, j, syncpoint_count; - int64_t filesize = avio_size(bc); - int64_t *syncpoints; - int8_t *has_keyframe; - int ret = -1; - - if(filesize <= 0) - return -1; - - avio_seek(bc, filesize - 12, SEEK_SET); - avio_seek(bc, filesize - avio_rb64(bc), SEEK_SET); - if (avio_rb64(bc) != INDEX_STARTCODE) { - av_log(s, AV_LOG_ERROR, "no index at the end\n"); - - if(s->duration<=0) - s->duration = find_duration(nut, filesize); - return -1; - } - - end = get_packetheader(nut, bc, 1, INDEX_STARTCODE); - end += avio_tell(bc); - - ffio_read_varlen(bc); // max_pts - GET_V(syncpoint_count, tmp < INT_MAX / 8 && tmp > 0); - syncpoints = av_malloc(sizeof(int64_t) * syncpoint_count); - has_keyframe = av_malloc(sizeof(int8_t) * (syncpoint_count + 1)); - for (i = 0; i < syncpoint_count; i++) { - syncpoints[i] = ffio_read_varlen(bc); - if (syncpoints[i] <= 0) - goto fail; - if (i) - syncpoints[i] += syncpoints[i - 1]; - } - - for (i = 0; i < s->nb_streams; i++) { - int64_t last_pts = -1; - for (j = 0; j < syncpoint_count;) { - uint64_t x = ffio_read_varlen(bc); - int type = x & 1; - int n = j; - x >>= 1; - if (type) { - int flag = x & 1; - x >>= 1; - if (n + x >= syncpoint_count + 1) { - av_log(s, AV_LOG_ERROR, "index overflow A %d + %"PRIu64" >= %d\n", n, x, syncpoint_count + 1); - goto fail; - } - while (x--) - has_keyframe[n++] = flag; - has_keyframe[n++] = !flag; - } else { - while (x != 1) { - if (n >= syncpoint_count + 1) { - av_log(s, AV_LOG_ERROR, "index overflow B\n"); - goto fail; - } - has_keyframe[n++] = x & 1; - x >>= 1; - } - } - if (has_keyframe[0]) { - av_log(s, AV_LOG_ERROR, "keyframe before first syncpoint in index\n"); - goto fail; - } - av_assert0(n <= syncpoint_count + 1); - for (; j < n && j < syncpoint_count; j++) { - if (has_keyframe[j]) { - uint64_t B, A = ffio_read_varlen(bc); - if (!A) { - A = ffio_read_varlen(bc); - B = ffio_read_varlen(bc); - // eor_pts[j][i] = last_pts + A + B - } else - B = 0; - av_add_index_entry(s->streams[i], 16 * syncpoints[j - 1], - last_pts + A, 0, 0, AVINDEX_KEYFRAME); - last_pts += A + B; - } - } - } - } - - if (skip_reserved(bc, end) || ffio_get_checksum(bc)) { - av_log(s, AV_LOG_ERROR, "index checksum mismatch\n"); - goto fail; - } - ret = 0; - -fail: - av_free(syncpoints); - av_free(has_keyframe); - return ret; -} - -static int nut_read_header(AVFormatContext *s) -{ - NUTContext *nut = s->priv_data; - AVIOContext *bc = s->pb; - int64_t pos; - int initialized_stream_count; - - nut->avf = s; - - /* main header */ - pos = 0; - do { - pos = find_startcode(bc, MAIN_STARTCODE, pos) + 1; - if (pos < 0 + 1) { - av_log(s, AV_LOG_ERROR, "No main startcode found.\n"); - return AVERROR_INVALIDDATA; - } - } while (decode_main_header(nut) < 0); - - /* stream headers */ - pos = 0; - for (initialized_stream_count = 0; initialized_stream_count < s->nb_streams;) { - pos = find_startcode(bc, STREAM_STARTCODE, pos) + 1; - if (pos < 0 + 1) { - av_log(s, AV_LOG_ERROR, "Not all stream headers found.\n"); - return AVERROR_INVALIDDATA; - } - if (decode_stream_header(nut) >= 0) - initialized_stream_count++; - } - - /* info headers */ - pos = 0; - for (;;) { - uint64_t startcode = find_any_startcode(bc, pos); - pos = avio_tell(bc); - - if (startcode == 0) { - av_log(s, AV_LOG_ERROR, "EOF before video frames\n"); - return AVERROR_INVALIDDATA; - } else if (startcode == SYNCPOINT_STARTCODE) { - nut->next_startcode = startcode; - break; - } else if (startcode != INFO_STARTCODE) { - continue; - } - - decode_info_header(nut); - } - - s->data_offset = pos - 8; - - if (bc->seekable) { - int64_t orig_pos = avio_tell(bc); - find_and_decode_index(nut); - avio_seek(bc, orig_pos, SEEK_SET); - } - av_assert0(nut->next_startcode == SYNCPOINT_STARTCODE); - - ff_metadata_conv_ctx(s, NULL, ff_nut_metadata_conv); - - return 0; -} - -static int decode_frame_header(NUTContext *nut, int64_t *pts, int *stream_id, - uint8_t *header_idx, int frame_code) -{ - AVFormatContext *s = nut->avf; - AVIOContext *bc = s->pb; - StreamContext *stc; - int size, flags, size_mul, pts_delta, i, reserved_count; - uint64_t tmp; - - if (avio_tell(bc) > nut->last_syncpoint_pos + nut->max_distance) { - av_log(s, AV_LOG_ERROR, - "Last frame must have been damaged %"PRId64" > %"PRId64" + %d\n", - avio_tell(bc), nut->last_syncpoint_pos, nut->max_distance); - return AVERROR_INVALIDDATA; - } - - flags = nut->frame_code[frame_code].flags; - size_mul = nut->frame_code[frame_code].size_mul; - size = nut->frame_code[frame_code].size_lsb; - *stream_id = nut->frame_code[frame_code].stream_id; - pts_delta = nut->frame_code[frame_code].pts_delta; - reserved_count = nut->frame_code[frame_code].reserved_count; - *header_idx = nut->frame_code[frame_code].header_idx; - - if (flags & FLAG_INVALID) - return AVERROR_INVALIDDATA; - if (flags & FLAG_CODED) - flags ^= ffio_read_varlen(bc); - if (flags & FLAG_STREAM_ID) { - GET_V(*stream_id, tmp < s->nb_streams); - } - stc = &nut->stream[*stream_id]; - if (flags & FLAG_CODED_PTS) { - int coded_pts = ffio_read_varlen(bc); - // FIXME check last_pts validity? - if (coded_pts < (1 << stc->msb_pts_shift)) { - *pts = ff_lsb2full(stc, coded_pts); - } else - *pts = coded_pts - (1LL << stc->msb_pts_shift); - } else - *pts = stc->last_pts + pts_delta; - if (flags & FLAG_SIZE_MSB) - size += size_mul * ffio_read_varlen(bc); - if (flags & FLAG_MATCH_TIME) - get_s(bc); - if (flags & FLAG_HEADER_IDX) - *header_idx = ffio_read_varlen(bc); - if (flags & FLAG_RESERVED) - reserved_count = ffio_read_varlen(bc); - for (i = 0; i < reserved_count; i++) - ffio_read_varlen(bc); - - if (*header_idx >= (unsigned)nut->header_count) { - av_log(s, AV_LOG_ERROR, "header_idx invalid\n"); - return AVERROR_INVALIDDATA; - } - if (size > 4096) - *header_idx = 0; - size -= nut->header_len[*header_idx]; - - if (flags & FLAG_CHECKSUM) { - avio_rb32(bc); // FIXME check this - } else if (size > 2 * nut->max_distance || FFABS(stc->last_pts - *pts) > - stc->max_pts_distance) { - av_log(s, AV_LOG_ERROR, "frame size > 2max_distance and no checksum\n"); - return AVERROR_INVALIDDATA; - } - - stc->last_pts = *pts; - stc->last_flags = flags; - - return size; -} - -static int decode_frame(NUTContext *nut, AVPacket *pkt, int frame_code) -{ - AVFormatContext *s = nut->avf; - AVIOContext *bc = s->pb; - int size, stream_id, discard; - int64_t pts, last_IP_pts; - StreamContext *stc; - uint8_t header_idx; - - size = decode_frame_header(nut, &pts, &stream_id, &header_idx, frame_code); - if (size < 0) - return size; - - stc = &nut->stream[stream_id]; - - if (stc->last_flags & FLAG_KEY) - stc->skip_until_key_frame = 0; - - discard = s->streams[stream_id]->discard; - last_IP_pts = s->streams[stream_id]->last_IP_pts; - if ((discard >= AVDISCARD_NONKEY && !(stc->last_flags & FLAG_KEY)) || - (discard >= AVDISCARD_BIDIR && last_IP_pts != AV_NOPTS_VALUE && - last_IP_pts > pts) || - discard >= AVDISCARD_ALL || - stc->skip_until_key_frame) { - avio_skip(bc, size); - return 1; - } - - if (av_new_packet(pkt, size + nut->header_len[header_idx]) < 0) - return AVERROR(ENOMEM); - memcpy(pkt->data, nut->header[header_idx], nut->header_len[header_idx]); - pkt->pos = avio_tell(bc); // FIXME - avio_read(bc, pkt->data + nut->header_len[header_idx], size); - - pkt->stream_index = stream_id; - if (stc->last_flags & FLAG_KEY) - pkt->flags |= AV_PKT_FLAG_KEY; - pkt->pts = pts; - - return 0; -} - -static int nut_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - NUTContext *nut = s->priv_data; - AVIOContext *bc = s->pb; - int i, frame_code = 0, ret, skip; - int64_t ts, back_ptr; - - for (;;) { - int64_t pos = avio_tell(bc); - uint64_t tmp = nut->next_startcode; - nut->next_startcode = 0; - - if (tmp) { - pos -= 8; - } else { - frame_code = avio_r8(bc); - if (url_feof(bc)) - return -1; - if (frame_code == 'N') { - tmp = frame_code; - for (i = 1; i < 8; i++) - tmp = (tmp << 8) + avio_r8(bc); - } - } - switch (tmp) { - case MAIN_STARTCODE: - case STREAM_STARTCODE: - case INDEX_STARTCODE: - skip = get_packetheader(nut, bc, 0, tmp); - avio_skip(bc, skip); - break; - case INFO_STARTCODE: - if (decode_info_header(nut) < 0) - goto resync; - break; - case SYNCPOINT_STARTCODE: - if (decode_syncpoint(nut, &ts, &back_ptr) < 0) - goto resync; - frame_code = avio_r8(bc); - case 0: - ret = decode_frame(nut, pkt, frame_code); - if (ret == 0) - return 0; - else if (ret == 1) // OK but discard packet - break; - default: -resync: - av_log(s, AV_LOG_DEBUG, "syncing from %"PRId64"\n", pos); - tmp = find_any_startcode(bc, nut->last_syncpoint_pos + 1); - if (tmp == 0) - return AVERROR_INVALIDDATA; - av_log(s, AV_LOG_DEBUG, "sync\n"); - nut->next_startcode = tmp; - } - } -} - -static int64_t nut_read_timestamp(AVFormatContext *s, int stream_index, - int64_t *pos_arg, int64_t pos_limit) -{ - NUTContext *nut = s->priv_data; - AVIOContext *bc = s->pb; - int64_t pos, pts, back_ptr; - av_log(s, AV_LOG_DEBUG, "read_timestamp(X,%d,%"PRId64",%"PRId64")\n", - stream_index, *pos_arg, pos_limit); - - pos = *pos_arg; - do { - pos = find_startcode(bc, SYNCPOINT_STARTCODE, pos) + 1; - if (pos < 1) { - av_log(s, AV_LOG_ERROR, "read_timestamp failed.\n"); - return AV_NOPTS_VALUE; - } - } while (decode_syncpoint(nut, &pts, &back_ptr) < 0); - *pos_arg = pos - 1; - av_assert0(nut->last_syncpoint_pos == *pos_arg); - - av_log(s, AV_LOG_DEBUG, "return %"PRId64" %"PRId64"\n", pts, back_ptr); - if (stream_index == -2) - return back_ptr; - av_assert0(stream_index == -1); - return pts; -} - -static int read_seek(AVFormatContext *s, int stream_index, - int64_t pts, int flags) -{ - NUTContext *nut = s->priv_data; - AVStream *st = s->streams[stream_index]; - Syncpoint dummy = { .ts = pts * av_q2d(st->time_base) * AV_TIME_BASE }; - Syncpoint nopts_sp = { .ts = AV_NOPTS_VALUE, .back_ptr = AV_NOPTS_VALUE }; - Syncpoint *sp, *next_node[2] = { &nopts_sp, &nopts_sp }; - int64_t pos, pos2, ts; - int i; - - if (st->index_entries) { - int index = av_index_search_timestamp(st, pts, flags); - if (index < 0) - index = av_index_search_timestamp(st, pts, flags ^ AVSEEK_FLAG_BACKWARD); - if (index < 0) - return -1; - - pos2 = st->index_entries[index].pos; - ts = st->index_entries[index].timestamp; - } else { - av_tree_find(nut->syncpoints, &dummy, (void *) ff_nut_sp_pts_cmp, - (void **) next_node); - av_log(s, AV_LOG_DEBUG, "%"PRIu64"-%"PRIu64" %"PRId64"-%"PRId64"\n", - next_node[0]->pos, next_node[1]->pos, next_node[0]->ts, - next_node[1]->ts); - pos = ff_gen_search(s, -1, dummy.ts, next_node[0]->pos, - next_node[1]->pos, next_node[1]->pos, - next_node[0]->ts, next_node[1]->ts, - AVSEEK_FLAG_BACKWARD, &ts, nut_read_timestamp); - - if (!(flags & AVSEEK_FLAG_BACKWARD)) { - dummy.pos = pos + 16; - next_node[1] = &nopts_sp; - av_tree_find(nut->syncpoints, &dummy, (void *) ff_nut_sp_pos_cmp, - (void **) next_node); - pos2 = ff_gen_search(s, -2, dummy.pos, next_node[0]->pos, - next_node[1]->pos, next_node[1]->pos, - next_node[0]->back_ptr, next_node[1]->back_ptr, - flags, &ts, nut_read_timestamp); - if (pos2 >= 0) - pos = pos2; - // FIXME dir but I think it does not matter - } - dummy.pos = pos; - sp = av_tree_find(nut->syncpoints, &dummy, (void *) ff_nut_sp_pos_cmp, - NULL); - - av_assert0(sp); - pos2 = sp->back_ptr - 15; - } - av_log(NULL, AV_LOG_DEBUG, "SEEKTO: %"PRId64"\n", pos2); - pos = find_startcode(s->pb, SYNCPOINT_STARTCODE, pos2); - avio_seek(s->pb, pos, SEEK_SET); - av_log(NULL, AV_LOG_DEBUG, "SP: %"PRId64"\n", pos); - if (pos2 > pos || pos2 + 15 < pos) - av_log(NULL, AV_LOG_ERROR, "no syncpoint at backptr pos\n"); - for (i = 0; i < s->nb_streams; i++) - nut->stream[i].skip_until_key_frame = 1; - - return 0; -} - -static int nut_read_close(AVFormatContext *s) -{ - NUTContext *nut = s->priv_data; - int i; - - av_freep(&nut->time_base); - av_freep(&nut->stream); - ff_nut_free_sp(nut); - for (i = 1; i < nut->header_count; i++) - av_freep(&nut->header[i]); - - return 0; -} - -AVInputFormat ff_nut_demuxer = { - .name = "nut", - .long_name = NULL_IF_CONFIG_SMALL("NUT"), - .flags = AVFMT_SEEK_TO_PTS, - .priv_data_size = sizeof(NUTContext), - .read_probe = nut_probe, - .read_header = nut_read_header, - .read_packet = nut_read_packet, - .read_close = nut_read_close, - .read_seek = read_seek, - .extensions = "nut", - .codec_tag = ff_nut_codec_tags, -}; diff --git a/ffmpeg1/libavformat/nutenc.c b/ffmpeg1/libavformat/nutenc.c deleted file mode 100644 index 2d8d265..0000000 --- a/ffmpeg1/libavformat/nutenc.c +++ /dev/null @@ -1,1023 +0,0 @@ -/* - * nut muxer - * Copyright (c) 2004-2007 Michael Niedermayer - * - * 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 "libavutil/intreadwrite.h" -#include "libavutil/mathematics.h" -#include "libavutil/tree.h" -#include "libavutil/dict.h" -#include "libavutil/avassert.h" -#include "libavcodec/mpegaudiodata.h" -#include "nut.h" -#include "internal.h" -#include "avio_internal.h" -#include "riff.h" - -static int find_expected_header(AVCodecContext *c, int size, int key_frame, - uint8_t out[64]) -{ - int sample_rate = c->sample_rate; - - if (size > 4096) - return 0; - - AV_WB24(out, 1); - - if (c->codec_id == AV_CODEC_ID_MPEG4) { - if (key_frame) { - return 3; - } else { - out[3] = 0xB6; - return 4; - } - } else if (c->codec_id == AV_CODEC_ID_MPEG1VIDEO || - c->codec_id == AV_CODEC_ID_MPEG2VIDEO) { - return 3; - } else if (c->codec_id == AV_CODEC_ID_H264) { - return 3; - } else if (c->codec_id == AV_CODEC_ID_MP3 || - c->codec_id == AV_CODEC_ID_MP2) { - int lsf, mpeg25, sample_rate_index, bitrate_index, frame_size; - int layer = c->codec_id == AV_CODEC_ID_MP3 ? 3 : 2; - unsigned int header = 0xFFF00000; - - lsf = sample_rate < (24000 + 32000) / 2; - mpeg25 = sample_rate < (12000 + 16000) / 2; - sample_rate <<= lsf + mpeg25; - if (sample_rate < (32000 + 44100) / 2) sample_rate_index = 2; - else if (sample_rate < (44100 + 48000) / 2) sample_rate_index = 0; - else sample_rate_index = 1; - - sample_rate = avpriv_mpa_freq_tab[sample_rate_index] >> (lsf + mpeg25); - - for (bitrate_index = 2; bitrate_index < 30; bitrate_index++) { - frame_size = - avpriv_mpa_bitrate_tab[lsf][layer - 1][bitrate_index >> 1]; - frame_size = (frame_size * 144000) / (sample_rate << lsf) + - (bitrate_index & 1); - - if (frame_size == size) - break; - } - - header |= (!lsf) << 19; - header |= (4 - layer) << 17; - header |= 1 << 16; //no crc - AV_WB32(out, header); - if (size <= 0) - return 2; //we guess there is no crc, if there is one the user clearly does not care about overhead - if (bitrate_index == 30) - return -1; //something is wrong ... - - header |= (bitrate_index >> 1) << 12; - header |= sample_rate_index << 10; - header |= (bitrate_index & 1) << 9; - - return 2; //FIXME actually put the needed ones in build_elision_headers() - return 3; //we guess that the private bit is not set -//FIXME the above assumptions should be checked, if these turn out false too often something should be done - } - return 0; -} - -static int find_header_idx(AVFormatContext *s, AVCodecContext *c, int size, int frame_type) -{ - NUTContext *nut = s->priv_data; - uint8_t out[64]; - int i; - int len = find_expected_header(c, size, frame_type, out); - - for (i = 1; i < nut->header_count; i++) { - if (len == nut->header_len[i] && !memcmp(out, nut->header[i], len)) { - return i; - } - } - - return 0; -} - -static void build_elision_headers(AVFormatContext *s) -{ - NUTContext *nut = s->priv_data; - int i; - //FIXME this is lame - //FIXME write a 2pass mode to find the maximal headers - static const uint8_t headers[][5] = { - { 3, 0x00, 0x00, 0x01 }, - { 4, 0x00, 0x00, 0x01, 0xB6}, - { 2, 0xFF, 0xFA }, //mp3+crc - { 2, 0xFF, 0xFB }, //mp3 - { 2, 0xFF, 0xFC }, //mp2+crc - { 2, 0xFF, 0xFD }, //mp2 - }; - - nut->header_count = 7; - for (i = 1; i < nut->header_count; i++) { - nut->header_len[i] = headers[i - 1][0]; - nut->header[i] = &headers[i - 1][1]; - } -} - -static void build_frame_code(AVFormatContext *s) -{ - NUTContext *nut = s->priv_data; - int key_frame, index, pred, stream_id; - int start = 1; - int end = 254; - int keyframe_0_esc = s->nb_streams > 2; - int pred_table[10]; - FrameCode *ft; - - ft = &nut->frame_code[start]; - ft->flags = FLAG_CODED; - ft->size_mul = 1; - ft->pts_delta = 1; - start++; - - if (keyframe_0_esc) { - /* keyframe = 0 escape */ - FrameCode *ft = &nut->frame_code[start]; - ft->flags = FLAG_STREAM_ID | FLAG_SIZE_MSB | FLAG_CODED_PTS; - ft->size_mul = 1; - start++; - } - - for (stream_id = 0; stream_id < s->nb_streams; stream_id++) { - int start2 = start + (end - start) * stream_id / s->nb_streams; - int end2 = start + (end - start) * (stream_id + 1) / s->nb_streams; - AVCodecContext *codec = s->streams[stream_id]->codec; - int is_audio = codec->codec_type == AVMEDIA_TYPE_AUDIO; - int intra_only = /*codec->intra_only || */ is_audio; - int pred_count; - int frame_size = 0; - - if (codec->codec_type == AVMEDIA_TYPE_AUDIO) { - frame_size = av_get_audio_frame_duration(codec, 0); - if (codec->codec_id == AV_CODEC_ID_VORBIS && !frame_size) - frame_size = 64; - } else { - AVRational f = av_div_q(codec->time_base, *nut->stream[stream_id].time_base); - if (f.den == 1 && f.num>0) - frame_size = f.num; - } - if (!frame_size) - frame_size = 1; - - for (key_frame = 0; key_frame < 2; key_frame++) { - if (!intra_only || !keyframe_0_esc || key_frame != 0) { - FrameCode *ft = &nut->frame_code[start2]; - ft->flags = FLAG_KEY * key_frame; - ft->flags |= FLAG_SIZE_MSB | FLAG_CODED_PTS; - ft->stream_id = stream_id; - ft->size_mul = 1; - if (is_audio) - ft->header_idx = find_header_idx(s, codec, -1, key_frame); - start2++; - } - } - - key_frame = intra_only; -#if 1 - if (is_audio) { - int frame_bytes = codec->frame_size * (int64_t)codec->bit_rate / - (8 * codec->sample_rate); - int pts; - for (pts = 0; pts < 2; pts++) { - for (pred = 0; pred < 2; pred++) { - FrameCode *ft = &nut->frame_code[start2]; - ft->flags = FLAG_KEY * key_frame; - ft->stream_id = stream_id; - ft->size_mul = frame_bytes + 2; - ft->size_lsb = frame_bytes + pred; - ft->pts_delta = pts * frame_size; - ft->header_idx = find_header_idx(s, codec, frame_bytes + pred, key_frame); - start2++; - } - } - } else { - FrameCode *ft = &nut->frame_code[start2]; - ft->flags = FLAG_KEY | FLAG_SIZE_MSB; - ft->stream_id = stream_id; - ft->size_mul = 1; - ft->pts_delta = frame_size; - start2++; - } -#endif - - if (codec->has_b_frames) { - pred_count = 5; - pred_table[0] = -2; - pred_table[1] = -1; - pred_table[2] = 1; - pred_table[3] = 3; - pred_table[4] = 4; - } else if (codec->codec_id == AV_CODEC_ID_VORBIS) { - pred_count = 3; - pred_table[0] = 2; - pred_table[1] = 9; - pred_table[2] = 16; - } else { - pred_count = 1; - pred_table[0] = 1; - } - - for (pred = 0; pred < pred_count; pred++) { - int start3 = start2 + (end2 - start2) * pred / pred_count; - int end3 = start2 + (end2 - start2) * (pred + 1) / pred_count; - - pred_table[pred] *= frame_size; - - for (index = start3; index < end3; index++) { - FrameCode *ft = &nut->frame_code[index]; - ft->flags = FLAG_KEY * key_frame; - ft->flags |= FLAG_SIZE_MSB; - ft->stream_id = stream_id; -//FIXME use single byte size and pred from last - ft->size_mul = end3 - start3; - ft->size_lsb = index - start3; - ft->pts_delta = pred_table[pred]; - if (is_audio) - ft->header_idx = find_header_idx(s, codec, -1, key_frame); - } - } - } - memmove(&nut->frame_code['N' + 1], &nut->frame_code['N'], sizeof(FrameCode) * (255 - 'N')); - nut->frame_code[0].flags = - nut->frame_code[255].flags = - nut->frame_code['N'].flags = FLAG_INVALID; -} - -static void put_tt(NUTContext *nut, AVRational *time_base, AVIOContext *bc, uint64_t val) -{ - val *= nut->time_base_count; - val += time_base - nut->time_base; - ff_put_v(bc, val); -} -/** - * Store a string as vb. - */ -static void put_str(AVIOContext *bc, const char *string) -{ - int len = strlen(string); - - ff_put_v(bc, len); - avio_write(bc, string, len); -} - -static void put_s(AVIOContext *bc, int64_t val) -{ - ff_put_v(bc, 2 * FFABS(val) - (val > 0)); -} - -#ifdef TRACE -static inline void ff_put_v_trace(AVIOContext *bc, uint64_t v, const char *file, - const char *func, int line) -{ - av_log(NULL, AV_LOG_DEBUG, "ff_put_v %5"PRId64" / %"PRIX64" in %s %s:%d\n", v, v, file, func, line); - - ff_put_v(bc, v); -} - -static inline void put_s_trace(AVIOContext *bc, int64_t v, const char *file, const char *func, int line) -{ - av_log(NULL, AV_LOG_DEBUG, "put_s %5"PRId64" / %"PRIX64" in %s %s:%d\n", v, v, file, func, line); - - put_s(bc, v); -} -#define ff_put_v(bc, v) ff_put_v_trace(bc, v, __FILE__, __PRETTY_FUNCTION__, __LINE__) -#define put_s(bc, v) put_s_trace(bc, v, __FILE__, __PRETTY_FUNCTION__, __LINE__) -#endif - -//FIXME remove calculate_checksum -static void put_packet(NUTContext *nut, AVIOContext *bc, AVIOContext *dyn_bc, - int calculate_checksum, uint64_t startcode) -{ - uint8_t *dyn_buf = NULL; - int dyn_size = avio_close_dyn_buf(dyn_bc, &dyn_buf); - int forw_ptr = dyn_size + 4 * calculate_checksum; - - if (forw_ptr > 4096) - ffio_init_checksum(bc, ff_crc04C11DB7_update, 0); - avio_wb64(bc, startcode); - ff_put_v(bc, forw_ptr); - if (forw_ptr > 4096) - avio_wl32(bc, ffio_get_checksum(bc)); - - if (calculate_checksum) - ffio_init_checksum(bc, ff_crc04C11DB7_update, 0); - avio_write(bc, dyn_buf, dyn_size); - if (calculate_checksum) - avio_wl32(bc, ffio_get_checksum(bc)); - - av_free(dyn_buf); -} - -static void write_mainheader(NUTContext *nut, AVIOContext *bc) -{ - int i, j, tmp_pts, tmp_flags, tmp_stream, tmp_mul, tmp_size, tmp_fields, - tmp_head_idx; - int64_t tmp_match; - - ff_put_v(bc, 3); /* version */ - ff_put_v(bc, nut->avf->nb_streams); - ff_put_v(bc, nut->max_distance); - ff_put_v(bc, nut->time_base_count); - - for (i = 0; i < nut->time_base_count; i++) { - ff_put_v(bc, nut->time_base[i].num); - ff_put_v(bc, nut->time_base[i].den); - } - - tmp_pts = 0; - tmp_mul = 1; - tmp_stream = 0; - tmp_match = 1 - (1LL << 62); - tmp_head_idx = 0; - for (i = 0; i < 256; ) { - tmp_fields = 0; - tmp_size = 0; -// tmp_res=0; - if (tmp_pts != nut->frame_code[i].pts_delta ) tmp_fields = 1; - if (tmp_mul != nut->frame_code[i].size_mul ) tmp_fields = 2; - if (tmp_stream != nut->frame_code[i].stream_id ) tmp_fields = 3; - if (tmp_size != nut->frame_code[i].size_lsb ) tmp_fields = 4; -// if (tmp_res != nut->frame_code[i].res ) tmp_fields=5; - if (tmp_head_idx != nut->frame_code[i].header_idx) tmp_fields = 8; - - tmp_pts = nut->frame_code[i].pts_delta; - tmp_flags = nut->frame_code[i].flags; - tmp_stream = nut->frame_code[i].stream_id; - tmp_mul = nut->frame_code[i].size_mul; - tmp_size = nut->frame_code[i].size_lsb; -// tmp_res = nut->frame_code[i].res; - tmp_head_idx = nut->frame_code[i].header_idx; - - for (j = 0; i < 256; j++, i++) { - if (i == 'N') { - j--; - continue; - } - if (nut->frame_code[i].pts_delta != tmp_pts || - nut->frame_code[i].flags != tmp_flags || - nut->frame_code[i].stream_id != tmp_stream || - nut->frame_code[i].size_mul != tmp_mul || - nut->frame_code[i].size_lsb != tmp_size + j || -// nut->frame_code[i].res != tmp_res || - nut->frame_code[i].header_idx != tmp_head_idx) - break; - } - if (j != tmp_mul - tmp_size) - tmp_fields = 6; - - ff_put_v(bc, tmp_flags); - ff_put_v(bc, tmp_fields); - if (tmp_fields > 0) put_s(bc, tmp_pts); - if (tmp_fields > 1) ff_put_v(bc, tmp_mul); - if (tmp_fields > 2) ff_put_v(bc, tmp_stream); - if (tmp_fields > 3) ff_put_v(bc, tmp_size); - if (tmp_fields > 4) ff_put_v(bc, 0 /*tmp_res*/); - if (tmp_fields > 5) ff_put_v(bc, j); - if (tmp_fields > 6) ff_put_v(bc, tmp_match); - if (tmp_fields > 7) ff_put_v(bc, tmp_head_idx); - } - ff_put_v(bc, nut->header_count - 1); - for (i = 1; i < nut->header_count; i++) { - ff_put_v(bc, nut->header_len[i]); - avio_write(bc, nut->header[i], nut->header_len[i]); - } -} - -static int write_streamheader(AVFormatContext *avctx, AVIOContext *bc, - AVStream *st, int i) -{ - NUTContext *nut = avctx->priv_data; - AVCodecContext *codec = st->codec; - - ff_put_v(bc, i); - switch (codec->codec_type) { - case AVMEDIA_TYPE_VIDEO: ff_put_v(bc, 0); break; - case AVMEDIA_TYPE_AUDIO: ff_put_v(bc, 1); break; - case AVMEDIA_TYPE_SUBTITLE: ff_put_v(bc, 2); break; - default: ff_put_v(bc, 3); break; - } - ff_put_v(bc, 4); - if (codec->codec_tag) { - avio_wl32(bc, codec->codec_tag); - } else { - av_log(avctx, AV_LOG_ERROR, "No codec tag defined for stream %d\n", i); - return AVERROR(EINVAL); - } - - ff_put_v(bc, nut->stream[i].time_base - nut->time_base); - ff_put_v(bc, nut->stream[i].msb_pts_shift); - ff_put_v(bc, nut->stream[i].max_pts_distance); - ff_put_v(bc, codec->has_b_frames); - avio_w8(bc, 0); /* flags: 0x1 - fixed_fps, 0x2 - index_present */ - - ff_put_v(bc, codec->extradata_size); - avio_write(bc, codec->extradata, codec->extradata_size); - - switch (codec->codec_type) { - case AVMEDIA_TYPE_AUDIO: - ff_put_v(bc, codec->sample_rate); - ff_put_v(bc, 1); - ff_put_v(bc, codec->channels); - break; - case AVMEDIA_TYPE_VIDEO: - ff_put_v(bc, codec->width); - ff_put_v(bc, codec->height); - - if (st->sample_aspect_ratio.num <= 0 || - st->sample_aspect_ratio.den <= 0) { - ff_put_v(bc, 0); - ff_put_v(bc, 0); - } else { - ff_put_v(bc, st->sample_aspect_ratio.num); - ff_put_v(bc, st->sample_aspect_ratio.den); - } - ff_put_v(bc, 0); /* csp type -- unknown */ - break; - default: - break; - } - return 0; -} - -static int add_info(AVIOContext *bc, const char *type, const char *value) -{ - put_str(bc, type); - put_s(bc, -1); - put_str(bc, value); - return 1; -} - -static int write_globalinfo(NUTContext *nut, AVIOContext *bc) -{ - AVFormatContext *s = nut->avf; - AVDictionaryEntry *t = NULL; - AVIOContext *dyn_bc; - uint8_t *dyn_buf = NULL; - int count = 0, dyn_size; - int ret = avio_open_dyn_buf(&dyn_bc); - if (ret < 0) - return ret; - - while ((t = av_dict_get(s->metadata, "", t, AV_DICT_IGNORE_SUFFIX))) - count += add_info(dyn_bc, t->key, t->value); - - ff_put_v(bc, 0); //stream_if_plus1 - ff_put_v(bc, 0); //chapter_id - ff_put_v(bc, 0); //timestamp_start - ff_put_v(bc, 0); //length - - ff_put_v(bc, count); - - dyn_size = avio_close_dyn_buf(dyn_bc, &dyn_buf); - avio_write(bc, dyn_buf, dyn_size); - av_free(dyn_buf); - return 0; -} - -static int write_streaminfo(NUTContext *nut, AVIOContext *bc, int stream_id) { - AVFormatContext *s= nut->avf; - AVStream* st = s->streams[stream_id]; - AVDictionaryEntry *t = NULL; - AVIOContext *dyn_bc; - uint8_t *dyn_buf=NULL; - int count=0, dyn_size, i; - int ret = avio_open_dyn_buf(&dyn_bc); - if (ret < 0) - return ret; - - while ((t = av_dict_get(st->metadata, "", t, AV_DICT_IGNORE_SUFFIX))) - count += add_info(dyn_bc, t->key, t->value); - for (i=0; ff_nut_dispositions[i].flag; ++i) { - if (st->disposition & ff_nut_dispositions[i].flag) - count += add_info(dyn_bc, "Disposition", ff_nut_dispositions[i].str); - } - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { - uint8_t buf[256]; - snprintf(buf, sizeof(buf), "%d/%d", st->codec->time_base.den, st->codec->time_base.num); - count += add_info(dyn_bc, "r_frame_rate", buf); - } - dyn_size = avio_close_dyn_buf(dyn_bc, &dyn_buf); - - if (count) { - ff_put_v(bc, stream_id + 1); //stream_id_plus1 - ff_put_v(bc, 0); //chapter_id - ff_put_v(bc, 0); //timestamp_start - ff_put_v(bc, 0); //length - - ff_put_v(bc, count); - - avio_write(bc, dyn_buf, dyn_size); - } - - av_free(dyn_buf); - return count; -} - -static int write_chapter(NUTContext *nut, AVIOContext *bc, int id) -{ - AVIOContext *dyn_bc; - uint8_t *dyn_buf = NULL; - AVDictionaryEntry *t = NULL; - AVChapter *ch = nut->avf->chapters[id]; - int ret, dyn_size, count = 0; - - ret = avio_open_dyn_buf(&dyn_bc); - if (ret < 0) - return ret; - - ff_put_v(bc, 0); // stream_id_plus1 - put_s(bc, id + 1); // chapter_id - put_tt(nut, nut->chapter[id].time_base, bc, ch->start); // chapter_start - ff_put_v(bc, ch->end - ch->start); // chapter_len - - while ((t = av_dict_get(ch->metadata, "", t, AV_DICT_IGNORE_SUFFIX))) - count += add_info(dyn_bc, t->key, t->value); - - ff_put_v(bc, count); - - dyn_size = avio_close_dyn_buf(dyn_bc, &dyn_buf); - avio_write(bc, dyn_buf, dyn_size); - av_freep(&dyn_buf); - return 0; -} - -static int write_index(NUTContext *nut, AVIOContext *bc) { - int i; - Syncpoint dummy= { .pos= 0 }; - Syncpoint *next_node[2] = { NULL }; - int64_t startpos = avio_tell(bc); - int64_t payload_size; - - put_tt(nut, nut->max_pts_tb, bc, nut->max_pts); - - ff_put_v(bc, nut->sp_count); - - for (i=0; isp_count; i++) { - av_tree_find(nut->syncpoints, &dummy, (void *) ff_nut_sp_pos_cmp, (void**)next_node); - ff_put_v(bc, (next_node[1]->pos >> 4) - (dummy.pos>>4)); - dummy.pos = next_node[1]->pos; - } - - for (i=0; iavf->nb_streams; i++) { - StreamContext *nus= &nut->stream[i]; - int64_t last_pts= -1; - int j, k; - for (j=0; jsp_count; j++) { - int flag = (nus->keyframe_pts[j] != AV_NOPTS_VALUE) ^ (j+1 == nut->sp_count); - int n = 0; - for (; jsp_count && (nus->keyframe_pts[j] != AV_NOPTS_VALUE) == flag; j++) - n++; - - ff_put_v(bc, 1 + 2*flag + 4*n); - for (k= j - n; k<=j && ksp_count; k++) { - if (nus->keyframe_pts[k] == AV_NOPTS_VALUE) - continue; - av_assert0(nus->keyframe_pts[k] > last_pts); - ff_put_v(bc, nus->keyframe_pts[k] - last_pts); - last_pts = nus->keyframe_pts[k]; - } - } - } - - payload_size = avio_tell(bc) - startpos + 8 + 4; - - avio_wb64(bc, 8 + payload_size + av_log2(payload_size) / 7 + 1 + 4*(payload_size > 4096)); - - return 0; -} - -static int write_headers(AVFormatContext *avctx, AVIOContext *bc) -{ - NUTContext *nut = avctx->priv_data; - AVIOContext *dyn_bc; - int i, ret; - - ff_metadata_conv_ctx(avctx, ff_nut_metadata_conv, NULL); - - ret = avio_open_dyn_buf(&dyn_bc); - if (ret < 0) - return ret; - write_mainheader(nut, dyn_bc); - put_packet(nut, bc, dyn_bc, 1, MAIN_STARTCODE); - - for (i = 0; i < nut->avf->nb_streams; i++) { - ret = avio_open_dyn_buf(&dyn_bc); - if (ret < 0) - return ret; - ret = write_streamheader(avctx, dyn_bc, nut->avf->streams[i], i); - if (ret < 0) - return ret; - put_packet(nut, bc, dyn_bc, 1, STREAM_STARTCODE); - } - - ret = avio_open_dyn_buf(&dyn_bc); - if (ret < 0) - return ret; - write_globalinfo(nut, dyn_bc); - put_packet(nut, bc, dyn_bc, 1, INFO_STARTCODE); - - for (i = 0; i < nut->avf->nb_streams; i++) { - ret = avio_open_dyn_buf(&dyn_bc); - if (ret < 0) - return ret; - ret = write_streaminfo(nut, dyn_bc, i); - if (ret < 0) - return ret; - if (ret > 0) - put_packet(nut, bc, dyn_bc, 1, INFO_STARTCODE); - else { - uint8_t *buf; - avio_close_dyn_buf(dyn_bc, &buf); - av_free(buf); - } - } - - for (i = 0; i < nut->avf->nb_chapters; i++) { - ret = avio_open_dyn_buf(&dyn_bc); - if (ret < 0) - return ret; - ret = write_chapter(nut, dyn_bc, i); - if (ret < 0) { - uint8_t *buf; - avio_close_dyn_buf(dyn_bc, &buf); - av_freep(&buf); - return ret; - } - put_packet(nut, bc, dyn_bc, 1, INFO_STARTCODE); - } - - nut->last_syncpoint_pos = INT_MIN; - nut->header_count++; - return 0; -} - -static int nut_write_header(AVFormatContext *s) -{ - NUTContext *nut = s->priv_data; - AVIOContext *bc = s->pb; - int i, j, ret; - - nut->avf = s; - - nut->stream = av_mallocz(sizeof(StreamContext ) * s->nb_streams); - nut->chapter = av_mallocz(sizeof(ChapterContext) * s->nb_chapters); - nut->time_base= av_mallocz(sizeof(AVRational ) *(s->nb_streams + - s->nb_chapters)); - if (!nut->stream || !nut->chapter || !nut->time_base) { - av_freep(&nut->stream); - av_freep(&nut->chapter); - av_freep(&nut->time_base); - return AVERROR(ENOMEM); - } - - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - int ssize; - AVRational time_base; - ff_parse_specific_params(st->codec, &time_base.den, &ssize, &time_base.num); - - if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && st->codec->sample_rate) { - time_base = (AVRational) {1, st->codec->sample_rate}; - } else { - time_base = ff_choose_timebase(s, st, 48000); - } - - avpriv_set_pts_info(st, 64, time_base.num, time_base.den); - - for (j = 0; j < nut->time_base_count; j++) - if (!memcmp(&time_base, &nut->time_base[j], sizeof(AVRational))) { - break; - } - nut->time_base[j] = time_base; - nut->stream[i].time_base = &nut->time_base[j]; - if (j == nut->time_base_count) - nut->time_base_count++; - - if (INT64_C(1000) * time_base.num >= time_base.den) - nut->stream[i].msb_pts_shift = 7; - else - nut->stream[i].msb_pts_shift = 14; - nut->stream[i].max_pts_distance = - FFMAX(time_base.den, time_base.num) / time_base.num; - } - - for (i = 0; i < s->nb_chapters; i++) { - AVChapter *ch = s->chapters[i]; - - for (j = 0; j < nut->time_base_count; j++) - if (!memcmp(&ch->time_base, &nut->time_base[j], sizeof(AVRational))) - break; - - nut->time_base[j] = ch->time_base; - nut->chapter[i].time_base = &nut->time_base[j]; - if (j == nut->time_base_count) - nut->time_base_count++; - } - - nut->max_distance = MAX_DISTANCE; - build_elision_headers(s); - build_frame_code(s); - av_assert0(nut->frame_code['N'].flags == FLAG_INVALID); - - avio_write(bc, ID_STRING, strlen(ID_STRING)); - avio_w8(bc, 0); - - if ((ret = write_headers(s, bc)) < 0) - return ret; - - if (s->avoid_negative_ts < 0) - s->avoid_negative_ts = 1; - - avio_flush(bc); - - return 0; -} - -static int get_needed_flags(NUTContext *nut, StreamContext *nus, FrameCode *fc, - AVPacket *pkt) -{ - int flags = 0; - - if (pkt->flags & AV_PKT_FLAG_KEY) - flags |= FLAG_KEY; - if (pkt->stream_index != fc->stream_id) - flags |= FLAG_STREAM_ID; - if (pkt->size / fc->size_mul) - flags |= FLAG_SIZE_MSB; - if (pkt->pts - nus->last_pts != fc->pts_delta) - flags |= FLAG_CODED_PTS; - if (pkt->size > 2 * nut->max_distance) - flags |= FLAG_CHECKSUM; - if (FFABS(pkt->pts - nus->last_pts) > nus->max_pts_distance) - flags |= FLAG_CHECKSUM; - if (pkt->size < nut->header_len[fc->header_idx] || - (pkt->size > 4096 && fc->header_idx) || - memcmp(pkt->data, nut->header[fc->header_idx], - nut->header_len[fc->header_idx])) - flags |= FLAG_HEADER_IDX; - - return flags | (fc->flags & FLAG_CODED); -} - -static int find_best_header_idx(NUTContext *nut, AVPacket *pkt) -{ - int i; - int best_i = 0; - int best_len = 0; - - if (pkt->size > 4096) - return 0; - - for (i = 1; i < nut->header_count; i++) - if (pkt->size >= nut->header_len[i] - && nut->header_len[i] > best_len - && !memcmp(pkt->data, nut->header[i], nut->header_len[i])) { - best_i = i; - best_len = nut->header_len[i]; - } - return best_i; -} - -static int nut_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - NUTContext *nut = s->priv_data; - StreamContext *nus = &nut->stream[pkt->stream_index]; - AVIOContext *bc = s->pb, *dyn_bc; - FrameCode *fc; - int64_t coded_pts; - int best_length, frame_code, flags, needed_flags, i, header_idx; - int best_header_idx; - int key_frame = !!(pkt->flags & AV_PKT_FLAG_KEY); - int store_sp = 0; - int ret; - - if (pkt->pts < 0) { - av_log(s, AV_LOG_ERROR, - "Negative pts not supported stream %d, pts %"PRId64"\n", - pkt->stream_index, pkt->pts); - return AVERROR(EINVAL); - } - - if (1LL << (20 + 3 * nut->header_count) <= avio_tell(bc)) - write_headers(s, bc); - - if (key_frame && !(nus->last_flags & FLAG_KEY)) - store_sp = 1; - - if (pkt->size + 30 /*FIXME check*/ + avio_tell(bc) >= nut->last_syncpoint_pos + nut->max_distance) - store_sp = 1; - -//FIXME: Ensure store_sp is 1 in the first place. - - if (store_sp) { - Syncpoint *sp, dummy = { .pos = INT64_MAX }; - - ff_nut_reset_ts(nut, *nus->time_base, pkt->dts); - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - int64_t dts_tb = av_rescale_rnd(pkt->dts, - nus->time_base->num * (int64_t)nut->stream[i].time_base->den, - nus->time_base->den * (int64_t)nut->stream[i].time_base->num, - AV_ROUND_DOWN); - int index = av_index_search_timestamp(st, dts_tb, - AVSEEK_FLAG_BACKWARD); - if (index >= 0) - dummy.pos = FFMIN(dummy.pos, st->index_entries[index].pos); - } - if (dummy.pos == INT64_MAX) - dummy.pos = 0; - sp = av_tree_find(nut->syncpoints, &dummy, (void *)ff_nut_sp_pos_cmp, - NULL); - - nut->last_syncpoint_pos = avio_tell(bc); - ret = avio_open_dyn_buf(&dyn_bc); - if (ret < 0) - return ret; - put_tt(nut, nus->time_base, dyn_bc, pkt->dts); - ff_put_v(dyn_bc, sp ? (nut->last_syncpoint_pos - sp->pos) >> 4 : 0); - put_packet(nut, bc, dyn_bc, 1, SYNCPOINT_STARTCODE); - - ff_nut_add_sp(nut, nut->last_syncpoint_pos, 0 /*unused*/, pkt->dts); - - if ((1ll<<60) % nut->sp_count == 0) - for (i=0; inb_streams; i++) { - int j; - StreamContext *nus = &nut->stream[i]; - nus->keyframe_pts = av_realloc(nus->keyframe_pts, 2*nut->sp_count*sizeof(*nus->keyframe_pts)); - if (!nus->keyframe_pts) - return AVERROR(ENOMEM); - for (j=nut->sp_count == 1 ? 0 : nut->sp_count; j<2*nut->sp_count; j++) - nus->keyframe_pts[j] = AV_NOPTS_VALUE; - } - } - av_assert0(nus->last_pts != AV_NOPTS_VALUE); - - coded_pts = pkt->pts & ((1 << nus->msb_pts_shift) - 1); - if (ff_lsb2full(nus, coded_pts) != pkt->pts) - coded_pts = pkt->pts + (1 << nus->msb_pts_shift); - - best_header_idx = find_best_header_idx(nut, pkt); - - best_length = INT_MAX; - frame_code = -1; - for (i = 0; i < 256; i++) { - int length = 0; - FrameCode *fc = &nut->frame_code[i]; - int flags = fc->flags; - - if (flags & FLAG_INVALID) - continue; - needed_flags = get_needed_flags(nut, nus, fc, pkt); - - if (flags & FLAG_CODED) { - length++; - flags = needed_flags; - } - - if ((flags & needed_flags) != needed_flags) - continue; - - if ((flags ^ needed_flags) & FLAG_KEY) - continue; - - if (flags & FLAG_STREAM_ID) - length += ff_get_v_length(pkt->stream_index); - - if (pkt->size % fc->size_mul != fc->size_lsb) - continue; - if (flags & FLAG_SIZE_MSB) - length += ff_get_v_length(pkt->size / fc->size_mul); - - if (flags & FLAG_CHECKSUM) - length += 4; - - if (flags & FLAG_CODED_PTS) - length += ff_get_v_length(coded_pts); - - if ( (flags & FLAG_CODED) - && nut->header_len[best_header_idx] > nut->header_len[fc->header_idx] + 1) { - flags |= FLAG_HEADER_IDX; - } - - if (flags & FLAG_HEADER_IDX) { - length += 1 - nut->header_len[best_header_idx]; - } else { - length -= nut->header_len[fc->header_idx]; - } - - length *= 4; - length += !(flags & FLAG_CODED_PTS); - length += !(flags & FLAG_CHECKSUM); - - if (length < best_length) { - best_length = length; - frame_code = i; - } - } - av_assert0(frame_code != -1); - fc = &nut->frame_code[frame_code]; - flags = fc->flags; - needed_flags = get_needed_flags(nut, nus, fc, pkt); - header_idx = fc->header_idx; - - ffio_init_checksum(bc, ff_crc04C11DB7_update, 0); - avio_w8(bc, frame_code); - if (flags & FLAG_CODED) { - ff_put_v(bc, (flags ^ needed_flags) & ~(FLAG_CODED)); - flags = needed_flags; - } - if (flags & FLAG_STREAM_ID) ff_put_v(bc, pkt->stream_index); - if (flags & FLAG_CODED_PTS) ff_put_v(bc, coded_pts); - if (flags & FLAG_SIZE_MSB ) ff_put_v(bc, pkt->size / fc->size_mul); - if (flags & FLAG_HEADER_IDX) ff_put_v(bc, header_idx = best_header_idx); - - if (flags & FLAG_CHECKSUM) avio_wl32(bc, ffio_get_checksum(bc)); - else ffio_get_checksum(bc); - - avio_write(bc, pkt->data + nut->header_len[header_idx], pkt->size - nut->header_len[header_idx]); - nus->last_flags = flags; - nus->last_pts = pkt->pts; - - //FIXME just store one per syncpoint - if (flags & FLAG_KEY) { - av_add_index_entry( - s->streams[pkt->stream_index], - nut->last_syncpoint_pos, - pkt->pts, - 0, - 0, - AVINDEX_KEYFRAME); - if (nus->keyframe_pts && nus->keyframe_pts[nut->sp_count] == AV_NOPTS_VALUE) - nus->keyframe_pts[nut->sp_count] = pkt->pts; - } - - if (!nut->max_pts_tb || av_compare_ts(nut->max_pts, *nut->max_pts_tb, pkt->pts, *nus->time_base) < 0) { - nut->max_pts = pkt->pts; - nut->max_pts_tb = nus->time_base; - } - - return 0; -} - -static int nut_write_trailer(AVFormatContext *s) -{ - NUTContext *nut = s->priv_data; - AVIOContext *bc = s->pb, *dyn_bc; - int i, ret; - - while (nut->header_count < 3) - write_headers(s, bc); - - ret = avio_open_dyn_buf(&dyn_bc); - if (ret >= 0 && nut->sp_count) { - write_index(nut, dyn_bc); - put_packet(nut, bc, dyn_bc, 1, INDEX_STARTCODE); - } - - ff_nut_free_sp(nut); - for (i=0; inb_streams; i++) - av_freep(&nut->stream[i].keyframe_pts); - - av_freep(&nut->stream); - av_freep(&nut->chapter); - av_freep(&nut->time_base); - - return 0; -} - -AVOutputFormat ff_nut_muxer = { - .name = "nut", - .long_name = NULL_IF_CONFIG_SMALL("NUT"), - .mime_type = "video/x-nut", - .extensions = "nut", - .priv_data_size = sizeof(NUTContext), - .audio_codec = CONFIG_LIBVORBIS ? AV_CODEC_ID_VORBIS : - CONFIG_LIBMP3LAME ? AV_CODEC_ID_MP3 : AV_CODEC_ID_MP2, - .video_codec = AV_CODEC_ID_MPEG4, - .write_header = nut_write_header, - .write_packet = nut_write_packet, - .write_trailer = nut_write_trailer, - .flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS, - .codec_tag = ff_nut_codec_tags, -}; diff --git a/ffmpeg1/libavformat/nuv.c b/ffmpeg1/libavformat/nuv.c deleted file mode 100644 index fc9e916..0000000 --- a/ffmpeg1/libavformat/nuv.c +++ /dev/null @@ -1,392 +0,0 @@ -/* - * NuppelVideo demuxer. - * Copyright (c) 2006 Reimar Doeffinger - * - * 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 "libavutil/channel_layout.h" -#include "libavutil/intreadwrite.h" -#include "libavutil/intfloat.h" -#include "avformat.h" -#include "internal.h" -#include "riff.h" - -static const AVCodecTag nuv_audio_tags[] = { - { AV_CODEC_ID_PCM_S16LE, MKTAG('R', 'A', 'W', 'A') }, - { AV_CODEC_ID_MP3, MKTAG('L', 'A', 'M', 'E') }, - { AV_CODEC_ID_NONE, 0 }, -}; - -typedef struct { - int v_id; - int a_id; - int rtjpg_video; -} NUVContext; - -typedef enum { - NUV_VIDEO = 'V', - NUV_EXTRADATA = 'D', - NUV_AUDIO = 'A', - NUV_SEEKP = 'R', - NUV_MYTHEXT = 'X' -} nuv_frametype; - -static int nuv_probe(AVProbeData *p) -{ - if (!memcmp(p->buf, "NuppelVideo", 12)) - return AVPROBE_SCORE_MAX; - if (!memcmp(p->buf, "MythTVVideo", 12)) - return AVPROBE_SCORE_MAX; - return 0; -} - -/// little macro to sanitize packet size -#define PKTSIZE(s) (s & 0xffffff) - -/** - * @brief read until we found all data needed for decoding - * @param vst video stream of which to change parameters - * @param ast video stream of which to change parameters - * @param myth set if this is a MythTVVideo format file - * @return 0 or AVERROR code - */ -static int get_codec_data(AVIOContext *pb, AVStream *vst, - AVStream *ast, int myth) -{ - nuv_frametype frametype; - - if (!vst && !myth) - return 1; // no codec data needed - while (!url_feof(pb)) { - int size, subtype; - - frametype = avio_r8(pb); - switch (frametype) { - case NUV_EXTRADATA: - subtype = avio_r8(pb); - avio_skip(pb, 6); - size = PKTSIZE(avio_rl32(pb)); - if (vst && subtype == 'R') { - if (vst->codec->extradata) { - av_freep(&vst->codec->extradata); - vst->codec->extradata_size = 0; - } - vst->codec->extradata = av_malloc(size); - if (!vst->codec->extradata) - return AVERROR(ENOMEM); - vst->codec->extradata_size = size; - avio_read(pb, vst->codec->extradata, size); - size = 0; - if (!myth) - return 0; - } - break; - case NUV_MYTHEXT: - avio_skip(pb, 7); - size = PKTSIZE(avio_rl32(pb)); - if (size != 128 * 4) - break; - avio_rl32(pb); // version - if (vst) { - vst->codec->codec_tag = avio_rl32(pb); - vst->codec->codec_id = - ff_codec_get_id(ff_codec_bmp_tags, vst->codec->codec_tag); - if (vst->codec->codec_tag == MKTAG('R', 'J', 'P', 'G')) - vst->codec->codec_id = AV_CODEC_ID_NUV; - } else - avio_skip(pb, 4); - - if (ast) { - int id; - - ast->codec->codec_tag = avio_rl32(pb); - ast->codec->sample_rate = avio_rl32(pb); - ast->codec->bits_per_coded_sample = avio_rl32(pb); - ast->codec->channels = avio_rl32(pb); - ast->codec->channel_layout = 0; - - id = ff_wav_codec_get_id(ast->codec->codec_tag, - ast->codec->bits_per_coded_sample); - if (id == AV_CODEC_ID_NONE) { - id = ff_codec_get_id(nuv_audio_tags, ast->codec->codec_tag); - if (id == AV_CODEC_ID_PCM_S16LE) - id = ff_get_pcm_codec_id(ast->codec->bits_per_coded_sample, - 0, 0, ~1); - } - ast->codec->codec_id = id; - - ast->need_parsing = AVSTREAM_PARSE_FULL; - } else - avio_skip(pb, 4 * 4); - - size -= 6 * 4; - avio_skip(pb, size); - return 0; - case NUV_SEEKP: - size = 11; - break; - default: - avio_skip(pb, 7); - size = PKTSIZE(avio_rl32(pb)); - break; - } - avio_skip(pb, size); - } - - return 0; -} - -static int nuv_header(AVFormatContext *s) -{ - NUVContext *ctx = s->priv_data; - AVIOContext *pb = s->pb; - char id_string[12]; - double aspect, fps; - int is_mythtv, width, height, v_packs, a_packs, ret; - AVStream *vst = NULL, *ast = NULL; - - avio_read(pb, id_string, 12); - is_mythtv = !memcmp(id_string, "MythTVVideo", 12); - avio_skip(pb, 5); // version string - avio_skip(pb, 3); // padding - width = avio_rl32(pb); - height = avio_rl32(pb); - avio_rl32(pb); // unused, "desiredwidth" - avio_rl32(pb); // unused, "desiredheight" - avio_r8(pb); // 'P' == progressive, 'I' == interlaced - avio_skip(pb, 3); // padding - aspect = av_int2double(avio_rl64(pb)); - if (aspect > 0.9999 && aspect < 1.0001) - aspect = 4.0 / 3.0; - fps = av_int2double(avio_rl64(pb)); - - // number of packets per stream type, -1 means unknown, e.g. streaming - v_packs = avio_rl32(pb); - a_packs = avio_rl32(pb); - avio_rl32(pb); // text - - avio_rl32(pb); // keyframe distance (?) - - if (v_packs) { - vst = avformat_new_stream(s, NULL); - if (!vst) - return AVERROR(ENOMEM); - ctx->v_id = vst->index; - - vst->codec->codec_type = AVMEDIA_TYPE_VIDEO; - vst->codec->codec_id = AV_CODEC_ID_NUV; - vst->codec->width = width; - vst->codec->height = height; - vst->codec->bits_per_coded_sample = 10; - vst->sample_aspect_ratio = av_d2q(aspect * height / width, - 10000); -#if FF_API_R_FRAME_RATE - vst->r_frame_rate = -#endif - vst->avg_frame_rate = av_d2q(fps, 60000); - avpriv_set_pts_info(vst, 32, 1, 1000); - } else - ctx->v_id = -1; - - if (a_packs) { - ast = avformat_new_stream(s, NULL); - if (!ast) - return AVERROR(ENOMEM); - ctx->a_id = ast->index; - - ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; - ast->codec->codec_id = AV_CODEC_ID_PCM_S16LE; - ast->codec->channels = 2; - ast->codec->channel_layout = AV_CH_LAYOUT_STEREO; - ast->codec->sample_rate = 44100; - ast->codec->bit_rate = 2 * 2 * 44100 * 8; - ast->codec->block_align = 2 * 2; - ast->codec->bits_per_coded_sample = 16; - avpriv_set_pts_info(ast, 32, 1, 1000); - } else - ctx->a_id = -1; - - if ((ret = get_codec_data(pb, vst, ast, is_mythtv)) < 0) - return ret; - - ctx->rtjpg_video = vst && vst->codec->codec_id == AV_CODEC_ID_NUV; - - return 0; -} - -#define HDRSIZE 12 - -static int nuv_packet(AVFormatContext *s, AVPacket *pkt) -{ - NUVContext *ctx = s->priv_data; - AVIOContext *pb = s->pb; - uint8_t hdr[HDRSIZE]; - nuv_frametype frametype; - int ret, size; - - while (!url_feof(pb)) { - int copyhdrsize = ctx->rtjpg_video ? HDRSIZE : 0; - uint64_t pos = avio_tell(pb); - - ret = avio_read(pb, hdr, HDRSIZE); - if (ret < HDRSIZE) - return ret < 0 ? ret : AVERROR(EIO); - - frametype = hdr[0]; - size = PKTSIZE(AV_RL32(&hdr[8])); - - switch (frametype) { - case NUV_EXTRADATA: - if (!ctx->rtjpg_video) { - avio_skip(pb, size); - break; - } - case NUV_VIDEO: - if (ctx->v_id < 0) { - av_log(s, AV_LOG_ERROR, "Video packet in file without video stream!\n"); - avio_skip(pb, size); - break; - } - ret = av_new_packet(pkt, copyhdrsize + size); - if (ret < 0) - return ret; - - pkt->pos = pos; - pkt->flags |= hdr[2] == 0 ? AV_PKT_FLAG_KEY : 0; - pkt->pts = AV_RL32(&hdr[4]); - pkt->stream_index = ctx->v_id; - memcpy(pkt->data, hdr, copyhdrsize); - ret = avio_read(pb, pkt->data + copyhdrsize, size); - if (ret < 0) { - av_free_packet(pkt); - return ret; - } - if (ret < size) - av_shrink_packet(pkt, copyhdrsize + ret); - return 0; - case NUV_AUDIO: - if (ctx->a_id < 0) { - av_log(s, AV_LOG_ERROR, "Audio packet in file without audio stream!\n"); - avio_skip(pb, size); - break; - } - ret = av_get_packet(pb, pkt, size); - pkt->flags |= AV_PKT_FLAG_KEY; - pkt->pos = pos; - pkt->pts = AV_RL32(&hdr[4]); - pkt->stream_index = ctx->a_id; - if (ret < 0) - return ret; - return 0; - case NUV_SEEKP: - // contains no data, size value is invalid - break; - default: - avio_skip(pb, size); - break; - } - } - - return AVERROR(EIO); -} - -/** - * \brief looks for the string RTjjjjjjjjjj in the stream too resync reading - * \return 1 if the syncword is found 0 otherwise. - */ -static int nuv_resync(AVFormatContext *s, int64_t pos_limit) { - AVIOContext *pb = s->pb; - uint32_t tag = 0; - while(!url_feof(pb) && avio_tell(pb) < pos_limit) { - tag = (tag << 8) | avio_r8(pb); - if (tag == MKBETAG('R','T','j','j') && - (tag = avio_rb32(pb)) == MKBETAG('j','j','j','j') && - (tag = avio_rb32(pb)) == MKBETAG('j','j','j','j')) - return 1; - } - return 0; -} - -/** - * \brief attempts to read a timestamp from stream at the given stream position - * \return timestamp if successful and AV_NOPTS_VALUE if failure - */ -static int64_t nuv_read_dts(AVFormatContext *s, int stream_index, - int64_t *ppos, int64_t pos_limit) -{ - NUVContext *ctx = s->priv_data; - AVIOContext *pb = s->pb; - uint8_t hdr[HDRSIZE]; - nuv_frametype frametype; - int size, key, idx; - int64_t pos, dts; - - if (avio_seek(pb, *ppos, SEEK_SET) < 0) - return AV_NOPTS_VALUE; - - if (!nuv_resync(s, pos_limit)) - return AV_NOPTS_VALUE; - - while (!url_feof(pb) && avio_tell(pb) < pos_limit) { - if (avio_read(pb, hdr, HDRSIZE) < HDRSIZE) - return AV_NOPTS_VALUE; - frametype = hdr[0]; - size = PKTSIZE(AV_RL32(&hdr[8])); - switch (frametype) { - case NUV_SEEKP: - break; - case NUV_AUDIO: - case NUV_VIDEO: - if (frametype == NUV_VIDEO) { - idx = ctx->v_id; - key = hdr[2] == 0; - } else { - idx = ctx->a_id; - key = 1; - } - if (stream_index == idx) { - - pos = avio_tell(s->pb) - HDRSIZE; - dts = AV_RL32(&hdr[4]); - - // TODO - add general support in av_gen_search, so it adds positions after reading timestamps - av_add_index_entry(s->streams[stream_index], pos, dts, size + HDRSIZE, 0, - key ? AVINDEX_KEYFRAME : 0); - - *ppos = pos; - return dts; - } - default: - avio_skip(pb, size); - break; - } - } - return AV_NOPTS_VALUE; -} - - -AVInputFormat ff_nuv_demuxer = { - .name = "nuv", - .long_name = NULL_IF_CONFIG_SMALL("NuppelVideo"), - .priv_data_size = sizeof(NUVContext), - .read_probe = nuv_probe, - .read_header = nuv_header, - .read_packet = nuv_packet, - .read_timestamp = nuv_read_dts, - .flags = AVFMT_GENERIC_INDEX, -}; diff --git a/ffmpeg1/libavformat/oggdec.c b/ffmpeg1/libavformat/oggdec.c deleted file mode 100644 index fdb5e96..0000000 --- a/ffmpeg1/libavformat/oggdec.c +++ /dev/null @@ -1,853 +0,0 @@ -/* - * Ogg bitstream support - * Luca Barbato - * Based on tcvp implementation - */ - -/* - Copyright (C) 2005 Michael Ahlberg, MÃ¥ns RullgÃ¥rd - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. - */ - -#include -#include "libavutil/avassert.h" -#include "oggdec.h" -#include "avformat.h" -#include "internal.h" -#include "vorbiscomment.h" - -#define MAX_PAGE_SIZE 65307 -#define DECODER_BUFFER_SIZE MAX_PAGE_SIZE - -static const struct ogg_codec * const ogg_codecs[] = { - &ff_skeleton_codec, - &ff_dirac_codec, - &ff_speex_codec, - &ff_vorbis_codec, - &ff_theora_codec, - &ff_flac_codec, - &ff_celt_codec, - &ff_opus_codec, - &ff_old_dirac_codec, - &ff_old_flac_codec, - &ff_ogm_video_codec, - &ff_ogm_audio_codec, - &ff_ogm_text_codec, - &ff_ogm_old_codec, - NULL -}; - -static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts); -static int ogg_new_stream(AVFormatContext *s, uint32_t serial); - -//FIXME We could avoid some structure duplication -static int ogg_save(AVFormatContext *s) -{ - struct ogg *ogg = s->priv_data; - struct ogg_state *ost = - av_malloc(sizeof(*ost) + (ogg->nstreams - 1) * sizeof(*ogg->streams)); - int i; - ost->pos = avio_tell(s->pb); - ost->curidx = ogg->curidx; - ost->next = ogg->state; - ost->nstreams = ogg->nstreams; - memcpy(ost->streams, ogg->streams, ogg->nstreams * sizeof(*ogg->streams)); - - for (i = 0; i < ogg->nstreams; i++) { - struct ogg_stream *os = ogg->streams + i; - os->buf = av_mallocz(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE); - memcpy(os->buf, ost->streams[i].buf, os->bufpos); - } - - ogg->state = ost; - - return 0; -} - -static int ogg_restore(AVFormatContext *s, int discard) -{ - struct ogg *ogg = s->priv_data; - AVIOContext *bc = s->pb; - struct ogg_state *ost = ogg->state; - int i; - - if (!ost) - return 0; - - ogg->state = ost->next; - - if (!discard) { - struct ogg_stream *old_streams = ogg->streams; - - for (i = 0; i < ogg->nstreams; i++) - av_free(ogg->streams[i].buf); - - avio_seek(bc, ost->pos, SEEK_SET); - ogg->page_pos = -1; - ogg->curidx = ost->curidx; - ogg->nstreams = ost->nstreams; - ogg->streams = av_realloc(ogg->streams, - ogg->nstreams * sizeof(*ogg->streams)); - - if (ogg->streams) { - memcpy(ogg->streams, ost->streams, - ost->nstreams * sizeof(*ogg->streams)); - } else { - av_free(old_streams); - ogg->nstreams = 0; - } - } - - av_free(ost); - - return 0; -} - -static int ogg_reset(AVFormatContext *s) -{ - struct ogg *ogg = s->priv_data; - int i; - int64_t start_pos = avio_tell(s->pb); - - for (i = 0; i < ogg->nstreams; i++) { - struct ogg_stream *os = ogg->streams + i; - os->bufpos = 0; - os->pstart = 0; - os->psize = 0; - os->granule = -1; - os->lastpts = AV_NOPTS_VALUE; - os->lastdts = AV_NOPTS_VALUE; - os->sync_pos = -1; - os->page_pos = 0; - os->nsegs = 0; - os->segp = 0; - os->incomplete = 0; - os->got_data = 0; - if (start_pos <= s->data_offset) { - os->lastpts = 0; - } - } - - ogg->page_pos = -1; - ogg->curidx = -1; - - return 0; -} - -static const struct ogg_codec *ogg_find_codec(uint8_t *buf, int size) -{ - int i; - - for (i = 0; ogg_codecs[i]; i++) - if (size >= ogg_codecs[i]->magicsize && - !memcmp(buf, ogg_codecs[i]->magic, ogg_codecs[i]->magicsize)) - return ogg_codecs[i]; - - return NULL; -} - -/** - * Replace the current stream with a new one. This is a typical webradio - * situation where a new audio stream spawn (identified with a new serial) and - * must replace the previous one (track switch). - */ -static int ogg_replace_stream(AVFormatContext *s, uint32_t serial, int nsegs) -{ - struct ogg *ogg = s->priv_data; - struct ogg_stream *os; - const struct ogg_codec *codec; - int i = 0; - - if (s->pb->seekable) { - uint8_t magic[8]; - int64_t pos = avio_tell(s->pb); - avio_skip(s->pb, nsegs); - avio_read(s->pb, magic, sizeof(magic)); - avio_seek(s->pb, pos, SEEK_SET); - codec = ogg_find_codec(magic, sizeof(magic)); - if (!codec) { - av_log(s, AV_LOG_ERROR, "Cannot identify new stream\n"); - return AVERROR_INVALIDDATA; - } - for (i = 0; i < ogg->nstreams; i++) { - if (ogg->streams[i].codec == codec) - break; - } - if (i >= ogg->nstreams) - return ogg_new_stream(s, serial); - } else if (ogg->nstreams != 1) { - avpriv_report_missing_feature(s, "Changing stream parameters in multistream ogg"); - return AVERROR_PATCHWELCOME; - } - - os = &ogg->streams[i]; - - os->serial = serial; - return i; - -#if 0 - buf = os->buf; - bufsize = os->bufsize; - codec = os->codec; - - if (!ogg->state || ogg->state->streams[i].private != os->private) - av_freep(&ogg->streams[i].private); - - /* Set Ogg stream settings similar to what is done in ogg_new_stream(). We - * also re-use the ogg_stream allocated buffer */ - memset(os, 0, sizeof(*os)); - os->serial = serial; - os->bufsize = bufsize; - os->buf = buf; - os->header = -1; - os->codec = codec; - - return i; -#endif -} - -static int ogg_new_stream(AVFormatContext *s, uint32_t serial) -{ - struct ogg *ogg = s->priv_data; - int idx = ogg->nstreams; - AVStream *st; - struct ogg_stream *os; - size_t size; - - if (ogg->state) { - av_log(s, AV_LOG_ERROR, "New streams are not supposed to be added " - "in between Ogg context save/restore operations.\n"); - return AVERROR_BUG; - } - - /* Allocate and init a new Ogg Stream */ - if (av_size_mult(ogg->nstreams + 1, sizeof(*ogg->streams), &size) < 0 || - !(os = av_realloc(ogg->streams, size))) - return AVERROR(ENOMEM); - ogg->streams = os; - os = ogg->streams + idx; - memset(os, 0, sizeof(*os)); - os->serial = serial; - os->bufsize = DECODER_BUFFER_SIZE; - os->buf = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE); - os->header = -1; - os->start_granule = OGG_NOGRANULE_VALUE; - if (!os->buf) - return AVERROR(ENOMEM); - - /* Create the associated AVStream */ - st = avformat_new_stream(s, NULL); - if (!st) { - av_freep(&os->buf); - return AVERROR(ENOMEM); - } - st->id = idx; - avpriv_set_pts_info(st, 64, 1, 1000000); - - ogg->nstreams++; - return idx; -} - -static int ogg_new_buf(struct ogg *ogg, int idx) -{ - struct ogg_stream *os = ogg->streams + idx; - uint8_t *nb = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE); - int size = os->bufpos - os->pstart; - - if (os->buf) { - memcpy(nb, os->buf + os->pstart, size); - av_free(os->buf); - } - - os->buf = nb; - os->bufpos = size; - os->pstart = 0; - - return 0; -} - -static int data_packets_seen(const struct ogg *ogg) -{ - int i; - - for (i = 0; i < ogg->nstreams; i++) - if (ogg->streams[i].got_data) - return 1; - return 0; -} - -static int ogg_read_page(AVFormatContext *s, int *sid) -{ - AVIOContext *bc = s->pb; - struct ogg *ogg = s->priv_data; - struct ogg_stream *os; - int ret, i = 0; - int flags, nsegs; - uint64_t gp; - uint32_t serial; - int size, idx; - uint8_t sync[4]; - int sp = 0; - - ret = avio_read(bc, sync, 4); - if (ret < 4) - return ret < 0 ? ret : AVERROR_EOF; - - do { - int c; - - if (sync[sp & 3] == 'O' && - sync[(sp + 1) & 3] == 'g' && - sync[(sp + 2) & 3] == 'g' && sync[(sp + 3) & 3] == 'S') - break; - - if(!i && bc->seekable && ogg->page_pos > 0) { - memset(sync, 0, 4); - avio_seek(bc, ogg->page_pos+4, SEEK_SET); - ogg->page_pos = -1; - } - - c = avio_r8(bc); - - if (url_feof(bc)) - return AVERROR_EOF; - - sync[sp++ & 3] = c; - } while (i++ < MAX_PAGE_SIZE); - - if (i >= MAX_PAGE_SIZE) { - av_log(s, AV_LOG_INFO, "cannot find sync word\n"); - return AVERROR_INVALIDDATA; - } - - if (avio_r8(bc) != 0) { /* version */ - av_log (s, AV_LOG_ERROR, "ogg page, unsupported version\n"); - return AVERROR_INVALIDDATA; - } - - flags = avio_r8(bc); - gp = avio_rl64(bc); - serial = avio_rl32(bc); - avio_skip(bc, 8); /* seq, crc */ - nsegs = avio_r8(bc); - - idx = ogg_find_stream(ogg, serial); - if (idx < 0) { - if (data_packets_seen(ogg)) - idx = ogg_replace_stream(s, serial, nsegs); - else - idx = ogg_new_stream(s, serial); - - if (idx < 0) { - av_log(s, AV_LOG_ERROR, "failed to create or replace stream\n"); - return idx; - } - } - - os = ogg->streams + idx; - ogg->page_pos = - os->page_pos = avio_tell(bc) - 27; - - if (os->psize > 0) - ogg_new_buf(ogg, idx); - - ret = avio_read(bc, os->segments, nsegs); - if (ret < nsegs) - return ret < 0 ? ret : AVERROR_EOF; - - os->nsegs = nsegs; - os->segp = 0; - - size = 0; - for (i = 0; i < nsegs; i++) - size += os->segments[i]; - - if (!(flags & OGG_FLAG_BOS)) - os->got_data = 1; - - if (flags & OGG_FLAG_CONT || os->incomplete) { - if (!os->psize) { - // If this is the very first segment we started - // playback in the middle of a continuation packet. - // Discard it since we missed the start of it. - while (os->segp < os->nsegs) { - int seg = os->segments[os->segp++]; - os->pstart += seg; - if (seg < 255) - break; - } - os->sync_pos = os->page_pos; - } - } else { - os->psize = 0; - os->sync_pos = os->page_pos; - } - - if (os->bufsize - os->bufpos < size) { - uint8_t *nb = av_malloc((os->bufsize *= 2) + FF_INPUT_BUFFER_PADDING_SIZE); - if (!nb) - return AVERROR(ENOMEM); - memcpy(nb, os->buf, os->bufpos); - av_free(os->buf); - os->buf = nb; - } - - ret = avio_read(bc, os->buf + os->bufpos, size); - if (ret < size) - return ret < 0 ? ret : AVERROR_EOF; - - os->bufpos += size; - os->granule = gp; - os->flags = flags; - - memset(os->buf + os->bufpos, 0, FF_INPUT_BUFFER_PADDING_SIZE); - if (sid) - *sid = idx; - - return 0; -} - -/** - * @brief find the next Ogg packet - * @param *sid is set to the stream for the packet or -1 if there is - * no matching stream, in that case assume all other return - * values to be uninitialized. - * @return negative value on error or EOF. - */ -static int ogg_packet(AVFormatContext *s, int *sid, int *dstart, int *dsize, - int64_t *fpos) -{ - struct ogg *ogg = s->priv_data; - int idx, i, ret; - struct ogg_stream *os; - int complete = 0; - int segp = 0, psize = 0; - - av_dlog(s, "ogg_packet: curidx=%i\n", ogg->curidx); - if (sid) - *sid = -1; - - do { - idx = ogg->curidx; - - while (idx < 0) { - ret = ogg_read_page(s, &idx); - if (ret < 0) - return ret; - } - - os = ogg->streams + idx; - - av_dlog(s, "ogg_packet: idx=%d pstart=%d psize=%d segp=%d nsegs=%d\n", - idx, os->pstart, os->psize, os->segp, os->nsegs); - - if (!os->codec) { - if (os->header < 0) { - os->codec = ogg_find_codec(os->buf, os->bufpos); - if (!os->codec) { - av_log(s, AV_LOG_WARNING, "Codec not found\n"); - os->header = 0; - return 0; - } - } else { - return 0; - } - } - - segp = os->segp; - psize = os->psize; - - while (os->segp < os->nsegs) { - int ss = os->segments[os->segp++]; - os->psize += ss; - if (ss < 255) { - complete = 1; - break; - } - } - - if (!complete && os->segp == os->nsegs) { - ogg->curidx = -1; - // Do not set incomplete for empty packets. - // Together with the code in ogg_read_page - // that discards all continuation of empty packets - // we would get an infinite loop. - os->incomplete = !!os->psize; - } - } while (!complete); - - - if (os->granule == -1) - av_log(s, AV_LOG_WARNING, - "Page at %"PRId64" is missing granule\n", - os->page_pos); - - ogg->curidx = idx; - os->incomplete = 0; - - if (os->header) { - os->header = os->codec->header(s, idx); - if (!os->header) { - os->segp = segp; - os->psize = psize; - - // We have reached the first non-header packet in this stream. - // Unfortunately more header packets may still follow for others, - // but if we continue with header parsing we may lose data packets. - ogg->headers = 1; - - // Update the header state for all streams and - // compute the data_offset. - if (!s->data_offset) - s->data_offset = os->sync_pos; - - for (i = 0; i < ogg->nstreams; i++) { - struct ogg_stream *cur_os = ogg->streams + i; - - // if we have a partial non-header packet, its start is - // obviously at or after the data start - if (cur_os->incomplete) - s->data_offset = FFMIN(s->data_offset, cur_os->sync_pos); - } - } else { - os->nb_header++; - os->pstart += os->psize; - os->psize = 0; - } - } else { - os->pflags = 0; - os->pduration = 0; - if (os->codec && os->codec->packet) - os->codec->packet(s, idx); - if (sid) - *sid = idx; - if (dstart) - *dstart = os->pstart; - if (dsize) - *dsize = os->psize; - if (fpos) - *fpos = os->sync_pos; - os->pstart += os->psize; - os->psize = 0; - if(os->pstart == os->bufpos) - os->bufpos = os->pstart = 0; - os->sync_pos = os->page_pos; - } - - // determine whether there are more complete packets in this page - // if not, the page's granule will apply to this packet - os->page_end = 1; - for (i = os->segp; i < os->nsegs; i++) - if (os->segments[i] < 255) { - os->page_end = 0; - break; - } - - if (os->segp == os->nsegs) - ogg->curidx = -1; - - return 0; -} - -static int ogg_get_length(AVFormatContext *s) -{ - struct ogg *ogg = s->priv_data; - int i; - int64_t size, end; - int streams_left=0; - - if (!s->pb->seekable) - return 0; - -// already set - if (s->duration != AV_NOPTS_VALUE) - return 0; - - size = avio_size(s->pb); - if (size < 0) - return 0; - end = size > MAX_PAGE_SIZE ? size - MAX_PAGE_SIZE : 0; - - ogg_save(s); - avio_seek(s->pb, end, SEEK_SET); - ogg->page_pos = -1; - - while (!ogg_read_page(s, &i)) { - if (ogg->streams[i].granule != -1 && ogg->streams[i].granule != 0 && - ogg->streams[i].codec) { - s->streams[i]->duration = - ogg_gptopts(s, i, ogg->streams[i].granule, NULL); - if (s->streams[i]->start_time != AV_NOPTS_VALUE) { - s->streams[i]->duration -= s->streams[i]->start_time; - streams_left-= (ogg->streams[i].got_start==-1); - ogg->streams[i].got_start= 1; - } else if(!ogg->streams[i].got_start) { - ogg->streams[i].got_start= -1; - streams_left++; - } - } - } - - ogg_restore(s, 0); - - ogg_save (s); - avio_seek (s->pb, s->data_offset, SEEK_SET); - ogg_reset(s); - while (streams_left > 0 && !ogg_packet(s, &i, NULL, NULL, NULL)) { - int64_t pts; - if (i < 0) continue; - pts = ogg_calc_pts(s, i, NULL); - if (pts != AV_NOPTS_VALUE && s->streams[i]->start_time == AV_NOPTS_VALUE && !ogg->streams[i].got_start) { - s->streams[i]->duration -= pts; - ogg->streams[i].got_start= 1; - streams_left--; - }else if(s->streams[i]->start_time != AV_NOPTS_VALUE && !ogg->streams[i].got_start) { - ogg->streams[i].got_start= 1; - streams_left--; - } - } - ogg_restore (s, 0); - - return 0; -} - -static int ogg_read_close(AVFormatContext *s) -{ - struct ogg *ogg = s->priv_data; - int i; - - for (i = 0; i < ogg->nstreams; i++) { - av_free(ogg->streams[i].buf); - if (ogg->streams[i].codec && - ogg->streams[i].codec->cleanup) { - ogg->streams[i].codec->cleanup(s, i); - } - av_free(ogg->streams[i].private); - } - av_free(ogg->streams); - return 0; -} - -static int ogg_read_header(AVFormatContext *s) -{ - struct ogg *ogg = s->priv_data; - int ret, i; - - ogg->curidx = -1; - - //linear headers seek from start - do { - ret = ogg_packet(s, NULL, NULL, NULL, NULL); - if (ret < 0) { - ogg_read_close(s); - return ret; - } - } while (!ogg->headers); - av_dlog(s, "found headers\n"); - - for (i = 0; i < ogg->nstreams; i++) { - struct ogg_stream *os = ogg->streams + i; - - if (ogg->streams[i].header < 0) { - av_log(s, AV_LOG_ERROR, "Header parsing failed for stream %d\n", i); - ogg->streams[i].codec = NULL; - } else if (os->codec && os->nb_header < os->codec->nb_header) { - av_log(s, AV_LOG_WARNING, "Number of headers (%d) mismatch for stream %d\n", os->nb_header, i); - } - if (os->start_granule != OGG_NOGRANULE_VALUE) - os->lastpts = s->streams[i]->start_time = - ogg_gptopts(s, i, os->start_granule, NULL); - } - - //linear granulepos seek from end - ogg_get_length(s); - - return 0; -} - -static int64_t ogg_calc_pts(AVFormatContext *s, int idx, int64_t *dts) -{ - struct ogg *ogg = s->priv_data; - struct ogg_stream *os = ogg->streams + idx; - int64_t pts = AV_NOPTS_VALUE; - - if (dts) - *dts = AV_NOPTS_VALUE; - - if (os->lastpts != AV_NOPTS_VALUE) { - pts = os->lastpts; - os->lastpts = AV_NOPTS_VALUE; - } - if (os->lastdts != AV_NOPTS_VALUE) { - if (dts) - *dts = os->lastdts; - os->lastdts = AV_NOPTS_VALUE; - } - if (os->page_end) { - if (os->granule != -1LL) { - if (os->codec && os->codec->granule_is_start) - pts = ogg_gptopts(s, idx, os->granule, dts); - else - os->lastpts = ogg_gptopts(s, idx, os->granule, &os->lastdts); - os->granule = -1LL; - } - } - return pts; -} - -static void ogg_validate_keyframe(AVFormatContext *s, int idx, int pstart, int psize) -{ - struct ogg *ogg = s->priv_data; - struct ogg_stream *os = ogg->streams + idx; - if (psize && s->streams[idx]->codec->codec_id == AV_CODEC_ID_THEORA) { - if (!!(os->pflags & AV_PKT_FLAG_KEY) != !(os->buf[pstart] & 0x40)) { - os->pflags ^= AV_PKT_FLAG_KEY; - av_log(s, AV_LOG_WARNING, "Broken file, %skeyframe not correctly marked.\n", - (os->pflags & AV_PKT_FLAG_KEY) ? "" : "non-"); - } - } -} - -static int ogg_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - struct ogg *ogg; - struct ogg_stream *os; - int idx, ret; - int pstart, psize; - int64_t fpos, pts, dts; - - //Get an ogg packet -retry: - do { - ret = ogg_packet(s, &idx, &pstart, &psize, &fpos); - if (ret < 0) - return ret; - } while (idx < 0 || !s->streams[idx]); - - ogg = s->priv_data; - os = ogg->streams + idx; - - // pflags might not be set until after this - pts = ogg_calc_pts(s, idx, &dts); - ogg_validate_keyframe(s, idx, pstart, psize); - - if (os->keyframe_seek && !(os->pflags & AV_PKT_FLAG_KEY)) - goto retry; - os->keyframe_seek = 0; - - //Alloc a pkt - ret = av_new_packet(pkt, psize); - if (ret < 0) - return ret; - pkt->stream_index = idx; - memcpy(pkt->data, os->buf + pstart, psize); - - pkt->pts = pts; - pkt->dts = dts; - pkt->flags = os->pflags; - pkt->duration = os->pduration; - pkt->pos = fpos; - - return psize; -} - -static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index, - int64_t *pos_arg, int64_t pos_limit) -{ - struct ogg *ogg = s->priv_data; - AVIOContext *bc = s->pb; - int64_t pts = AV_NOPTS_VALUE; - int64_t keypos = -1; - int i; - int pstart, psize; - avio_seek(bc, *pos_arg, SEEK_SET); - ogg_reset(s); - - while ( avio_tell(bc) <= pos_limit - && !ogg_packet(s, &i, &pstart, &psize, pos_arg)) { - if (i == stream_index) { - struct ogg_stream *os = ogg->streams + stream_index; - pts = ogg_calc_pts(s, i, NULL); - ogg_validate_keyframe(s, i, pstart, psize); - if (os->pflags & AV_PKT_FLAG_KEY) { - keypos = *pos_arg; - } else if (os->keyframe_seek) { - // if we had a previous keyframe but no pts for it, - // return that keyframe with this pts value. - if (keypos >= 0) - *pos_arg = keypos; - else - pts = AV_NOPTS_VALUE; - } - } - if (pts != AV_NOPTS_VALUE) - break; - } - ogg_reset(s); - return pts; -} - -static int ogg_read_seek(AVFormatContext *s, int stream_index, - int64_t timestamp, int flags) -{ - struct ogg *ogg = s->priv_data; - struct ogg_stream *os = ogg->streams + stream_index; - int ret; - - av_assert0(stream_index < ogg->nstreams); - // Ensure everything is reset even when seeking via - // the generated index. - ogg_reset(s); - - // Try seeking to a keyframe first. If this fails (very possible), - // av_seek_frame will fall back to ignoring keyframes - if (s->streams[stream_index]->codec->codec_type == AVMEDIA_TYPE_VIDEO - && !(flags & AVSEEK_FLAG_ANY)) - os->keyframe_seek = 1; - - ret = ff_seek_frame_binary(s, stream_index, timestamp, flags); - os = ogg->streams + stream_index; - if (ret < 0) - os->keyframe_seek = 0; - return ret; -} - -static int ogg_probe(AVProbeData *p) -{ - if (!memcmp("OggS", p->buf, 5) && p->buf[5] <= 0x7) - return AVPROBE_SCORE_MAX; - return 0; -} - -AVInputFormat ff_ogg_demuxer = { - .name = "ogg", - .long_name = NULL_IF_CONFIG_SMALL("Ogg"), - .priv_data_size = sizeof(struct ogg), - .read_probe = ogg_probe, - .read_header = ogg_read_header, - .read_packet = ogg_read_packet, - .read_close = ogg_read_close, - .read_seek = ogg_read_seek, - .read_timestamp = ogg_read_timestamp, - .extensions = "ogg", - .flags = AVFMT_GENERIC_INDEX | AVFMT_TS_DISCONT, -}; diff --git a/ffmpeg1/libavformat/oggdec.h b/ffmpeg1/libavformat/oggdec.h deleted file mode 100644 index e9a300d..0000000 --- a/ffmpeg1/libavformat/oggdec.h +++ /dev/null @@ -1,160 +0,0 @@ -/** - Copyright (C) 2005 Michael Ahlberg, MÃ¥ns RullgÃ¥rd - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -**/ - -#ifndef AVFORMAT_OGGDEC_H -#define AVFORMAT_OGGDEC_H - -#include "avformat.h" -#include "metadata.h" - -struct ogg_codec { - const int8_t *magic; - uint8_t magicsize; - const int8_t *name; - /** - * Attempt to process a packet as a header - * @return 1 if the packet was a valid header, - * 0 if the packet was not a header (was a data packet) - * -1 if an error occurred or for unsupported stream - */ - int (*header)(AVFormatContext *, int); - int (*packet)(AVFormatContext *, int); - /** - * Translate a granule into a timestamp. - * Will set dts if non-null and known. - * @return pts - */ - uint64_t (*gptopts)(AVFormatContext *, int, uint64_t, int64_t *dts); - /** - * 1 if granule is the start time of the associated packet. - * 0 if granule is the end time of the associated packet. - */ - int granule_is_start; - /** - * Number of expected headers - */ - int nb_header; - void (*cleanup)(AVFormatContext *s, int idx); -}; - -struct ogg_stream { - uint8_t *buf; - unsigned int bufsize; - unsigned int bufpos; - unsigned int pstart; - unsigned int psize; - unsigned int pflags; - unsigned int pduration; - uint32_t serial; - uint64_t granule; - uint64_t start_granule; - int64_t lastpts; - int64_t lastdts; - int64_t sync_pos; ///< file offset of the first page needed to reconstruct the current packet - int64_t page_pos; ///< file offset of the current page - int flags; - const struct ogg_codec *codec; - int header; - int nsegs, segp; - uint8_t segments[255]; - int incomplete; ///< whether we're expecting a continuation in the next page - int page_end; ///< current packet is the last one completed in the page - int keyframe_seek; - int got_start; - int got_data; ///< 1 if the stream got some data (non-initial packets), 0 otherwise - int nb_header; ///< set to the number of parsed headers - void *private; -}; - -struct ogg_state { - uint64_t pos; - int curidx; - struct ogg_state *next; - int nstreams; - struct ogg_stream streams[1]; -}; - -struct ogg { - struct ogg_stream *streams; - int nstreams; - int headers; - int curidx; - int64_t page_pos; ///< file offset of the current page - struct ogg_state *state; -}; - -#define OGG_FLAG_CONT 1 -#define OGG_FLAG_BOS 2 -#define OGG_FLAG_EOS 4 - -#define OGG_NOGRANULE_VALUE (-1ull) - -extern const struct ogg_codec ff_celt_codec; -extern const struct ogg_codec ff_dirac_codec; -extern const struct ogg_codec ff_flac_codec; -extern const struct ogg_codec ff_ogm_audio_codec; -extern const struct ogg_codec ff_ogm_old_codec; -extern const struct ogg_codec ff_ogm_text_codec; -extern const struct ogg_codec ff_ogm_video_codec; -extern const struct ogg_codec ff_old_dirac_codec; -extern const struct ogg_codec ff_old_flac_codec; -extern const struct ogg_codec ff_opus_codec; -extern const struct ogg_codec ff_skeleton_codec; -extern const struct ogg_codec ff_speex_codec; -extern const struct ogg_codec ff_theora_codec; -extern const struct ogg_codec ff_vorbis_codec; - -int ff_vorbis_comment(AVFormatContext *ms, AVDictionary **m, const uint8_t *buf, int size); - -static inline int -ogg_find_stream (struct ogg * ogg, int serial) -{ - int i; - - for (i = 0; i < ogg->nstreams; i++) - if (ogg->streams[i].serial == serial) - return i; - - return -1; -} - -static inline uint64_t -ogg_gptopts (AVFormatContext * s, int i, uint64_t gp, int64_t *dts) -{ - struct ogg *ogg = s->priv_data; - struct ogg_stream *os = ogg->streams + i; - uint64_t pts = AV_NOPTS_VALUE; - - if(os->codec && os->codec->gptopts){ - pts = os->codec->gptopts(s, i, gp, dts); - } else { - pts = gp; - if (dts) - *dts = pts; - } - - return pts; -} - -#endif /* AVFORMAT_OGGDEC_H */ diff --git a/ffmpeg1/libavformat/oggenc.c b/ffmpeg1/libavformat/oggenc.c deleted file mode 100644 index 3d4519c..0000000 --- a/ffmpeg1/libavformat/oggenc.c +++ /dev/null @@ -1,636 +0,0 @@ -/* - * Ogg muxer - * Copyright (c) 2007 Baptiste Coudurier - * - * 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 "libavutil/crc.h" -#include "libavutil/opt.h" -#include "libavutil/mathematics.h" -#include "libavutil/opt.h" -#include "libavutil/random_seed.h" -#include "libavcodec/xiph.h" -#include "libavcodec/bytestream.h" -#include "libavcodec/flac.h" -#include "avformat.h" -#include "avio_internal.h" -#include "internal.h" -#include "vorbiscomment.h" - -#define MAX_PAGE_SIZE 65025 - -typedef struct { - int64_t start_granule; - int64_t granule; - int stream_index; - uint8_t flags; - uint8_t segments_count; - uint8_t segments[255]; - uint8_t data[MAX_PAGE_SIZE]; - uint16_t size; -} OGGPage; - -typedef struct { - unsigned page_counter; - uint8_t *header[3]; - int header_len[3]; - /** for theora granule */ - int kfgshift; - int64_t last_kf_pts; - int vrev; - int eos; - unsigned page_count; ///< number of page buffered - OGGPage page; ///< current page - unsigned serial_num; ///< serial number - int64_t last_granule; ///< last packet granule -} OGGStreamContext; - -typedef struct OGGPageList { - OGGPage page; - struct OGGPageList *next; -} OGGPageList; - -typedef struct { - const AVClass *class; - OGGPageList *page_list; - int pref_size; ///< preferred page size (0 => fill all segments) - int64_t pref_duration; ///< preferred page duration (0 => fill all segments) -} OGGContext; - -#define OFFSET(x) offsetof(OGGContext, x) -#define PARAM AV_OPT_FLAG_ENCODING_PARAM - -static const AVOption options[] = { - { "oggpagesize", "Set preferred Ogg page size.", - offsetof(OGGContext, pref_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, MAX_PAGE_SIZE, AV_OPT_FLAG_ENCODING_PARAM}, - { "pagesize", "preferred page size in bytes (deprecated)", - OFFSET(pref_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, MAX_PAGE_SIZE, PARAM }, - { "page_duration", "preferred page duration, in microseconds", - OFFSET(pref_duration), AV_OPT_TYPE_INT, { .i64 = 1000000 }, 0, INT64_MAX, PARAM }, - { NULL }, -}; - -static const AVClass ogg_muxer_class = { - .class_name = "Ogg muxer", - .item_name = av_default_item_name, - .option = options, - .version = LIBAVUTIL_VERSION_INT, -}; - - -static void ogg_update_checksum(AVFormatContext *s, AVIOContext *pb, int64_t crc_offset) -{ - int64_t pos = avio_tell(pb); - uint32_t checksum = ffio_get_checksum(pb); - avio_seek(pb, crc_offset, SEEK_SET); - avio_wb32(pb, checksum); - avio_seek(pb, pos, SEEK_SET); -} - -static int ogg_write_page(AVFormatContext *s, OGGPage *page, int extra_flags) -{ - OGGStreamContext *oggstream = s->streams[page->stream_index]->priv_data; - AVIOContext *pb; - int64_t crc_offset; - int ret, size; - uint8_t *buf; - - ret = avio_open_dyn_buf(&pb); - if (ret < 0) - return ret; - ffio_init_checksum(pb, ff_crc04C11DB7_update, 0); - ffio_wfourcc(pb, "OggS"); - avio_w8(pb, 0); - avio_w8(pb, page->flags | extra_flags); - avio_wl64(pb, page->granule); - avio_wl32(pb, oggstream->serial_num); - avio_wl32(pb, oggstream->page_counter++); - crc_offset = avio_tell(pb); - avio_wl32(pb, 0); // crc - avio_w8(pb, page->segments_count); - avio_write(pb, page->segments, page->segments_count); - avio_write(pb, page->data, page->size); - - ogg_update_checksum(s, pb, crc_offset); - avio_flush(pb); - - size = avio_close_dyn_buf(pb, &buf); - if (size < 0) - return size; - - avio_write(s->pb, buf, size); - avio_flush(s->pb); - av_free(buf); - oggstream->page_count--; - return 0; -} - -static int ogg_key_granule(OGGStreamContext *oggstream, int64_t granule) -{ - return oggstream->kfgshift && !(granule & ((1<kfgshift)-1)); -} - -static int64_t ogg_granule_to_timestamp(OGGStreamContext *oggstream, int64_t granule) -{ - if (oggstream->kfgshift) - return (granule>>oggstream->kfgshift) + - (granule & ((1<kfgshift)-1)); - else - return granule; -} - -static int ogg_compare_granule(AVFormatContext *s, OGGPage *next, OGGPage *page) -{ - AVStream *st2 = s->streams[next->stream_index]; - AVStream *st = s->streams[page->stream_index]; - int64_t next_granule, cur_granule; - - if (next->granule == -1 || page->granule == -1) - return 0; - - next_granule = av_rescale_q(ogg_granule_to_timestamp(st2->priv_data, next->granule), - st2->time_base, AV_TIME_BASE_Q); - cur_granule = av_rescale_q(ogg_granule_to_timestamp(st->priv_data, page->granule), - st ->time_base, AV_TIME_BASE_Q); - return next_granule > cur_granule; -} - -static int ogg_reset_cur_page(OGGStreamContext *oggstream) -{ - oggstream->page.granule = -1; - oggstream->page.flags = 0; - oggstream->page.segments_count = 0; - oggstream->page.size = 0; - return 0; -} - -static int ogg_buffer_page(AVFormatContext *s, OGGStreamContext *oggstream) -{ - OGGContext *ogg = s->priv_data; - OGGPageList **p = &ogg->page_list; - OGGPageList *l = av_mallocz(sizeof(*l)); - - if (!l) - return AVERROR(ENOMEM); - l->page = oggstream->page; - - oggstream->page.start_granule = oggstream->page.granule; - oggstream->page_count++; - ogg_reset_cur_page(oggstream); - - while (*p) { - if (ogg_compare_granule(s, &(*p)->page, &l->page)) - break; - p = &(*p)->next; - } - l->next = *p; - *p = l; - - return 0; -} - -static int ogg_buffer_data(AVFormatContext *s, AVStream *st, - uint8_t *data, unsigned size, int64_t granule, - int header) -{ - OGGStreamContext *oggstream = st->priv_data; - OGGContext *ogg = s->priv_data; - int total_segments = size / 255 + 1; - uint8_t *p = data; - int i, segments, len, flush = 0; - - // Handles VFR by flushing page because this frame needs to have a timestamp - // For theora, keyframes also need to have a timestamp to correctly mark - // them as such, otherwise seeking will not work correctly at the very - // least with old libogg versions. - // Do not try to flush header packets though, that will create broken files. - if (st->codec->codec_id == AV_CODEC_ID_THEORA && !header && - (ogg_granule_to_timestamp(oggstream, granule) > - ogg_granule_to_timestamp(oggstream, oggstream->last_granule) + 1 || - ogg_key_granule(oggstream, granule))) { - if (oggstream->page.granule != -1) - ogg_buffer_page(s, oggstream); - flush = 1; - } - - // avoid a continued page - if (!header && oggstream->page.size > 0 && - MAX_PAGE_SIZE - oggstream->page.size < size) { - ogg_buffer_page(s, oggstream); - } - - for (i = 0; i < total_segments; ) { - OGGPage *page = &oggstream->page; - - segments = FFMIN(total_segments - i, 255 - page->segments_count); - - if (i && !page->segments_count) - page->flags |= 1; // continued packet - - memset(page->segments+page->segments_count, 255, segments - 1); - page->segments_count += segments - 1; - - len = FFMIN(size, segments*255); - page->segments[page->segments_count++] = len - (segments-1)*255; - memcpy(page->data+page->size, p, len); - p += len; - size -= len; - i += segments; - page->size += len; - - if (i == total_segments) - page->granule = granule; - - if (!header) { - AVStream *st = s->streams[page->stream_index]; - - int64_t start = av_rescale_q(page->start_granule, st->time_base, - AV_TIME_BASE_Q); - int64_t next = av_rescale_q(page->granule, st->time_base, - AV_TIME_BASE_Q); - - if (page->segments_count == 255 || - (ogg->pref_size > 0 && page->size >= ogg->pref_size) || - (ogg->pref_duration > 0 && next - start >= ogg->pref_duration)) { - ogg_buffer_page(s, oggstream); - } - } - } - - if (flush && oggstream->page.granule != -1) - ogg_buffer_page(s, oggstream); - - return 0; -} - -static uint8_t *ogg_write_vorbiscomment(int offset, int bitexact, - int *header_len, AVDictionary **m, int framing_bit) -{ - const char *vendor = bitexact ? "ffmpeg" : LIBAVFORMAT_IDENT; - int size; - uint8_t *p, *p0; - unsigned int count; - - ff_metadata_conv(m, ff_vorbiscomment_metadata_conv, NULL); - - size = offset + ff_vorbiscomment_length(*m, vendor, &count) + framing_bit; - p = av_mallocz(size); - if (!p) - return NULL; - p0 = p; - - p += offset; - ff_vorbiscomment_write(&p, m, vendor, count); - if (framing_bit) - bytestream_put_byte(&p, 1); - - *header_len = size; - return p0; -} - -static int ogg_build_flac_headers(AVCodecContext *avctx, - OGGStreamContext *oggstream, int bitexact, - AVDictionary **m) -{ - enum FLACExtradataFormat format; - uint8_t *streaminfo; - uint8_t *p; - - if (!avpriv_flac_is_extradata_valid(avctx, &format, &streaminfo)) - return -1; - - // first packet: STREAMINFO - oggstream->header_len[0] = 51; - oggstream->header[0] = av_mallocz(51); // per ogg flac specs - p = oggstream->header[0]; - if (!p) - return AVERROR(ENOMEM); - bytestream_put_byte(&p, 0x7F); - bytestream_put_buffer(&p, "FLAC", 4); - bytestream_put_byte(&p, 1); // major version - bytestream_put_byte(&p, 0); // minor version - bytestream_put_be16(&p, 1); // headers packets without this one - bytestream_put_buffer(&p, "fLaC", 4); - bytestream_put_byte(&p, 0x00); // streaminfo - bytestream_put_be24(&p, 34); - bytestream_put_buffer(&p, streaminfo, FLAC_STREAMINFO_SIZE); - - // second packet: VorbisComment - p = ogg_write_vorbiscomment(4, bitexact, &oggstream->header_len[1], m, 0); - if (!p) - return AVERROR(ENOMEM); - oggstream->header[1] = p; - bytestream_put_byte(&p, 0x84); // last metadata block and vorbis comment - bytestream_put_be24(&p, oggstream->header_len[1] - 4); - - return 0; -} - -#define SPEEX_HEADER_SIZE 80 - -static int ogg_build_speex_headers(AVCodecContext *avctx, - OGGStreamContext *oggstream, int bitexact, - AVDictionary **m) -{ - uint8_t *p; - - if (avctx->extradata_size < SPEEX_HEADER_SIZE) - return -1; - - // first packet: Speex header - p = av_mallocz(SPEEX_HEADER_SIZE); - if (!p) - return AVERROR(ENOMEM); - oggstream->header[0] = p; - oggstream->header_len[0] = SPEEX_HEADER_SIZE; - bytestream_put_buffer(&p, avctx->extradata, SPEEX_HEADER_SIZE); - AV_WL32(&oggstream->header[0][68], 0); // set extra_headers to 0 - - // second packet: VorbisComment - p = ogg_write_vorbiscomment(0, bitexact, &oggstream->header_len[1], m, 0); - if (!p) - return AVERROR(ENOMEM); - oggstream->header[1] = p; - - return 0; -} - -#define OPUS_HEADER_SIZE 19 - -static int ogg_build_opus_headers(AVCodecContext *avctx, - OGGStreamContext *oggstream, int bitexact, - AVDictionary **m) -{ - uint8_t *p; - - if (avctx->extradata_size < OPUS_HEADER_SIZE) - return -1; - - /* first packet: Opus header */ - p = av_mallocz(avctx->extradata_size); - if (!p) - return AVERROR(ENOMEM); - oggstream->header[0] = p; - oggstream->header_len[0] = avctx->extradata_size; - bytestream_put_buffer(&p, avctx->extradata, avctx->extradata_size); - - /* second packet: VorbisComment */ - p = ogg_write_vorbiscomment(8, bitexact, &oggstream->header_len[1], m, 0); - if (!p) - return AVERROR(ENOMEM); - oggstream->header[1] = p; - bytestream_put_buffer(&p, "OpusTags", 8); - - return 0; -} - -static int ogg_write_header(AVFormatContext *s) -{ - OGGContext *ogg = s->priv_data; - OGGStreamContext *oggstream = NULL; - int i, j; - - if (ogg->pref_size) - av_log(s, AV_LOG_WARNING, "The pagesize option is deprecated\n"); - - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - unsigned serial_num = i; - - if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO) { - if (st->codec->codec_id == AV_CODEC_ID_OPUS) - /* Opus requires a fixed 48kHz clock */ - avpriv_set_pts_info(st, 64, 1, 48000); - else - avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); - } else if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) - avpriv_set_pts_info(st, 64, st->codec->time_base.num, st->codec->time_base.den); - if (st->codec->codec_id != AV_CODEC_ID_VORBIS && - st->codec->codec_id != AV_CODEC_ID_THEORA && - st->codec->codec_id != AV_CODEC_ID_SPEEX && - st->codec->codec_id != AV_CODEC_ID_FLAC && - st->codec->codec_id != AV_CODEC_ID_OPUS) { - av_log(s, AV_LOG_ERROR, "Unsupported codec id in stream %d\n", i); - return -1; - } - - if (!st->codec->extradata || !st->codec->extradata_size) { - av_log(s, AV_LOG_ERROR, "No extradata present\n"); - return -1; - } - oggstream = av_mallocz(sizeof(*oggstream)); - oggstream->page.stream_index = i; - - if (!(st->codec->flags & CODEC_FLAG_BITEXACT)) - do { - serial_num = av_get_random_seed(); - for (j = 0; j < i; j++) { - OGGStreamContext *sc = s->streams[j]->priv_data; - if (serial_num == sc->serial_num) - break; - } - } while (j < i); - oggstream->serial_num = serial_num; - - st->priv_data = oggstream; - if (st->codec->codec_id == AV_CODEC_ID_FLAC) { - int err = ogg_build_flac_headers(st->codec, oggstream, - st->codec->flags & CODEC_FLAG_BITEXACT, - &s->metadata); - if (err) { - av_log(s, AV_LOG_ERROR, "Error writing FLAC headers\n"); - av_freep(&st->priv_data); - return err; - } - } else if (st->codec->codec_id == AV_CODEC_ID_SPEEX) { - int err = ogg_build_speex_headers(st->codec, oggstream, - st->codec->flags & CODEC_FLAG_BITEXACT, - &s->metadata); - if (err) { - av_log(s, AV_LOG_ERROR, "Error writing Speex headers\n"); - av_freep(&st->priv_data); - return err; - } - } else if (st->codec->codec_id == AV_CODEC_ID_OPUS) { - int err = ogg_build_opus_headers(st->codec, oggstream, - st->codec->flags & CODEC_FLAG_BITEXACT, - &s->metadata); - if (err) { - av_log(s, AV_LOG_ERROR, "Error writing Opus headers\n"); - av_freep(&st->priv_data); - return err; - } - } else { - uint8_t *p; - const char *cstr = st->codec->codec_id == AV_CODEC_ID_VORBIS ? "vorbis" : "theora"; - int header_type = st->codec->codec_id == AV_CODEC_ID_VORBIS ? 3 : 0x81; - int framing_bit = st->codec->codec_id == AV_CODEC_ID_VORBIS ? 1 : 0; - - if (avpriv_split_xiph_headers(st->codec->extradata, st->codec->extradata_size, - st->codec->codec_id == AV_CODEC_ID_VORBIS ? 30 : 42, - oggstream->header, oggstream->header_len) < 0) { - av_log(s, AV_LOG_ERROR, "Extradata corrupted\n"); - av_freep(&st->priv_data); - return -1; - } - - p = ogg_write_vorbiscomment(7, st->codec->flags & CODEC_FLAG_BITEXACT, - &oggstream->header_len[1], &s->metadata, - framing_bit); - oggstream->header[1] = p; - if (!p) - return AVERROR(ENOMEM); - - bytestream_put_byte(&p, header_type); - bytestream_put_buffer(&p, cstr, 6); - - if (st->codec->codec_id == AV_CODEC_ID_THEORA) { - /** KFGSHIFT is the width of the less significant section of the granule position - The less significant section is the frame count since the last keyframe */ - oggstream->kfgshift = ((oggstream->header[0][40]&3)<<3)|(oggstream->header[0][41]>>5); - oggstream->vrev = oggstream->header[0][9]; - av_log(s, AV_LOG_DEBUG, "theora kfgshift %d, vrev %d\n", - oggstream->kfgshift, oggstream->vrev); - } - } - } - - for (j = 0; j < s->nb_streams; j++) { - OGGStreamContext *oggstream = s->streams[j]->priv_data; - ogg_buffer_data(s, s->streams[j], oggstream->header[0], - oggstream->header_len[0], 0, 1); - oggstream->page.flags |= 2; // bos - ogg_buffer_page(s, oggstream); - } - for (j = 0; j < s->nb_streams; j++) { - AVStream *st = s->streams[j]; - OGGStreamContext *oggstream = st->priv_data; - for (i = 1; i < 3; i++) { - if (oggstream->header_len[i]) - ogg_buffer_data(s, st, oggstream->header[i], - oggstream->header_len[i], 0, 1); - } - ogg_buffer_page(s, oggstream); - } - - oggstream->page.start_granule = AV_NOPTS_VALUE; - - return 0; -} - -static void ogg_write_pages(AVFormatContext *s, int flush) -{ - OGGContext *ogg = s->priv_data; - OGGPageList *next, *p; - - if (!ogg->page_list) - return; - - for (p = ogg->page_list; p; ) { - OGGStreamContext *oggstream = - s->streams[p->page.stream_index]->priv_data; - if (oggstream->page_count < 2 && !flush) - break; - ogg_write_page(s, &p->page, - flush && oggstream->page_count == 1 ? 4 : 0); // eos - next = p->next; - av_freep(&p); - p = next; - } - ogg->page_list = p; -} - -static int ogg_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - AVStream *st = s->streams[pkt->stream_index]; - OGGStreamContext *oggstream = st->priv_data; - int ret; - int64_t granule; - - if (st->codec->codec_id == AV_CODEC_ID_THEORA) { - int64_t pts = oggstream->vrev < 1 ? pkt->pts : pkt->pts + pkt->duration; - int pframe_count; - if (pkt->flags & AV_PKT_FLAG_KEY) - oggstream->last_kf_pts = pts; - pframe_count = pts - oggstream->last_kf_pts; - // prevent frame count from overflow if key frame flag is not set - if (pframe_count >= (1<kfgshift)) { - oggstream->last_kf_pts += pframe_count; - pframe_count = 0; - } - granule = (oggstream->last_kf_pts<kfgshift) | pframe_count; - } else if (st->codec->codec_id == AV_CODEC_ID_OPUS) - granule = pkt->pts + pkt->duration + av_rescale_q(st->codec->delay, (AVRational){ 1, st->codec->sample_rate }, st->time_base); - else - granule = pkt->pts + pkt->duration; - - if (oggstream->page.start_granule == AV_NOPTS_VALUE) - oggstream->page.start_granule = pkt->pts; - - ret = ogg_buffer_data(s, st, pkt->data, pkt->size, granule, 0); - if (ret < 0) - return ret; - - ogg_write_pages(s, 0); - - oggstream->last_granule = granule; - - return 0; -} - -static int ogg_write_trailer(AVFormatContext *s) -{ - int i; - - /* flush current page if needed */ - for (i = 0; i < s->nb_streams; i++) { - OGGStreamContext *oggstream = s->streams[i]->priv_data; - - if (oggstream->page.size > 0) - ogg_buffer_page(s, oggstream); - } - - ogg_write_pages(s, 1); - - for (i = 0; i < s->nb_streams; i++) { - AVStream *st = s->streams[i]; - OGGStreamContext *oggstream = st->priv_data; - if (st->codec->codec_id == AV_CODEC_ID_FLAC || - st->codec->codec_id == AV_CODEC_ID_SPEEX || - st->codec->codec_id == AV_CODEC_ID_OPUS) { - av_freep(&oggstream->header[0]); - } - av_freep(&oggstream->header[1]); - av_freep(&st->priv_data); - } - return 0; -} - -AVOutputFormat ff_ogg_muxer = { - .name = "ogg", - .long_name = NULL_IF_CONFIG_SMALL("Ogg"), - .mime_type = "application/ogg", - .extensions = "ogg,ogv,spx,opus", - .priv_data_size = sizeof(OGGContext), - .audio_codec = AV_CODEC_ID_FLAC, - .video_codec = AV_CODEC_ID_THEORA, - .write_header = ogg_write_header, - .write_packet = ogg_write_packet, - .write_trailer = ogg_write_trailer, - .priv_class = &ogg_muxer_class, -}; diff --git a/ffmpeg1/libavformat/oggparsecelt.c b/ffmpeg1/libavformat/oggparsecelt.c deleted file mode 100644 index afc4392..0000000 --- a/ffmpeg1/libavformat/oggparsecelt.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Xiph CELT parser for Ogg - * Copyright (c) 2011 Nicolas George - * - * 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 - -#include "libavutil/intreadwrite.h" -#include "avformat.h" -#include "internal.h" -#include "oggdec.h" - -struct oggcelt_private { - int extra_headers_left; -}; - -static int celt_header(AVFormatContext *s, int idx) -{ - struct ogg *ogg = s->priv_data; - struct ogg_stream *os = ogg->streams + idx; - AVStream *st = s->streams[idx]; - struct oggcelt_private *priv = os->private; - uint8_t *p = os->buf + os->pstart; - - if (os->psize == 60 && - !memcmp(p, ff_celt_codec.magic, ff_celt_codec.magicsize)) { - /* Main header */ - - uint32_t version, sample_rate, nb_channels, frame_size; - uint32_t overlap, extra_headers; - uint8_t *extradata; - - extradata = av_malloc(2 * sizeof(uint32_t) + - FF_INPUT_BUFFER_PADDING_SIZE); - priv = av_malloc(sizeof(struct oggcelt_private)); - if (!extradata || !priv) { - av_free(extradata); - av_free(priv); - return AVERROR(ENOMEM); - } - version = AV_RL32(p + 28); - /* unused header size field skipped */ - sample_rate = AV_RL32(p + 36); - nb_channels = AV_RL32(p + 40); - frame_size = AV_RL32(p + 44); - overlap = AV_RL32(p + 48); - /* unused bytes per packet field skipped */ - extra_headers = AV_RL32(p + 56); - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = AV_CODEC_ID_CELT; - st->codec->sample_rate = sample_rate; - st->codec->channels = nb_channels; - st->codec->frame_size = frame_size; - av_free(st->codec->extradata); - st->codec->extradata = extradata; - st->codec->extradata_size = 2 * sizeof(uint32_t); - if (sample_rate) - avpriv_set_pts_info(st, 64, 1, sample_rate); - priv->extra_headers_left = 1 + extra_headers; - av_free(os->private); - os->private = priv; - AV_WL32(extradata + 0, overlap); - AV_WL32(extradata + 4, version); - return 1; - } else if (priv && priv->extra_headers_left) { - /* Extra headers (vorbiscomment) */ - - ff_vorbis_comment(s, &st->metadata, p, os->psize); - priv->extra_headers_left--; - return 1; - } else { - return 0; - } -} - -const struct ogg_codec ff_celt_codec = { - .magic = "CELT ", - .magicsize = 8, - .header = celt_header, - .nb_header = 2, -}; diff --git a/ffmpeg1/libavformat/oggparsedirac.c b/ffmpeg1/libavformat/oggparsedirac.c deleted file mode 100644 index 73bc495..0000000 --- a/ffmpeg1/libavformat/oggparsedirac.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (C) 2008 David Conrad - * - * 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 "libavcodec/get_bits.h" -#include "libavcodec/dirac.h" -#include "avformat.h" -#include "internal.h" -#include "oggdec.h" - -static int dirac_header(AVFormatContext *s, int idx) -{ - struct ogg *ogg = s->priv_data; - struct ogg_stream *os = ogg->streams + idx; - AVStream *st = s->streams[idx]; - dirac_source_params source; - GetBitContext gb; - - // already parsed the header - if (st->codec->codec_id == AV_CODEC_ID_DIRAC) - return 0; - - init_get_bits(&gb, os->buf + os->pstart + 13, (os->psize - 13) * 8); - if (avpriv_dirac_parse_sequence_header(st->codec, &gb, &source) < 0) - return -1; - - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = AV_CODEC_ID_DIRAC; - // dirac in ogg always stores timestamps as though the video were interlaced - avpriv_set_pts_info(st, 64, st->codec->time_base.num, 2*st->codec->time_base.den); - return 1; -} - -// various undocument things: granule is signed (only for dirac!) -static uint64_t dirac_gptopts(AVFormatContext *s, int idx, uint64_t granule, - int64_t *dts_out) -{ - int64_t gp = granule; - struct ogg *ogg = s->priv_data; - struct ogg_stream *os = ogg->streams + idx; - - unsigned dist = ((gp >> 14) & 0xff00) | (gp & 0xff); - int64_t dts = (gp >> 31); - int64_t pts = dts + ((gp >> 9) & 0x1fff); - - if (!dist) - os->pflags |= AV_PKT_FLAG_KEY; - - if (dts_out) - *dts_out = dts; - - return pts; -} - -static int old_dirac_header(AVFormatContext *s, int idx) -{ - struct ogg *ogg = s->priv_data; - struct ogg_stream *os = ogg->streams + idx; - AVStream *st = s->streams[idx]; - uint8_t *buf = os->buf + os->pstart; - - if (buf[0] != 'K') - return 0; - - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = AV_CODEC_ID_DIRAC; - avpriv_set_pts_info(st, 64, AV_RB32(buf+12), AV_RB32(buf+8)); - return 1; -} - -static uint64_t old_dirac_gptopts(AVFormatContext *s, int idx, uint64_t gp, - int64_t *dts) -{ - struct ogg *ogg = s->priv_data; - struct ogg_stream *os = ogg->streams + idx; - uint64_t iframe = gp >> 30; - uint64_t pframe = gp & 0x3fffffff; - - if (!pframe) - os->pflags |= AV_PKT_FLAG_KEY; - - return iframe + pframe; -} - -const struct ogg_codec ff_dirac_codec = { - .magic = "BBCD\0", - .magicsize = 5, - .header = dirac_header, - .gptopts = dirac_gptopts, - .granule_is_start = 1, - .nb_header = 1, -}; - -const struct ogg_codec ff_old_dirac_codec = { - .magic = "KW-DIRAC", - .magicsize = 8, - .header = old_dirac_header, - .gptopts = old_dirac_gptopts, - .granule_is_start = 1, - .nb_header = 1, -}; diff --git a/ffmpeg1/libavformat/oggparseflac.c b/ffmpeg1/libavformat/oggparseflac.c deleted file mode 100644 index 3ff594e..0000000 --- a/ffmpeg1/libavformat/oggparseflac.c +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2005 Matthieu CASTET - * - * 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 -#include "libavcodec/get_bits.h" -#include "libavcodec/flac.h" -#include "avformat.h" -#include "internal.h" -#include "oggdec.h" - -#define OGG_FLAC_METADATA_TYPE_STREAMINFO 0x7F - -static int -flac_header (AVFormatContext * s, int idx) -{ - struct ogg *ogg = s->priv_data; - struct ogg_stream *os = ogg->streams + idx; - AVStream *st = s->streams[idx]; - GetBitContext gb; - FLACStreaminfo si; - int mdt; - - if (os->buf[os->pstart] == 0xff) - return 0; - - init_get_bits(&gb, os->buf + os->pstart, os->psize*8); - skip_bits1(&gb); /* metadata_last */ - mdt = get_bits(&gb, 7); - - if (mdt == OGG_FLAC_METADATA_TYPE_STREAMINFO) { - uint8_t *streaminfo_start = os->buf + os->pstart + 5 + 4 + 4 + 4; - skip_bits_long(&gb, 4*8); /* "FLAC" */ - if(get_bits(&gb, 8) != 1) /* unsupported major version */ - return -1; - skip_bits_long(&gb, 8 + 16); /* minor version + header count */ - skip_bits_long(&gb, 4*8); /* "fLaC" */ - - /* METADATA_BLOCK_HEADER */ - if (get_bits_long(&gb, 32) != FLAC_STREAMINFO_SIZE) - return -1; - - avpriv_flac_parse_streaminfo(st->codec, &si, streaminfo_start); - - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = AV_CODEC_ID_FLAC; - st->need_parsing = AVSTREAM_PARSE_HEADERS; - - st->codec->extradata = - av_malloc(FLAC_STREAMINFO_SIZE + FF_INPUT_BUFFER_PADDING_SIZE); - memcpy(st->codec->extradata, streaminfo_start, FLAC_STREAMINFO_SIZE); - st->codec->extradata_size = FLAC_STREAMINFO_SIZE; - - avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); - } else if (mdt == FLAC_METADATA_TYPE_VORBIS_COMMENT) { - ff_vorbis_comment (s, &st->metadata, os->buf + os->pstart + 4, os->psize - 4); - } - - return 1; -} - -static int -old_flac_header (AVFormatContext * s, int idx) -{ - AVStream *st = s->streams[idx]; - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = AV_CODEC_ID_FLAC; - - return 0; -} - -const struct ogg_codec ff_flac_codec = { - .magic = "\177FLAC", - .magicsize = 5, - .header = flac_header, - .nb_header = 2, -}; - -const struct ogg_codec ff_old_flac_codec = { - .magic = "fLaC", - .magicsize = 4, - .header = old_flac_header, - .nb_header = 0, -}; diff --git a/ffmpeg1/libavformat/oggparseogm.c b/ffmpeg1/libavformat/oggparseogm.c deleted file mode 100644 index a3caac0..0000000 --- a/ffmpeg1/libavformat/oggparseogm.c +++ /dev/null @@ -1,202 +0,0 @@ -/** - Copyright (C) 2005 Michael Ahlberg, MÃ¥ns RullgÃ¥rd - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -**/ - -#include -#include "libavutil/avassert.h" -#include "libavutil/intreadwrite.h" -#include "libavcodec/get_bits.h" -#include "libavcodec/bytestream.h" -#include "avformat.h" -#include "internal.h" -#include "oggdec.h" -#include "riff.h" - -static int -ogm_header(AVFormatContext *s, int idx) -{ - struct ogg *ogg = s->priv_data; - struct ogg_stream *os = ogg->streams + idx; - AVStream *st = s->streams[idx]; - const uint8_t *p = os->buf + os->pstart; - uint64_t time_unit; - uint64_t spu; - uint32_t size; - - if(!(*p & 1)) - return 0; - - if(*p == 1) { - p++; - - if(*p == 'v'){ - int tag; - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - p += 8; - tag = bytestream_get_le32(&p); - st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, tag); - st->codec->codec_tag = tag; - } else if (*p == 't') { - st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE; - st->codec->codec_id = AV_CODEC_ID_TEXT; - p += 12; - } else { - uint8_t acid[5]; - int cid; - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - p += 8; - bytestream_get_buffer(&p, acid, 4); - acid[4] = 0; - cid = strtol(acid, NULL, 16); - st->codec->codec_id = ff_codec_get_id(ff_codec_wav_tags, cid); - // our parser completely breaks AAC in Ogg - if (st->codec->codec_id != AV_CODEC_ID_AAC) - st->need_parsing = AVSTREAM_PARSE_FULL; - } - - size = bytestream_get_le32(&p); - size = FFMIN(size, os->psize); - time_unit = bytestream_get_le64(&p); - spu = bytestream_get_le64(&p); - p += 4; /* default_len */ - p += 8; /* buffersize + bits_per_sample */ - - if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO){ - st->codec->width = bytestream_get_le32(&p); - st->codec->height = bytestream_get_le32(&p); - avpriv_set_pts_info(st, 64, time_unit, spu * 10000000); - } else { - st->codec->channels = bytestream_get_le16(&p); - p += 2; /* block_align */ - st->codec->bit_rate = bytestream_get_le32(&p) * 8; - st->codec->sample_rate = time_unit ? spu * 10000000 / time_unit : 0; - avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); - if (size >= 56 && st->codec->codec_id == AV_CODEC_ID_AAC) { - p += 4; - size -= 4; - } - if (size > 52) { - av_assert0(FF_INPUT_BUFFER_PADDING_SIZE <= 52); - size -= 52; - st->codec->extradata_size = size; - st->codec->extradata = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE); - bytestream_get_buffer(&p, st->codec->extradata, size); - } - } - } else if (*p == 3) { - if (os->psize > 8) - ff_vorbis_comment(s, &st->metadata, p+7, os->psize-8); - } - - return 1; -} - -static int -ogm_dshow_header(AVFormatContext *s, int idx) -{ - struct ogg *ogg = s->priv_data; - struct ogg_stream *os = ogg->streams + idx; - AVStream *st = s->streams[idx]; - uint8_t *p = os->buf + os->pstart; - uint32_t t; - - if(!(*p & 1)) - return 0; - if(*p != 1) - return 1; - - t = AV_RL32(p + 96); - - if(t == 0x05589f80){ - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, AV_RL32(p + 68)); - avpriv_set_pts_info(st, 64, AV_RL64(p + 164), 10000000); - st->codec->width = AV_RL32(p + 176); - st->codec->height = AV_RL32(p + 180); - } else if(t == 0x05589f81){ - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = ff_codec_get_id(ff_codec_wav_tags, AV_RL16(p + 124)); - st->codec->channels = AV_RL16(p + 126); - st->codec->sample_rate = AV_RL32(p + 128); - st->codec->bit_rate = AV_RL32(p + 132) * 8; - } - - return 1; -} - -static int -ogm_packet(AVFormatContext *s, int idx) -{ - struct ogg *ogg = s->priv_data; - struct ogg_stream *os = ogg->streams + idx; - uint8_t *p = os->buf + os->pstart; - int lb; - - if(*p & 8) - os->pflags |= AV_PKT_FLAG_KEY; - - lb = ((*p & 2) << 1) | ((*p >> 6) & 3); - os->pstart += lb + 1; - os->psize -= lb + 1; - - while (lb--) - os->pduration += p[lb+1] << (lb*8); - - return 0; -} - -const struct ogg_codec ff_ogm_video_codec = { - .magic = "\001video", - .magicsize = 6, - .header = ogm_header, - .packet = ogm_packet, - .granule_is_start = 1, - .nb_header = 2, -}; - -const struct ogg_codec ff_ogm_audio_codec = { - .magic = "\001audio", - .magicsize = 6, - .header = ogm_header, - .packet = ogm_packet, - .granule_is_start = 1, - .nb_header = 2, -}; - -const struct ogg_codec ff_ogm_text_codec = { - .magic = "\001text", - .magicsize = 5, - .header = ogm_header, - .packet = ogm_packet, - .granule_is_start = 1, - .nb_header = 2, -}; - -const struct ogg_codec ff_ogm_old_codec = { - .magic = "\001Direct Show Samples embedded in Ogg", - .magicsize = 35, - .header = ogm_dshow_header, - .packet = ogm_packet, - .granule_is_start = 1, - .nb_header = 1, -}; diff --git a/ffmpeg1/libavformat/oggparseopus.c b/ffmpeg1/libavformat/oggparseopus.c deleted file mode 100644 index 0e8f1ca..0000000 --- a/ffmpeg1/libavformat/oggparseopus.c +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Opus parser for Ogg - * Copyright (c) 2012 Nicolas George - * - * 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 - -#include "libavutil/intreadwrite.h" -#include "avformat.h" -#include "internal.h" -#include "oggdec.h" - -struct oggopus_private { - int need_comments; - unsigned pre_skip; - int64_t cur_dts; -}; - -#define OPUS_HEAD_SIZE 19 - -static int opus_header(AVFormatContext *avf, int idx) -{ - struct ogg *ogg = avf->priv_data; - struct ogg_stream *os = &ogg->streams[idx]; - AVStream *st = avf->streams[idx]; - struct oggopus_private *priv = os->private; - uint8_t *packet = os->buf + os->pstart; - uint8_t *extradata; - - if (!priv) { - priv = os->private = av_mallocz(sizeof(*priv)); - if (!priv) - return AVERROR(ENOMEM); - } - if (os->flags & OGG_FLAG_BOS) { - if (os->psize < OPUS_HEAD_SIZE || (AV_RL8(packet + 8) & 0xF0) != 0) - return AVERROR_INVALIDDATA; - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = AV_CODEC_ID_OPUS; - st->codec->channels = AV_RL8 (packet + 9); - priv->pre_skip = AV_RL16(packet + 10); - /*orig_sample_rate = AV_RL32(packet + 12);*/ - /*gain = AV_RL16(packet + 16);*/ - /*channel_map = AV_RL8 (packet + 18);*/ - - extradata = av_malloc(os->psize + FF_INPUT_BUFFER_PADDING_SIZE); - if (!extradata) - return AVERROR(ENOMEM); - memcpy(extradata, packet, os->psize); - st->codec->extradata = extradata; - st->codec->extradata_size = os->psize; - - st->codec->sample_rate = 48000; - avpriv_set_pts_info(st, 64, 1, 48000); - priv->need_comments = 1; - return 1; - } - - if (priv->need_comments) { - if (os->psize < 8 || memcmp(packet, "OpusTags", 8)) - return AVERROR_INVALIDDATA; - ff_vorbis_comment(avf, &st->metadata, packet + 8, os->psize - 8); - priv->need_comments--; - return 1; - } - return 0; -} - -static int opus_packet(AVFormatContext *avf, int idx) -{ - struct ogg *ogg = avf->priv_data; - struct ogg_stream *os = &ogg->streams[idx]; - AVStream *st = avf->streams[idx]; - struct oggopus_private *priv = os->private; - uint8_t *packet = os->buf + os->pstart; - unsigned toc, toc_config, toc_count, frame_size, nb_frames = 1; - - if (!os->psize) - return AVERROR_INVALIDDATA; - toc = *packet; - toc_config = toc >> 3; - toc_count = toc & 3; - frame_size = toc_config < 12 ? FFMAX(480, 960 * (toc_config & 3)) : - toc_config < 16 ? 480 << (toc_config & 1) : - 120 << (toc_config & 3); - if (toc_count == 3) { - if (os->psize < 2) - return AVERROR_INVALIDDATA; - nb_frames = packet[1] & 0x3F; - } else if (toc_count) { - nb_frames = 2; - } - os->pduration = frame_size * nb_frames; - if (os->lastpts != AV_NOPTS_VALUE) { - if (st->start_time == AV_NOPTS_VALUE) - st->start_time = os->lastpts; - priv->cur_dts = os->lastdts = os->lastpts -= priv->pre_skip; - } - priv->cur_dts += os->pduration; - if ((os->flags & OGG_FLAG_EOS)) { - int64_t skip = priv->cur_dts - os->granule + priv->pre_skip; - skip = FFMIN(skip, os->pduration); - if (skip > 0) { - os->pduration = skip < os->pduration ? os->pduration - skip : 1; - av_log(avf, AV_LOG_WARNING, - "Last packet must be truncated to %d (unimplemented).\n", - os->pduration); - } - } - return 0; -} - -const struct ogg_codec ff_opus_codec = { - .name = "Opus", - .magic = "OpusHead", - .magicsize = 8, - .header = opus_header, - .packet = opus_packet, -}; diff --git a/ffmpeg1/libavformat/oggparseskeleton.c b/ffmpeg1/libavformat/oggparseskeleton.c deleted file mode 100644 index 307387d..0000000 --- a/ffmpeg1/libavformat/oggparseskeleton.c +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (C) 2010 David Conrad - * - * 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 "libavcodec/bytestream.h" -#include "avformat.h" -#include "internal.h" -#include "oggdec.h" - -static int skeleton_header(AVFormatContext *s, int idx) -{ - struct ogg *ogg = s->priv_data; - struct ogg_stream *os = ogg->streams + idx; - AVStream *st = s->streams[idx]; - uint8_t *buf = os->buf + os->pstart; - int version_major, version_minor; - int64_t start_num, start_den; - uint64_t start_granule; - int target_idx, start_time; - - strcpy(st->codec->codec_name, "skeleton"); - st->codec->codec_type = AVMEDIA_TYPE_DATA; - - if (os->psize < 8) - return -1; - - if (!strncmp(buf, "fishead", 8)) { - if (os->psize < 64) - return -1; - - version_major = AV_RL16(buf+8); - version_minor = AV_RL16(buf+10); - - if (version_major != 3 && version_major != 4) { - av_log(s, AV_LOG_WARNING, "Unknown skeleton version %d.%d\n", - version_major, version_minor); - return -1; - } - - // This is the overall start time. We use it for the start time of - // of the skeleton stream since if left unset lavf assumes 0, - // which we don't want since skeleton is timeless - // FIXME: the real meaning of this field is "start playback at - // this time which can be in the middle of a packet - start_num = AV_RL64(buf+12); - start_den = AV_RL64(buf+20); - - if (start_den > 0 && start_num > 0) { - int base_den; - av_reduce(&start_time, &base_den, start_num, start_den, INT_MAX); - avpriv_set_pts_info(st, 64, 1, base_den); - os->lastpts = - st->start_time = start_time; - } - } else if (!strncmp(buf, "fisbone", 8)) { - if (os->psize < 52) - return -1; - - target_idx = ogg_find_stream(ogg, AV_RL32(buf+12)); - start_granule = AV_RL64(buf+36); - if (os->start_granule != OGG_NOGRANULE_VALUE) { - avpriv_report_missing_feature(s, - "Multiple fisbone for the same stream"); - return 1; - } - if (target_idx >= 0 && start_granule != OGG_NOGRANULE_VALUE) { - os->start_granule = start_granule; - } - } - - return 1; -} - -const struct ogg_codec ff_skeleton_codec = { - .magic = "fishead", - .magicsize = 8, - .header = skeleton_header, - .nb_header = 0, -}; diff --git a/ffmpeg1/libavformat/oggparsespeex.c b/ffmpeg1/libavformat/oggparsespeex.c deleted file mode 100644 index 63e6370..0000000 --- a/ffmpeg1/libavformat/oggparsespeex.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - Copyright (C) 2008 Reimar Döffinger - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -**/ - -#include -#include "libavutil/bswap.h" -#include "libavutil/avstring.h" -#include "libavutil/channel_layout.h" -#include "libavcodec/get_bits.h" -#include "libavcodec/bytestream.h" -#include "avformat.h" -#include "internal.h" -#include "oggdec.h" - -struct speex_params { - int packet_size; - int final_packet_duration; - int seq; -}; - -static int speex_header(AVFormatContext *s, int idx) { - struct ogg *ogg = s->priv_data; - struct ogg_stream *os = ogg->streams + idx; - struct speex_params *spxp = os->private; - AVStream *st = s->streams[idx]; - uint8_t *p = os->buf + os->pstart; - - if (!spxp) { - spxp = av_mallocz(sizeof(*spxp)); - os->private = spxp; - } - - if (spxp->seq > 1) - return 0; - - if (spxp->seq == 0) { - int frames_per_packet; - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = AV_CODEC_ID_SPEEX; - - if (os->psize < 68) { - av_log(s, AV_LOG_ERROR, "speex packet too small\n"); - return AVERROR_INVALIDDATA; - } - - st->codec->sample_rate = AV_RL32(p + 36); - st->codec->channels = AV_RL32(p + 48); - if (st->codec->channels < 1 || st->codec->channels > 2) { - av_log(s, AV_LOG_ERROR, "invalid channel count. Speex must be mono or stereo.\n"); - return AVERROR_INVALIDDATA; - } - st->codec->channel_layout = st->codec->channels == 1 ? AV_CH_LAYOUT_MONO : - AV_CH_LAYOUT_STEREO; - - spxp->packet_size = AV_RL32(p + 56); - frames_per_packet = AV_RL32(p + 64); - if (frames_per_packet) - spxp->packet_size *= frames_per_packet; - - st->codec->extradata_size = os->psize; - st->codec->extradata = av_malloc(st->codec->extradata_size - + FF_INPUT_BUFFER_PADDING_SIZE); - memcpy(st->codec->extradata, p, st->codec->extradata_size); - - avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); - } else - ff_vorbis_comment(s, &st->metadata, p, os->psize); - - spxp->seq++; - return 1; -} - -static int ogg_page_packets(struct ogg_stream *os) -{ - int i; - int packets = 0; - for (i = 0; i < os->nsegs; i++) - if (os->segments[i] < 255) - packets++; - return packets; -} - -static int speex_packet(AVFormatContext *s, int idx) -{ - struct ogg *ogg = s->priv_data; - struct ogg_stream *os = ogg->streams + idx; - struct speex_params *spxp = os->private; - int packet_size = spxp->packet_size; - - if (os->flags & OGG_FLAG_EOS && os->lastpts != AV_NOPTS_VALUE && - os->granule > 0) { - /* first packet of final page. we have to calculate the final packet - duration here because it is the only place we know the next-to-last - granule position. */ - spxp->final_packet_duration = os->granule - os->lastpts - - packet_size * (ogg_page_packets(os) - 1); - } - - if (!os->lastpts && os->granule > 0) - /* first packet */ - os->lastpts = os->lastdts = os->granule - packet_size * - ogg_page_packets(os); - if (os->flags & OGG_FLAG_EOS && os->segp == os->nsegs && - spxp->final_packet_duration) - /* final packet */ - os->pduration = spxp->final_packet_duration; - else - os->pduration = packet_size; - - return 0; -} - -const struct ogg_codec ff_speex_codec = { - .magic = "Speex ", - .magicsize = 8, - .header = speex_header, - .packet = speex_packet, - .nb_header = 2, -}; diff --git a/ffmpeg1/libavformat/oggparsetheora.c b/ffmpeg1/libavformat/oggparsetheora.c deleted file mode 100644 index 6877d1e..0000000 --- a/ffmpeg1/libavformat/oggparsetheora.c +++ /dev/null @@ -1,206 +0,0 @@ -/** - Copyright (C) 2005 Matthieu CASTET, Alex Beregszaszi - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -**/ - -#include -#include "libavutil/bswap.h" -#include "libavcodec/get_bits.h" -#include "avformat.h" -#include "internal.h" -#include "oggdec.h" - -struct theora_params { - int gpshift; - int gpmask; - unsigned version; -}; - -static int -theora_header (AVFormatContext * s, int idx) -{ - struct ogg *ogg = s->priv_data; - struct ogg_stream *os = ogg->streams + idx; - AVStream *st = s->streams[idx]; - struct theora_params *thp = os->private; - int cds = st->codec->extradata_size + os->psize + 2; - uint8_t *cdp; - - if(!(os->buf[os->pstart] & 0x80)) - return 0; - - if(!thp){ - thp = av_mallocz(sizeof(*thp)); - os->private = thp; - } - - switch (os->buf[os->pstart]) { - case 0x80: { - GetBitContext gb; - int width, height; - AVRational timebase; - - init_get_bits(&gb, os->buf + os->pstart, os->psize*8); - - skip_bits_long(&gb, 7*8); /* 0x80"theora" */ - - thp->version = get_bits_long(&gb, 24); - if (thp->version < 0x030100) - { - av_log(s, AV_LOG_ERROR, - "Too old or unsupported Theora (%x)\n", thp->version); - return -1; - } - - width = get_bits(&gb, 16) << 4; - height = get_bits(&gb, 16) << 4; - avcodec_set_dimensions(st->codec, width, height); - - if (thp->version >= 0x030400) - skip_bits(&gb, 100); - - if (thp->version >= 0x030200) { - width = get_bits_long(&gb, 24); - height = get_bits_long(&gb, 24); - if ( width <= st->codec->width && width > st->codec->width-16 - && height <= st->codec->height && height > st->codec->height-16) - avcodec_set_dimensions(st->codec, width, height); - - skip_bits(&gb, 16); - } - timebase.den = get_bits_long(&gb, 32); - timebase.num = get_bits_long(&gb, 32); - if (!(timebase.num > 0 && timebase.den > 0)) { - av_log(s, AV_LOG_WARNING, "Invalid time base in theora stream, assuming 25 FPS\n"); - timebase.num = 1; - timebase.den = 25; - } - avpriv_set_pts_info(st, 64, timebase.num, timebase.den); - - st->sample_aspect_ratio.num = get_bits_long(&gb, 24); - st->sample_aspect_ratio.den = get_bits_long(&gb, 24); - - if (thp->version >= 0x030200) - skip_bits_long(&gb, 38); - if (thp->version >= 0x304000) - skip_bits(&gb, 2); - - thp->gpshift = get_bits(&gb, 5); - thp->gpmask = (1 << thp->gpshift) - 1; - - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = AV_CODEC_ID_THEORA; - st->need_parsing = AVSTREAM_PARSE_HEADERS; - } - break; - case 0x81: - ff_vorbis_comment(s, &st->metadata, os->buf + os->pstart + 7, os->psize - 7); - case 0x82: - if (!thp->version) - return -1; - break; - default: - av_log(s, AV_LOG_ERROR, "Unknown header type %X\n", os->buf[os->pstart]); - return -1; - } - - st->codec->extradata = av_realloc (st->codec->extradata, - cds + FF_INPUT_BUFFER_PADDING_SIZE); - cdp = st->codec->extradata + st->codec->extradata_size; - *cdp++ = os->psize >> 8; - *cdp++ = os->psize & 0xff; - memcpy (cdp, os->buf + os->pstart, os->psize); - st->codec->extradata_size = cds; - - return 1; -} - -static uint64_t -theora_gptopts(AVFormatContext *ctx, int idx, uint64_t gp, int64_t *dts) -{ - struct ogg *ogg = ctx->priv_data; - struct ogg_stream *os = ogg->streams + idx; - struct theora_params *thp = os->private; - uint64_t iframe, pframe; - - if (!thp) - return AV_NOPTS_VALUE; - - iframe = gp >> thp->gpshift; - pframe = gp & thp->gpmask; - - if (thp->version < 0x030201) - iframe++; - - if(!pframe) - os->pflags |= AV_PKT_FLAG_KEY; - - if (dts) - *dts = iframe + pframe; - - return iframe + pframe; -} - -static int theora_packet(AVFormatContext *s, int idx) -{ - struct ogg *ogg = s->priv_data; - struct ogg_stream *os = ogg->streams + idx; - int duration; - - /* first packet handling - here we parse the duration of each packet in the first page and compare - the total duration to the page granule to find the encoder delay and - set the first timestamp */ - - if ((!os->lastpts || os->lastpts == AV_NOPTS_VALUE) && !(os->flags & OGG_FLAG_EOS)) { - int seg; - - duration = 1; - for (seg = os->segp; seg < os->nsegs; seg++) { - if (os->segments[seg] < 255) - duration ++; - } - - os->lastpts = os->lastdts = theora_gptopts(s, idx, os->granule, NULL) - duration; - if(s->streams[idx]->start_time == AV_NOPTS_VALUE) { - s->streams[idx]->start_time = os->lastpts; - if (s->streams[idx]->duration) - s->streams[idx]->duration -= s->streams[idx]->start_time; - } - } - - /* parse packet duration */ - if (os->psize > 0) { - os->pduration = 1; - } - - return 0; -} - -const struct ogg_codec ff_theora_codec = { - .magic = "\200theora", - .magicsize = 7, - .header = theora_header, - .packet = theora_packet, - .gptopts = theora_gptopts, - .nb_header = 3, -}; diff --git a/ffmpeg1/libavformat/oggparsevorbis.c b/ffmpeg1/libavformat/oggparsevorbis.c deleted file mode 100644 index da029a4..0000000 --- a/ffmpeg1/libavformat/oggparsevorbis.c +++ /dev/null @@ -1,392 +0,0 @@ -/** - Copyright (C) 2005 Michael Ahlberg, MÃ¥ns RullgÃ¥rd - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, copy, - modify, merge, publish, distribute, sublicense, and/or sell copies - of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - DEALINGS IN THE SOFTWARE. -**/ - -#include -#include "libavutil/avstring.h" -#include "libavutil/bswap.h" -#include "libavutil/dict.h" -#include "libavcodec/get_bits.h" -#include "libavcodec/bytestream.h" -#include "libavcodec/vorbis_parser.h" -#include "avformat.h" -#include "internal.h" -#include "oggdec.h" -#include "vorbiscomment.h" - -static int ogm_chapter(AVFormatContext *as, uint8_t *key, uint8_t *val) -{ - int i, cnum, h, m, s, ms, keylen = strlen(key); - AVChapter *chapter = NULL; - - if (keylen < 9 || sscanf(key, "CHAPTER%02d", &cnum) != 1) - return 0; - - if (keylen == 9) { - if (sscanf(val, "%02d:%02d:%02d.%03d", &h, &m, &s, &ms) < 4) - return 0; - - avpriv_new_chapter(as, cnum, (AVRational){1,1000}, - ms + 1000*(s + 60*(m + 60*h)), - AV_NOPTS_VALUE, NULL); - av_free(val); - } else if (!strcmp(key+9, "NAME")) { - for(i = 0; i < as->nb_chapters; i++) - if (as->chapters[i]->id == cnum) { - chapter = as->chapters[i]; - break; - } - if (!chapter) - return 0; - - av_dict_set(&chapter->metadata, "title", val, - AV_DICT_DONT_STRDUP_VAL); - } else - return 0; - - av_free(key); - return 1; -} - -int -ff_vorbis_comment(AVFormatContext * as, AVDictionary **m, const uint8_t *buf, int size) -{ - const uint8_t *p = buf; - const uint8_t *end = buf + size; - unsigned n, j; - int s; - - if (size < 8) /* must have vendor_length and user_comment_list_length */ - return -1; - - s = bytestream_get_le32(&p); - - if (end - p - 4 < s || s < 0) - return -1; - - p += s; - - n = bytestream_get_le32(&p); - - while (end - p >= 4 && n > 0) { - const char *t, *v; - int tl, vl; - - s = bytestream_get_le32(&p); - - if (end - p < s || s < 0) - break; - - t = p; - p += s; - n--; - - v = memchr(t, '=', s); - if (!v) - continue; - - tl = v - t; - vl = s - tl - 1; - v++; - - if (tl && vl) { - char *tt, *ct; - - tt = av_malloc(tl + 1); - ct = av_malloc(vl + 1); - if (!tt || !ct) { - av_freep(&tt); - av_freep(&ct); - av_log(as, AV_LOG_WARNING, "out-of-memory error. skipping VorbisComment tag.\n"); - continue; - } - - for (j = 0; j < tl; j++) - tt[j] = av_toupper(t[j]); - tt[tl] = 0; - - memcpy(ct, v, vl); - ct[vl] = 0; - - if (!ogm_chapter(as, tt, ct)) - av_dict_set(m, tt, ct, - AV_DICT_DONT_STRDUP_KEY | - AV_DICT_DONT_STRDUP_VAL); - } - } - - if (p != end) - av_log(as, AV_LOG_INFO, "%ti bytes of comment header remain\n", end-p); - if (n > 0) - av_log(as, AV_LOG_INFO, - "truncated comment header, %i comments not found\n", n); - - ff_metadata_conv(m, NULL, ff_vorbiscomment_metadata_conv); - - return 0; -} - - -/** Parse the vorbis header - * Vorbis Identification header from Vorbis_I_spec.html#vorbis-spec-codec - * [vorbis_version] = read 32 bits as unsigned integer | Not used - * [audio_channels] = read 8 bit integer as unsigned | Used - * [audio_sample_rate] = read 32 bits as unsigned integer | Used - * [bitrate_maximum] = read 32 bits as signed integer | Not used yet - * [bitrate_nominal] = read 32 bits as signed integer | Not used yet - * [bitrate_minimum] = read 32 bits as signed integer | Used as bitrate - * [blocksize_0] = read 4 bits as unsigned integer | Not Used - * [blocksize_1] = read 4 bits as unsigned integer | Not Used - * [framing_flag] = read one bit | Not Used - * */ - -struct oggvorbis_private { - unsigned int len[3]; - unsigned char *packet[3]; - VorbisParseContext vp; - int64_t final_pts; - int final_duration; -}; - - -static unsigned int -fixup_vorbis_headers(AVFormatContext * as, struct oggvorbis_private *priv, - uint8_t **buf) -{ - int i,offset, len, buf_len; - unsigned char *ptr; - - len = priv->len[0] + priv->len[1] + priv->len[2]; - buf_len = len + len/255 + 64; - ptr = *buf = av_realloc(NULL, buf_len); - if (!*buf) - return 0; - memset(*buf, '\0', buf_len); - - ptr[0] = 2; - offset = 1; - offset += av_xiphlacing(&ptr[offset], priv->len[0]); - offset += av_xiphlacing(&ptr[offset], priv->len[1]); - for (i = 0; i < 3; i++) { - memcpy(&ptr[offset], priv->packet[i], priv->len[i]); - offset += priv->len[i]; - av_freep(&priv->packet[i]); - } - *buf = av_realloc(*buf, offset + FF_INPUT_BUFFER_PADDING_SIZE); - return offset; -} - -static void vorbis_cleanup(AVFormatContext *s, int idx) -{ - struct ogg *ogg = s->priv_data; - struct ogg_stream *os = ogg->streams + idx; - struct oggvorbis_private *priv = os->private; - int i; - if (os->private) - for (i = 0; i < 3; i++) - av_freep(&priv->packet[i]); -} - -static int -vorbis_header (AVFormatContext * s, int idx) -{ - struct ogg *ogg = s->priv_data; - struct ogg_stream *os = ogg->streams + idx; - AVStream *st = s->streams[idx]; - struct oggvorbis_private *priv; - int pkt_type = os->buf[os->pstart]; - - if (!(pkt_type & 1)) - return os->private ? 0 : -1; - - if (!os->private) { - os->private = av_mallocz(sizeof(struct oggvorbis_private)); - if (!os->private) - return -1; - } - - if (os->psize < 1 || pkt_type > 5) - return -1; - - priv = os->private; - - if (priv->packet[pkt_type>>1]) - return -1; - if (pkt_type > 1 && !priv->packet[0] || pkt_type > 3 && !priv->packet[1]) - return -1; - - priv->len[pkt_type >> 1] = os->psize; - priv->packet[pkt_type >> 1] = av_mallocz(os->psize); - if (!priv->packet[pkt_type >> 1]) - return AVERROR(ENOMEM); - memcpy(priv->packet[pkt_type >> 1], os->buf + os->pstart, os->psize); - if (os->buf[os->pstart] == 1) { - const uint8_t *p = os->buf + os->pstart + 7; /* skip "\001vorbis" tag */ - unsigned blocksize, bs0, bs1; - int srate; - int channels; - - if (os->psize != 30) - return -1; - - if (bytestream_get_le32(&p) != 0) /* vorbis_version */ - return -1; - - channels= bytestream_get_byte(&p); - if (st->codec->channels && channels != st->codec->channels) { - av_log(s, AV_LOG_ERROR, "Channel change is not supported\n"); - return AVERROR_PATCHWELCOME; - } - st->codec->channels = channels; - srate = bytestream_get_le32(&p); - p += 4; // skip maximum bitrate - st->codec->bit_rate = bytestream_get_le32(&p); // nominal bitrate - p += 4; // skip minimum bitrate - - blocksize = bytestream_get_byte(&p); - bs0 = blocksize & 15; - bs1 = blocksize >> 4; - - if (bs0 > bs1) - return -1; - if (bs0 < 6 || bs1 > 13) - return -1; - - if (bytestream_get_byte(&p) != 1) /* framing_flag */ - return -1; - - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = AV_CODEC_ID_VORBIS; - - if (srate > 0) { - st->codec->sample_rate = srate; - avpriv_set_pts_info(st, 64, 1, srate); - } - } else if (os->buf[os->pstart] == 3) { - if (os->psize > 8 && - ff_vorbis_comment(s, &st->metadata, os->buf + os->pstart + 7, os->psize - 8) >= 0) { - // drop all metadata we parsed and which is not required by libvorbis - unsigned new_len = 7 + 4 + AV_RL32(priv->packet[1] + 7) + 4 + 1; - if (new_len >= 16 && new_len < os->psize) { - AV_WL32(priv->packet[1] + new_len - 5, 0); - priv->packet[1][new_len - 1] = 1; - priv->len[1] = new_len; - } - } - } else { - int ret; - st->codec->extradata_size = - fixup_vorbis_headers(s, priv, &st->codec->extradata); - if ((ret = avpriv_vorbis_parse_extradata(st->codec, &priv->vp))) { - av_freep(&st->codec->extradata); - st->codec->extradata_size = 0; - return ret; - } - } - - return 1; -} - -static int vorbis_packet(AVFormatContext *s, int idx) -{ - struct ogg *ogg = s->priv_data; - struct ogg_stream *os = ogg->streams + idx; - struct oggvorbis_private *priv = os->private; - int duration; - - /* first packet handling - here we parse the duration of each packet in the first page and compare - the total duration to the page granule to find the encoder delay and - set the first timestamp */ - if ((!os->lastpts || os->lastpts == AV_NOPTS_VALUE) && !(os->flags & OGG_FLAG_EOS)) { - int seg, d; - uint8_t *last_pkt = os->buf + os->pstart; - uint8_t *next_pkt = last_pkt; - - avpriv_vorbis_parse_reset(&priv->vp); - duration = 0; - seg = os->segp; - d = avpriv_vorbis_parse_frame(&priv->vp, last_pkt, 1); - if (d < 0) { - os->pflags |= AV_PKT_FLAG_CORRUPT; - return 0; - } - duration += d; - last_pkt = next_pkt = next_pkt + os->psize; - for (; seg < os->nsegs; seg++) { - if (os->segments[seg] < 255) { - int d = avpriv_vorbis_parse_frame(&priv->vp, last_pkt, 1); - if (d < 0) { - duration = os->granule; - break; - } - duration += d; - last_pkt = next_pkt + os->segments[seg]; - } - next_pkt += os->segments[seg]; - } - os->lastpts = os->lastdts = os->granule - duration; - if(s->streams[idx]->start_time == AV_NOPTS_VALUE) { - s->streams[idx]->start_time = FFMAX(os->lastpts, 0); - if (s->streams[idx]->duration) - s->streams[idx]->duration -= s->streams[idx]->start_time; - } - priv->final_pts = AV_NOPTS_VALUE; - avpriv_vorbis_parse_reset(&priv->vp); - } - - /* parse packet duration */ - if (os->psize > 0) { - duration = avpriv_vorbis_parse_frame(&priv->vp, os->buf + os->pstart, 1); - if (duration < 0) { - os->pflags |= AV_PKT_FLAG_CORRUPT; - return 0; - } - os->pduration = duration; - } - - /* final packet handling - here we save the pts of the first packet in the final page, sum up all - packet durations in the final page except for the last one, and compare - to the page granule to find the duration of the final packet */ - if (os->flags & OGG_FLAG_EOS) { - if (os->lastpts != AV_NOPTS_VALUE) { - priv->final_pts = os->lastpts; - priv->final_duration = 0; - } - if (os->segp == os->nsegs) - os->pduration = os->granule - priv->final_pts - priv->final_duration; - priv->final_duration += os->pduration; - } - - return 0; -} - -const struct ogg_codec ff_vorbis_codec = { - .magic = "\001vorbis", - .magicsize = 7, - .header = vorbis_header, - .packet = vorbis_packet, - .cleanup= vorbis_cleanup, - .nb_header = 3, -}; diff --git a/ffmpeg1/libavformat/oma.c b/ffmpeg1/libavformat/oma.c deleted file mode 100644 index 9e4bfbd..0000000 --- a/ffmpeg1/libavformat/oma.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Sony OpenMG (OMA) common data - * - * 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 "internal.h" -#include "oma.h" -#include "libavcodec/avcodec.h" - -const uint16_t ff_oma_srate_tab[8] = { 320, 441, 480, 882, 960, 0, 0, 0}; - -const AVCodecTag ff_oma_codec_tags[] = { - { AV_CODEC_ID_ATRAC3, OMA_CODECID_ATRAC3 }, - { AV_CODEC_ID_ATRAC3P, OMA_CODECID_ATRAC3P }, - { AV_CODEC_ID_MP3, OMA_CODECID_MP3 }, - { AV_CODEC_ID_PCM_S16BE, OMA_CODECID_LPCM }, - { 0 }, -}; - diff --git a/ffmpeg1/libavformat/oma.h b/ffmpeg1/libavformat/oma.h deleted file mode 100644 index 1f0ddf9..0000000 --- a/ffmpeg1/libavformat/oma.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Sony OpenMG (OMA) common data - * - * 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 - */ - -#ifndef AVFORMAT_OMA_H -#define AVFORMAT_OMA_H - -#include - -#include "internal.h" - -#define EA3_HEADER_SIZE 96 -#define ID3v2_EA3_MAGIC "ea3" -#define OMA_ENC_HEADER_SIZE 16 - -enum { - OMA_CODECID_ATRAC3 = 0, - OMA_CODECID_ATRAC3P = 1, - OMA_CODECID_MP3 = 3, - OMA_CODECID_LPCM = 4, - OMA_CODECID_WMA = 5, -}; - -extern const uint16_t ff_oma_srate_tab[8]; - -extern const AVCodecTag ff_oma_codec_tags[]; - -#endif /* AVFORMAT_OMA_H */ diff --git a/ffmpeg1/libavformat/omadec.c b/ffmpeg1/libavformat/omadec.c deleted file mode 100644 index 9f65db0..0000000 --- a/ffmpeg1/libavformat/omadec.c +++ /dev/null @@ -1,453 +0,0 @@ -/* - * Sony OpenMG (OMA) demuxer - * - * Copyright (c) 2008 Maxim Poliakovski - * 2008 Benjamin Larsson - * 2011 David Goldwich - * - * 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 - */ - -/** - * @file - * This is a demuxer for Sony OpenMG Music files - * - * Known file extensions: ".oma", "aa3" - * The format of such files consists of three parts: - * - "ea3" header carrying overall info and metadata. Except for starting with - * "ea" instead of "ID", it's an ID3v2 header. - * - "EA3" header is a Sony-specific header containing information about - * the OpenMG file: codec type (usually ATRAC, can also be MP3 or WMA), - * codec specific info (packet size, sample rate, channels and so on) - * and DRM related info (file encryption, content id). - * - Sound data organized in packets follow the EA3 header - * (can be encrypted using the Sony DRM!). - * - */ - -#include "libavutil/channel_layout.h" -#include "avformat.h" -#include "internal.h" -#include "libavutil/intreadwrite.h" -#include "libavutil/des.h" -#include "oma.h" -#include "pcm.h" -#include "id3v2.h" - - -static const uint64_t leaf_table[] = { - 0xd79e8283acea4620, 0x7a9762f445afd0d8, - 0x354d60a60b8c79f1, 0x584e1cde00b07aee, - 0x1573cd93da7df623, 0x47f98d79620dd535 -}; - -typedef struct OMAContext { - uint64_t content_start; - int encrypted; - uint16_t k_size; - uint16_t e_size; - uint16_t i_size; - uint16_t s_size; - uint32_t rid; - uint8_t r_val[24]; - uint8_t n_val[24]; - uint8_t m_val[8]; - uint8_t s_val[8]; - uint8_t sm_val[8]; - uint8_t e_val[8]; - uint8_t iv[8]; - struct AVDES av_des; -} OMAContext; - -static void hex_log(AVFormatContext *s, int level, const char *name, const uint8_t *value, int len) -{ - char buf[33]; - len = FFMIN(len, 16); - if (av_log_get_level() < level) - return; - ff_data_to_hex(buf, value, len, 1); - buf[len<<1] = '\0'; - av_log(s, level, "%s: %s\n", name, buf); -} - -static int kset(AVFormatContext *s, const uint8_t *r_val, const uint8_t *n_val, int len) -{ - OMAContext *oc = s->priv_data; - - if (!r_val && !n_val) - return -1; - - len = FFMIN(len, 16); - - /* use first 64 bits in the third round again */ - if (r_val) { - if (r_val != oc->r_val) { - memset(oc->r_val, 0, 24); - memcpy(oc->r_val, r_val, len); - } - memcpy(&oc->r_val[16], r_val, 8); - } - if (n_val) { - if (n_val != oc->n_val) { - memset(oc->n_val, 0, 24); - memcpy(oc->n_val, n_val, len); - } - memcpy(&oc->n_val[16], n_val, 8); - } - - return 0; -} - -static int rprobe(AVFormatContext *s, uint8_t *enc_header, const uint8_t *r_val) -{ - OMAContext *oc = s->priv_data; - unsigned int pos; - struct AVDES av_des; - - if (!enc_header || !r_val) - return -1; - - /* m_val */ - av_des_init(&av_des, r_val, 192, 1); - av_des_crypt(&av_des, oc->m_val, &enc_header[48], 1, NULL, 1); - - /* s_val */ - av_des_init(&av_des, oc->m_val, 64, 0); - av_des_crypt(&av_des, oc->s_val, NULL, 1, NULL, 0); - - /* sm_val */ - pos = OMA_ENC_HEADER_SIZE + oc->k_size + oc->e_size; - av_des_init(&av_des, oc->s_val, 64, 0); - av_des_mac(&av_des, oc->sm_val, &enc_header[pos], (oc->i_size >> 3)); - - pos += oc->i_size; - - return memcmp(&enc_header[pos], oc->sm_val, 8) ? -1 : 0; -} - -static int nprobe(AVFormatContext *s, uint8_t *enc_header, int size, const uint8_t *n_val) -{ - OMAContext *oc = s->priv_data; - uint32_t pos, taglen, datalen; - struct AVDES av_des; - - if (!enc_header || !n_val) - return -1; - - pos = OMA_ENC_HEADER_SIZE + oc->k_size; - if (!memcmp(&enc_header[pos], "EKB ", 4)) - pos += 32; - - if (AV_RB32(&enc_header[pos]) != oc->rid) - av_log(s, AV_LOG_DEBUG, "Mismatching RID\n"); - - taglen = AV_RB32(&enc_header[pos+32]); - datalen = AV_RB32(&enc_header[pos+36]) >> 4; - - if(pos + (uint64_t)taglen + (((uint64_t)datalen)<<4) + 44 > size) - return -1; - - pos += 44 + taglen; - - av_des_init(&av_des, n_val, 192, 1); - while (datalen-- > 0) { - av_des_crypt(&av_des, oc->r_val, &enc_header[pos], 2, NULL, 1); - kset(s, oc->r_val, NULL, 16); - if (!rprobe(s, enc_header, oc->r_val)) - return 0; - pos += 16; - } - - return -1; -} - -static int decrypt_init(AVFormatContext *s, ID3v2ExtraMeta *em, uint8_t *header) -{ - OMAContext *oc = s->priv_data; - ID3v2ExtraMetaGEOB *geob = NULL; - uint8_t *gdata; - - oc->encrypted = 1; - av_log(s, AV_LOG_INFO, "File is encrypted\n"); - - /* find GEOB metadata */ - while (em) { - if (!strcmp(em->tag, "GEOB") && - (geob = em->data) && - (!strcmp(geob->description, "OMG_LSI") || - !strcmp(geob->description, "OMG_BKLSI"))) { - break; - } - em = em->next; - } - if (!em) { - av_log(s, AV_LOG_ERROR, "No encryption header found\n"); - return -1; - } - - if (geob->datasize < 64) { - av_log(s, AV_LOG_ERROR, "Invalid GEOB data size: %u\n", geob->datasize); - return -1; - } - - gdata = geob->data; - - if (AV_RB16(gdata) != 1) - av_log(s, AV_LOG_WARNING, "Unknown version in encryption header\n"); - - oc->k_size = AV_RB16(&gdata[2]); - oc->e_size = AV_RB16(&gdata[4]); - oc->i_size = AV_RB16(&gdata[6]); - oc->s_size = AV_RB16(&gdata[8]); - - if (memcmp(&gdata[OMA_ENC_HEADER_SIZE], "KEYRING ", 12)) { - av_log(s, AV_LOG_ERROR, "Invalid encryption header\n"); - return -1; - } - if ( OMA_ENC_HEADER_SIZE + oc->k_size + oc->e_size + oc->i_size + 8 > geob->datasize - || OMA_ENC_HEADER_SIZE + 48 > geob->datasize - ) { - av_log(s, AV_LOG_ERROR, "Too little GEOB data\n"); - return AVERROR_INVALIDDATA; - } - oc->rid = AV_RB32(&gdata[OMA_ENC_HEADER_SIZE + 28]); - av_log(s, AV_LOG_DEBUG, "RID: %.8x\n", oc->rid); - - memcpy(oc->iv, &header[0x58], 8); - hex_log(s, AV_LOG_DEBUG, "IV", oc->iv, 8); - - hex_log(s, AV_LOG_DEBUG, "CBC-MAC", &gdata[OMA_ENC_HEADER_SIZE+oc->k_size+oc->e_size+oc->i_size], 8); - - if (s->keylen > 0) { - kset(s, s->key, s->key, s->keylen); - } - if (!memcmp(oc->r_val, (const uint8_t[8]){0}, 8) || - rprobe(s, gdata, oc->r_val) < 0 && - nprobe(s, gdata, geob->datasize, oc->n_val) < 0) { - int i; - for (i = 0; i < FF_ARRAY_ELEMS(leaf_table); i += 2) { - uint8_t buf[16]; - AV_WL64(buf, leaf_table[i]); - AV_WL64(&buf[8], leaf_table[i+1]); - kset(s, buf, buf, 16); - if (!rprobe(s, gdata, oc->r_val) || !nprobe(s, gdata, geob->datasize, oc->n_val)) - break; - } - if (i >= FF_ARRAY_ELEMS(leaf_table)) { - av_log(s, AV_LOG_ERROR, "Invalid key\n"); - return -1; - } - } - - /* e_val */ - av_des_init(&oc->av_des, oc->m_val, 64, 0); - av_des_crypt(&oc->av_des, oc->e_val, &gdata[OMA_ENC_HEADER_SIZE + 40], 1, NULL, 0); - hex_log(s, AV_LOG_DEBUG, "EK", oc->e_val, 8); - - /* init e_val */ - av_des_init(&oc->av_des, oc->e_val, 64, 1); - - return 0; -} - -static int oma_read_header(AVFormatContext *s) -{ - int ret, framesize, jsflag, samplerate; - uint32_t codec_params; - int16_t eid; - uint8_t buf[EA3_HEADER_SIZE]; - uint8_t *edata; - AVStream *st; - ID3v2ExtraMeta *extra_meta = NULL; - OMAContext *oc = s->priv_data; - - ff_id3v2_read(s, ID3v2_EA3_MAGIC, &extra_meta); - ret = avio_read(s->pb, buf, EA3_HEADER_SIZE); - if (ret < EA3_HEADER_SIZE) - return -1; - - if (memcmp(buf, ((const uint8_t[]){'E', 'A', '3'}),3) || buf[4] != 0 || buf[5] != EA3_HEADER_SIZE) { - av_log(s, AV_LOG_ERROR, "Couldn't find the EA3 header !\n"); - return -1; - } - - oc->content_start = avio_tell(s->pb); - - /* encrypted file */ - eid = AV_RB16(&buf[6]); - if (eid != -1 && eid != -128 && decrypt_init(s, extra_meta, buf) < 0) { - ff_id3v2_free_extra_meta(&extra_meta); - return -1; - } - - ff_id3v2_free_extra_meta(&extra_meta); - - codec_params = AV_RB24(&buf[33]); - - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - - st->start_time = 0; - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_tag = buf[32]; - st->codec->codec_id = ff_codec_get_id(ff_oma_codec_tags, st->codec->codec_tag); - - switch (buf[32]) { - case OMA_CODECID_ATRAC3: - samplerate = ff_oma_srate_tab[(codec_params >> 13) & 7]*100; - if (samplerate != 44100) - avpriv_request_sample(s, "Sample rate %d", samplerate); - - framesize = (codec_params & 0x3FF) * 8; - jsflag = (codec_params >> 17) & 1; /* get stereo coding mode, 1 for joint-stereo */ - st->codec->channels = 2; - st->codec->channel_layout = AV_CH_LAYOUT_STEREO; - st->codec->sample_rate = samplerate; - st->codec->bit_rate = st->codec->sample_rate * framesize * 8 / 1024; - - /* fake the atrac3 extradata (wav format, makes stream copy to wav work) */ - st->codec->extradata_size = 14; - edata = av_mallocz(14 + FF_INPUT_BUFFER_PADDING_SIZE); - if (!edata) - return AVERROR(ENOMEM); - - st->codec->extradata = edata; - AV_WL16(&edata[0], 1); // always 1 - AV_WL32(&edata[2], samplerate); // samples rate - AV_WL16(&edata[6], jsflag); // coding mode - AV_WL16(&edata[8], jsflag); // coding mode - AV_WL16(&edata[10], 1); // always 1 - // AV_WL16(&edata[12], 0); // always 0 - - avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); - break; - case OMA_CODECID_ATRAC3P: - st->codec->channels = (codec_params >> 10) & 7; - framesize = ((codec_params & 0x3FF) * 8) + 8; - st->codec->sample_rate = ff_oma_srate_tab[(codec_params >> 13) & 7]*100; - st->codec->bit_rate = st->codec->sample_rate * framesize * 8 / 1024; - avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); - av_log(s, AV_LOG_ERROR, "Unsupported codec ATRAC3+!\n"); - break; - case OMA_CODECID_MP3: - st->need_parsing = AVSTREAM_PARSE_FULL_RAW; - framesize = 1024; - break; - case OMA_CODECID_LPCM: - /* PCM 44.1 kHz 16 bit stereo big-endian */ - st->codec->channels = 2; - st->codec->channel_layout = AV_CH_LAYOUT_STEREO; - st->codec->sample_rate = 44100; - framesize = 1024; - /* bit rate = sample rate x PCM block align (= 4) x 8 */ - st->codec->bit_rate = st->codec->sample_rate * 32; - st->codec->bits_per_coded_sample = av_get_bits_per_sample(st->codec->codec_id); - avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); - break; - default: - av_log(s, AV_LOG_ERROR, "Unsupported codec %d!\n",buf[32]); - return -1; - } - - st->codec->block_align = framesize; - - return 0; -} - - -static int oma_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - OMAContext *oc = s->priv_data; - int packet_size = s->streams[0]->codec->block_align; - int ret = av_get_packet(s->pb, pkt, packet_size); - - if (ret <= 0) - return AVERROR(EIO); - - pkt->stream_index = 0; - - if (oc->encrypted) { - /* previous unencrypted block saved in IV for the next packet (CBC mode) */ - av_des_crypt(&oc->av_des, pkt->data, pkt->data, (ret >> 3), oc->iv, 1); - } - - return ret; -} - -static int oma_read_probe(AVProbeData *p) -{ - const uint8_t *buf; - unsigned tag_len = 0; - - buf = p->buf; - - if (p->buf_size < ID3v2_HEADER_SIZE || - !ff_id3v2_match(buf, ID3v2_EA3_MAGIC) || - buf[3] != 3 || // version must be 3 - buf[4]) // flags byte zero - return 0; - - tag_len = ff_id3v2_tag_len(buf); - - /* This check cannot overflow as tag_len has at most 28 bits */ - if (p->buf_size < tag_len + 5) - /* EA3 header comes late, might be outside of the probe buffer */ - return AVPROBE_SCORE_MAX / 2; - - buf += tag_len; - - if (!memcmp(buf, "EA3", 3) && !buf[4] && buf[5] == EA3_HEADER_SIZE) - return AVPROBE_SCORE_MAX; - else - return 0; -} - -static int oma_read_seek(struct AVFormatContext *s, int stream_index, int64_t timestamp, int flags) -{ - OMAContext *oc = s->priv_data; - - ff_pcm_read_seek(s, stream_index, timestamp, flags); - - if (oc->encrypted) { - /* readjust IV for CBC */ - int64_t pos = avio_tell(s->pb); - if (pos < oc->content_start) - memset(oc->iv, 0, 8); - else { - if (avio_seek(s->pb, -8, SEEK_CUR) < 0 || avio_read(s->pb, oc->iv, 8) < 8) { - memset(oc->iv, 0, 8); - return -1; - } - } - } - - return 0; -} - -AVInputFormat ff_oma_demuxer = { - .name = "oma", - .long_name = NULL_IF_CONFIG_SMALL("Sony OpenMG audio"), - .priv_data_size = sizeof(OMAContext), - .read_probe = oma_read_probe, - .read_header = oma_read_header, - .read_packet = oma_read_packet, - .read_seek = oma_read_seek, - .flags = AVFMT_GENERIC_INDEX, - .extensions = "oma,omg,aa3", - .codec_tag = (const AVCodecTag* const []){ff_oma_codec_tags, 0}, -}; diff --git a/ffmpeg1/libavformat/omaenc.c b/ffmpeg1/libavformat/omaenc.c deleted file mode 100644 index 5c5aff7..0000000 --- a/ffmpeg1/libavformat/omaenc.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Sony OpenMG (OMA) muxer - * - * Copyright (c) 2011 Michael Karcher - * - * 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 - */ - -#include "avformat.h" -#include "avio_internal.h" -#include "id3v2.h" -#include "internal.h" -#include "oma.h" -#include "rawenc.h" - -static av_cold int oma_write_header(AVFormatContext *s) -{ - int i; - AVCodecContext *format; - int srate_index; - int isjointstereo; - - format = s->streams[0]->codec; - /* check for support of the format first */ - - for (srate_index = 0; ; srate_index++) { - if (ff_oma_srate_tab[srate_index] == 0) { - av_log(s, AV_LOG_ERROR, "Sample rate %d not supported in OpenMG audio\n", - format->sample_rate); - return AVERROR(EINVAL); - } - - if (ff_oma_srate_tab[srate_index] * 100 == format->sample_rate) - break; - } - - /* Metadata; OpenMG does not support ID3v2.4 */ - ff_id3v2_write_simple(s, 3, ID3v2_EA3_MAGIC); - - ffio_wfourcc(s->pb, "EA3\0"); - avio_w8(s->pb, EA3_HEADER_SIZE >> 7); - avio_w8(s->pb, EA3_HEADER_SIZE & 0x7F); - avio_wl16(s->pb, 0xFFFF); /* not encrypted */ - for (i = 0; i < 6; i++) - avio_wl32(s->pb, 0); /* Padding + DRM id */ - - switch(format->codec_tag) { - case OMA_CODECID_ATRAC3: - if (format->channels != 2) { - av_log(s, AV_LOG_ERROR, "ATRAC3 in OMA is only supported with 2 channels\n"); - return AVERROR(EINVAL); - } - if (format->extradata_size == 14) /* WAV format extradata */ - isjointstereo = format->extradata[6] != 0; - else if(format->extradata_size == 10) /* RM format extradata */ - isjointstereo = format->extradata[8] == 0x12; - else { - av_log(s, AV_LOG_ERROR, "ATRAC3: Unsupported extradata size\n"); - return AVERROR(EINVAL); - } - avio_wb32(s->pb, (OMA_CODECID_ATRAC3 << 24) | - (isjointstereo << 17) | - (srate_index << 13) | - (format->block_align/8)); - break; - case OMA_CODECID_ATRAC3P: - avio_wb32(s->pb, (OMA_CODECID_ATRAC3P << 24) | - (srate_index << 13) | - (format->channels << 10) | - (format->block_align/8 - 1)); - break; - default: - av_log(s, AV_LOG_ERROR, "unsupported codec tag %d for write\n", - format->codec_tag); - return AVERROR(EINVAL); - } - for (i = 0; i < (EA3_HEADER_SIZE - 36)/4; i++) - avio_wl32(s->pb, 0); /* Padding */ - - return 0; -} - -AVOutputFormat ff_oma_muxer = { - .name = "oma", - .long_name = NULL_IF_CONFIG_SMALL("Sony OpenMG audio"), - .mime_type = "audio/x-oma", - .extensions = "oma", - .audio_codec = AV_CODEC_ID_ATRAC3, - .write_header = oma_write_header, - .write_packet = ff_raw_write_packet, - .codec_tag = (const AVCodecTag* const []){ff_oma_codec_tags, 0}, -}; diff --git a/ffmpeg1/libavformat/options.c b/ffmpeg1/libavformat/options.c deleted file mode 100644 index 42307d1..0000000 --- a/ffmpeg1/libavformat/options.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2000, 2001, 2002 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 "avio_internal.h" -#include "libavutil/opt.h" - -/** - * @file - * Options definition for AVFormatContext. - */ - -#include "options_table.h" - -static const char* format_to_name(void* ptr) -{ - AVFormatContext* fc = (AVFormatContext*) ptr; - if(fc->iformat) return fc->iformat->name; - else if(fc->oformat) return fc->oformat->name; - else return "NULL"; -} - -static void *format_child_next(void *obj, void *prev) -{ - AVFormatContext *s = obj; - if (!prev && s->priv_data && - ((s->iformat && s->iformat->priv_class) || - s->oformat && s->oformat->priv_class)) - return s->priv_data; - if (s->pb && s->pb->av_class && prev != s->pb) - return s->pb; - return NULL; -} - -static const AVClass *format_child_class_next(const AVClass *prev) -{ - AVInputFormat *ifmt = NULL; - AVOutputFormat *ofmt = NULL; - - if (!prev) - return &ffio_url_class; - - while ((ifmt = av_iformat_next(ifmt))) - if (ifmt->priv_class == prev) - break; - - if (!ifmt) - while ((ofmt = av_oformat_next(ofmt))) - if (ofmt->priv_class == prev) - break; - if (!ofmt) - while (ifmt = av_iformat_next(ifmt)) - if (ifmt->priv_class) - return ifmt->priv_class; - - while (ofmt = av_oformat_next(ofmt)) - if (ofmt->priv_class) - return ofmt->priv_class; - - return NULL; -} - -static AVClassCategory get_category(void *ptr) -{ - AVFormatContext* s = ptr; - if(s->iformat) return AV_CLASS_CATEGORY_DEMUXER; - else return AV_CLASS_CATEGORY_MUXER; -} - -static const AVClass av_format_context_class = { - .class_name = "AVFormatContext", - .item_name = format_to_name, - .option = options, - .version = LIBAVUTIL_VERSION_INT, - .child_next = format_child_next, - .child_class_next = format_child_class_next, - .category = AV_CLASS_CATEGORY_MUXER, - .get_category = get_category, -}; - -static void avformat_get_context_defaults(AVFormatContext *s) -{ - memset(s, 0, sizeof(AVFormatContext)); - - s->av_class = &av_format_context_class; - - av_opt_set_defaults(s); -} - -AVFormatContext *avformat_alloc_context(void) -{ - AVFormatContext *ic; - ic = av_malloc(sizeof(AVFormatContext)); - if (!ic) return ic; - avformat_get_context_defaults(ic); - return ic; -} - -enum AVDurationEstimationMethod av_fmt_ctx_get_duration_estimation_method(const AVFormatContext* ctx) -{ - return ctx->duration_estimation_method; -} - -const AVClass *avformat_get_class(void) -{ - return &av_format_context_class; -} diff --git a/ffmpeg1/libavformat/options_table.h b/ffmpeg1/libavformat/options_table.h deleted file mode 100644 index 6750050..0000000 --- a/ffmpeg1/libavformat/options_table.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2000, 2001, 2002 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 AVFORMAT_OPTIONS_TABLE_H -#define AVFORMAT_OPTIONS_TABLE_H - -#include - -#include "libavutil/opt.h" -#include "avformat.h" - -#define OFFSET(x) offsetof(AVFormatContext,x) -#define DEFAULT 0 //should be NAN but it does not work as it is not a constant in glibc as required by ANSI/ISO C -//these names are too long to be readable -#define E AV_OPT_FLAG_ENCODING_PARAM -#define D AV_OPT_FLAG_DECODING_PARAM - -static const AVOption options[]={ -{"avioflags", NULL, OFFSET(avio_flags), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT }, INT_MIN, INT_MAX, D|E, "avioflags"}, -{"direct", "reduce buffering", 0, AV_OPT_TYPE_CONST, {.i64 = AVIO_FLAG_DIRECT }, INT_MIN, INT_MAX, D|E, "avioflags"}, -{"probesize", "set probing size", OFFSET(probesize), AV_OPT_TYPE_INT, {.i64 = 5000000 }, 32, INT_MAX, D}, -{"packetsize", "set packet size", OFFSET(packet_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, E}, -{"fflags", NULL, OFFSET(flags), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT }, INT_MIN, INT_MAX, D|E, "fflags"}, -{"ignidx", "ignore index", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_IGNIDX }, INT_MIN, INT_MAX, D, "fflags"}, -{"genpts", "generate pts", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_GENPTS }, INT_MIN, INT_MAX, D, "fflags"}, -{"nofillin", "do not fill in missing values that can be exactly calculated", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_NOFILLIN }, INT_MIN, INT_MAX, D, "fflags"}, -{"noparse", "disable AVParsers, this needs nofillin too", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_NOPARSE }, INT_MIN, INT_MAX, D, "fflags"}, -{"igndts", "ignore dts", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_IGNDTS }, INT_MIN, INT_MAX, D, "fflags"}, -{"discardcorrupt", "discard corrupted frames", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_DISCARD_CORRUPT }, INT_MIN, INT_MAX, D, "fflags"}, -{"sortdts", "try to interleave outputted packets by dts", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_SORT_DTS }, INT_MIN, INT_MAX, D, "fflags"}, -{"keepside", "dont merge side data", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_KEEP_SIDE_DATA }, INT_MIN, INT_MAX, D, "fflags"}, -{"latm", "enable RTP MP4A-LATM payload", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_MP4A_LATM }, INT_MIN, INT_MAX, E, "fflags"}, -{"nobuffer", "reduce the latency introduced by optional buffering", 0, AV_OPT_TYPE_CONST, {.i64 = AVFMT_FLAG_NOBUFFER }, 0, INT_MAX, D, "fflags"}, -{"seek2any", "forces seeking to enable seek to any mode", OFFSET(seek2any), AV_OPT_TYPE_INT, {.i64 = 0 }, 0, 1, D}, -{"analyzeduration", "specify how many microseconds are analyzed to probe the input", OFFSET(max_analyze_duration), AV_OPT_TYPE_INT, {.i64 = 5*AV_TIME_BASE }, 0, INT_MAX, D}, -{"cryptokey", "decryption key", OFFSET(key), AV_OPT_TYPE_BINARY, {.dbl = 0}, 0, 0, D}, -{"indexmem", "max memory used for timestamp index (per stream)", OFFSET(max_index_size), AV_OPT_TYPE_INT, {.i64 = 1<<20 }, 0, INT_MAX, D}, -{"rtbufsize", "max memory used for buffering real-time frames", OFFSET(max_picture_buffer), AV_OPT_TYPE_INT, {.i64 = 3041280 }, 0, INT_MAX, D}, /* defaults to 1s of 15fps 352x288 YUYV422 video */ -{"fdebug", "print specific debug info", OFFSET(debug), AV_OPT_TYPE_FLAGS, {.i64 = DEFAULT }, 0, INT_MAX, E|D, "fdebug"}, -{"ts", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_FDEBUG_TS }, INT_MIN, INT_MAX, E|D, "fdebug"}, -{"max_delay", "maximum muxing or demuxing delay in microseconds", OFFSET(max_delay), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, INT_MAX, E|D}, -{"fpsprobesize", "number of frames used to probe fps", OFFSET(fps_probe_size), AV_OPT_TYPE_INT, {.i64 = -1}, -1, INT_MAX-1, D}, -{"audio_preload", "microseconds by which audio packets should be interleaved earlier", OFFSET(audio_preload), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX-1, E}, -{"chunk_duration", "microseconds for each chunk", OFFSET(max_chunk_duration), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX-1, E}, -{"chunk_size", "size in bytes for each chunk", OFFSET(max_chunk_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX-1, E}, -/* this is a crutch for avconv, since it cannot deal with identically named options in different contexts. - * to be removed when avconv is fixed */ -{"f_err_detect", "set error detection flags (deprecated; use err_detect, save via avconv)", OFFSET(error_recognition), AV_OPT_TYPE_FLAGS, {.i64 = AV_EF_CRCCHECK }, INT_MIN, INT_MAX, D, "err_detect"}, -{"err_detect", "set error detection flags", OFFSET(error_recognition), AV_OPT_TYPE_FLAGS, {.i64 = AV_EF_CRCCHECK }, INT_MIN, INT_MAX, D, "err_detect"}, -{"crccheck", "verify embedded CRCs", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_CRCCHECK }, INT_MIN, INT_MAX, D, "err_detect"}, -{"bitstream", "detect bitstream specification deviations", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_BITSTREAM }, INT_MIN, INT_MAX, D, "err_detect"}, -{"buffer", "detect improper bitstream length", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_BUFFER }, INT_MIN, INT_MAX, D, "err_detect"}, -{"explode", "abort decoding on minor error detection", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_EXPLODE }, INT_MIN, INT_MAX, D, "err_detect"}, -{"careful", "consider things that violate the spec and have not been seen in the wild as errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_CAREFUL }, INT_MIN, INT_MAX, D, "err_detect"}, -{"compliant", "consider all spec non compliancies as errors", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_COMPLIANT }, INT_MIN, INT_MAX, D, "err_detect"}, -{"aggressive", "consider things that a sane encoder shouldnt do as an error", 0, AV_OPT_TYPE_CONST, {.i64 = AV_EF_AGGRESSIVE }, INT_MIN, INT_MAX, D, "err_detect"}, -{"use_wallclock_as_timestamps", "use wallclock as timestamps", OFFSET(use_wallclock_as_timestamps), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX-1, D}, -{"avoid_negative_ts", "shift timestamps to make them positive. 1 enables, 0 disables, default of -1 enables when required by target format.", OFFSET(avoid_negative_ts), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, E}, -{"skip_initial_bytes", "skip initial bytes", OFFSET(skip_initial_bytes), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX-1, D}, -{"correct_ts_overflow", "correct single timestamp overflows", OFFSET(correct_ts_overflow), AV_OPT_TYPE_INT, {.i64 = 1}, 0, 1, D}, -{NULL}, -}; - -#undef E -#undef D -#undef DEFAULT -#undef OFFSET - -#endif /* AVFORMAT_OPTIONS_TABLE_H */ diff --git a/ffmpeg1/libavformat/os_support.c b/ffmpeg1/libavformat/os_support.c deleted file mode 100644 index 0a901f6..0000000 --- a/ffmpeg1/libavformat/os_support.c +++ /dev/null @@ -1,377 +0,0 @@ -/* - * various OS-feature replacement utilities - * Copyright (c) 2000, 2001, 2002 Fabrice Bellard - * copyright (c) 2002 Francois Revol - * - * 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 - */ - -/* needed by inet_aton() */ -#define _SVID_SOURCE - -#include "config.h" -#include "avformat.h" -#include "os_support.h" - -#if defined(_WIN32) && !defined(__MINGW32CE__) -#undef open -#undef lseek -#undef stat -#undef fstat -#include -#include -#include -#include - -int ff_win32_open(const char *filename_utf8, int oflag, int pmode) -{ - int fd; - int num_chars; - wchar_t *filename_w; - - /* convert UTF-8 to wide chars */ - num_chars = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, filename_utf8, -1, NULL, 0); - if (num_chars <= 0) - goto fallback; - filename_w = av_mallocz(sizeof(wchar_t) * num_chars); - if (!filename_w) - return -1; - MultiByteToWideChar(CP_UTF8, 0, filename_utf8, -1, filename_w, num_chars); - - fd = _wsopen(filename_w, oflag, SH_DENYNO, pmode); - av_freep(&filename_w); - - if (fd != -1 || (oflag & O_CREAT)) - return fd; - -fallback: - /* filename maybe be in CP_ACP */ - return _sopen(filename_utf8, oflag, SH_DENYNO, pmode); -} -#endif - -#if CONFIG_NETWORK -#include -#if !HAVE_POLL_H -#if HAVE_SYS_TIME_H -#include -#endif -#if HAVE_WINSOCK2_H -#include -#elif HAVE_SYS_SELECT_H -#include -#endif -#endif - -#include "network.h" - -#if !HAVE_INET_ATON -#include - -int ff_inet_aton(const char *str, struct in_addr *add) -{ - unsigned int add1 = 0, add2 = 0, add3 = 0, add4 = 0; - - if (sscanf(str, "%d.%d.%d.%d", &add1, &add2, &add3, &add4) != 4) - return 0; - - if (!add1 || (add1 | add2 | add3 | add4) > 255) - return 0; - - add->s_addr = htonl((add1 << 24) + (add2 << 16) + (add3 << 8) + add4); - - return 1; -} -#else -int ff_inet_aton(const char *str, struct in_addr *add) -{ - return inet_aton(str, add); -} -#endif /* !HAVE_INET_ATON */ - -#if !HAVE_GETADDRINFO -int ff_getaddrinfo(const char *node, const char *service, - const struct addrinfo *hints, struct addrinfo **res) -{ - struct hostent *h = NULL; - struct addrinfo *ai; - struct sockaddr_in *sin; - -#if HAVE_WINSOCK2_H - int (WSAAPI *win_getaddrinfo)(const char *node, const char *service, - const struct addrinfo *hints, - struct addrinfo **res); - HMODULE ws2mod = GetModuleHandle("ws2_32.dll"); - win_getaddrinfo = GetProcAddress(ws2mod, "getaddrinfo"); - if (win_getaddrinfo) - return win_getaddrinfo(node, service, hints, res); -#endif - - *res = NULL; - sin = av_mallocz(sizeof(struct sockaddr_in)); - if (!sin) - return EAI_FAIL; - sin->sin_family = AF_INET; - - if (node) { - if (!ff_inet_aton(node, &sin->sin_addr)) { - if (hints && (hints->ai_flags & AI_NUMERICHOST)) { - av_free(sin); - return EAI_FAIL; - } - h = gethostbyname(node); - if (!h) { - av_free(sin); - return EAI_FAIL; - } - memcpy(&sin->sin_addr, h->h_addr_list[0], sizeof(struct in_addr)); - } - } else { - if (hints && (hints->ai_flags & AI_PASSIVE)) - sin->sin_addr.s_addr = INADDR_ANY; - else - sin->sin_addr.s_addr = INADDR_LOOPBACK; - } - - /* Note: getaddrinfo allows service to be a string, which - * should be looked up using getservbyname. */ - if (service) - sin->sin_port = htons(atoi(service)); - - ai = av_mallocz(sizeof(struct addrinfo)); - if (!ai) { - av_free(sin); - return EAI_FAIL; - } - - *res = ai; - ai->ai_family = AF_INET; - ai->ai_socktype = hints ? hints->ai_socktype : 0; - switch (ai->ai_socktype) { - case SOCK_STREAM: - ai->ai_protocol = IPPROTO_TCP; - break; - case SOCK_DGRAM: - ai->ai_protocol = IPPROTO_UDP; - break; - default: - ai->ai_protocol = 0; - break; - } - - ai->ai_addr = (struct sockaddr *)sin; - ai->ai_addrlen = sizeof(struct sockaddr_in); - if (hints && (hints->ai_flags & AI_CANONNAME)) - ai->ai_canonname = h ? av_strdup(h->h_name) : NULL; - - ai->ai_next = NULL; - return 0; -} - -void ff_freeaddrinfo(struct addrinfo *res) -{ -#if HAVE_WINSOCK2_H - void (WSAAPI *win_freeaddrinfo)(struct addrinfo *res); - HMODULE ws2mod = GetModuleHandle("ws2_32.dll"); - win_freeaddrinfo = (void (WSAAPI *)(struct addrinfo *res)) - GetProcAddress(ws2mod, "freeaddrinfo"); - if (win_freeaddrinfo) { - win_freeaddrinfo(res); - return; - } -#endif - - av_free(res->ai_canonname); - av_free(res->ai_addr); - av_free(res); -} - -int ff_getnameinfo(const struct sockaddr *sa, int salen, - char *host, int hostlen, - char *serv, int servlen, int flags) -{ - const struct sockaddr_in *sin = (const struct sockaddr_in *)sa; - -#if HAVE_WINSOCK2_H - int (WSAAPI *win_getnameinfo)(const struct sockaddr *sa, socklen_t salen, - char *host, DWORD hostlen, - char *serv, DWORD servlen, int flags); - HMODULE ws2mod = GetModuleHandle("ws2_32.dll"); - win_getnameinfo = GetProcAddress(ws2mod, "getnameinfo"); - if (win_getnameinfo) - return win_getnameinfo(sa, salen, host, hostlen, serv, servlen, flags); -#endif - - if (sa->sa_family != AF_INET) - return EAI_FAMILY; - if (!host && !serv) - return EAI_NONAME; - - if (host && hostlen > 0) { - struct hostent *ent = NULL; - uint32_t a; - if (!(flags & NI_NUMERICHOST)) - ent = gethostbyaddr((const char *)&sin->sin_addr, - sizeof(sin->sin_addr), AF_INET); - - if (ent) { - snprintf(host, hostlen, "%s", ent->h_name); - } else if (flags & NI_NAMERQD) { - return EAI_NONAME; - } else { - a = ntohl(sin->sin_addr.s_addr); - snprintf(host, hostlen, "%d.%d.%d.%d", - ((a >> 24) & 0xff), ((a >> 16) & 0xff), - ((a >> 8) & 0xff), (a & 0xff)); - } - } - - if (serv && servlen > 0) { - struct servent *ent = NULL; -#if HAVE_GETSERVBYPORT - if (!(flags & NI_NUMERICSERV)) - ent = getservbyport(sin->sin_port, flags & NI_DGRAM ? "udp" : "tcp"); -#endif - - if (ent) - snprintf(serv, servlen, "%s", ent->s_name); - else - snprintf(serv, servlen, "%d", ntohs(sin->sin_port)); - } - - return 0; -} -#endif /* !HAVE_GETADDRINFO */ - -#if !HAVE_GETADDRINFO || HAVE_WINSOCK2_H -const char *ff_gai_strerror(int ecode) -{ - switch (ecode) { - case EAI_AGAIN: - return "Temporary failure in name resolution"; - case EAI_BADFLAGS: - return "Invalid flags for ai_flags"; - case EAI_FAIL: - return "A non-recoverable error occurred"; - case EAI_FAMILY: - return "The address family was not recognized or the address " - "length was invalid for the specified family"; - case EAI_MEMORY: - return "Memory allocation failure"; -#if EAI_NODATA != EAI_NONAME - case EAI_NODATA: - return "No address associated with hostname"; -#endif - case EAI_NONAME: - return "The name does not resolve for the supplied parameters"; - case EAI_SERVICE: - return "servname not supported for ai_socktype"; - case EAI_SOCKTYPE: - return "ai_socktype not supported"; - } - - return "Unknown error"; -} -#endif /* !HAVE_GETADDRINFO || HAVE_WINSOCK2_H */ - -int ff_socket_nonblock(int socket, int enable) -{ -#if HAVE_WINSOCK2_H - u_long param = enable; - return ioctlsocket(socket, FIONBIO, ¶m); -#else - if (enable) - return fcntl(socket, F_SETFL, fcntl(socket, F_GETFL) | O_NONBLOCK); - else - return fcntl(socket, F_SETFL, fcntl(socket, F_GETFL) & ~O_NONBLOCK); -#endif -} - -#if !HAVE_POLL_H -int ff_poll(struct pollfd *fds, nfds_t numfds, int timeout) -{ - fd_set read_set; - fd_set write_set; - fd_set exception_set; - nfds_t i; - int n; - int rc; - -#if HAVE_WINSOCK2_H - if (numfds >= FD_SETSIZE) { - errno = EINVAL; - return -1; - } -#endif - - FD_ZERO(&read_set); - FD_ZERO(&write_set); - FD_ZERO(&exception_set); - - n = 0; - for (i = 0; i < numfds; i++) { - if (fds[i].fd < 0) - continue; -#if !HAVE_WINSOCK2_H - if (fds[i].fd >= FD_SETSIZE) { - errno = EINVAL; - return -1; - } -#endif - - if (fds[i].events & POLLIN) - FD_SET(fds[i].fd, &read_set); - if (fds[i].events & POLLOUT) - FD_SET(fds[i].fd, &write_set); - if (fds[i].events & POLLERR) - FD_SET(fds[i].fd, &exception_set); - - if (fds[i].fd >= n) - n = fds[i].fd + 1; - } - - if (n == 0) - /* Hey!? Nothing to poll, in fact!!! */ - return 0; - - if (timeout < 0) { - rc = select(n, &read_set, &write_set, &exception_set, NULL); - } else { - struct timeval tv; - tv.tv_sec = timeout / 1000; - tv.tv_usec = 1000 * (timeout % 1000); - rc = select(n, &read_set, &write_set, &exception_set, &tv); - } - - if (rc < 0) - return rc; - - for (i = 0; i < numfds; i++) { - fds[i].revents = 0; - - if (FD_ISSET(fds[i].fd, &read_set)) - fds[i].revents |= POLLIN; - if (FD_ISSET(fds[i].fd, &write_set)) - fds[i].revents |= POLLOUT; - if (FD_ISSET(fds[i].fd, &exception_set)) - fds[i].revents |= POLLERR; - } - - return rc; -} -#endif /* HAVE_POLL_H */ -#endif /* CONFIG_NETWORK */ diff --git a/ffmpeg1/libavformat/os_support.h b/ffmpeg1/libavformat/os_support.h deleted file mode 100644 index e5f31e0..0000000 --- a/ffmpeg1/libavformat/os_support.h +++ /dev/null @@ -1,138 +0,0 @@ -/* - * various OS-feature replacement utilities - * copyright (c) 2000, 2001, 2002 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 AVFORMAT_OS_SUPPORT_H -#define AVFORMAT_OS_SUPPORT_H - -/** - * @file - * miscellaneous OS support macros and functions. - */ - -#include "config.h" - -#include - -#if defined(_WIN32) && !defined(__MINGW32CE__) -# include -# ifdef lseek -# undef lseek -# endif -# define lseek(f,p,w) _lseeki64((f), (p), (w)) -# ifdef stat -# undef stat -# endif -# define stat _stati64 -# ifdef fstat -# undef fstat -# endif -# define fstat(f,s) _fstati64((f), (s)) -#endif /* defined(__MINGW32__) && !defined(__MINGW32CE__) */ - -#ifdef _WIN32 -#if HAVE_DIRECT_H -#include -#elif HAVE_IO_H -#include -#endif -#define mkdir(a, b) _mkdir(a) -#else -#include -#endif - -static inline int is_dos_path(const char *path) -{ -#if HAVE_DOS_PATHS - if (path[0] && path[1] == ':') - return 1; -#endif - return 0; -} - -#if defined(__OS2__) || defined(__Plan9__) -#define SHUT_RD 0 -#define SHUT_WR 1 -#define SHUT_RDWR 2 -#endif - -#if defined(_WIN32) -#define SHUT_RD SD_RECEIVE -#define SHUT_WR SD_SEND -#define SHUT_RDWR SD_BOTH - -#ifndef S_IRUSR -#define S_IRUSR S_IREAD -#endif -#ifndef S_IWUSR -#define S_IWUSR S_IWRITE -#endif -#endif - -#if defined(_WIN32) && !defined(__MINGW32CE__) -int ff_win32_open(const char *filename, int oflag, int pmode); -#define open ff_win32_open -#endif - -#if CONFIG_NETWORK -#if !HAVE_SOCKLEN_T -typedef int socklen_t; -#endif - -/* most of the time closing a socket is just closing an fd */ -#if !HAVE_CLOSESOCKET -#define closesocket close -#endif - -#if !HAVE_POLL_H -typedef unsigned long nfds_t; - -#if HAVE_WINSOCK2_H -#include -#endif -#if !HAVE_STRUCT_POLLFD -struct pollfd { - int fd; - short events; /* events to look for */ - short revents; /* events that occurred */ -}; - -/* events & revents */ -#define POLLIN 0x0001 /* any readable data available */ -#define POLLOUT 0x0002 /* file descriptor is writeable */ -#define POLLRDNORM POLLIN -#define POLLWRNORM POLLOUT -#define POLLRDBAND 0x0008 /* priority readable data */ -#define POLLWRBAND 0x0010 /* priority data can be written */ -#define POLLPRI 0x0020 /* high priority readable data */ - -/* revents only */ -#define POLLERR 0x0004 /* errors pending */ -#define POLLHUP 0x0080 /* disconnected */ -#define POLLNVAL 0x1000 /* invalid file descriptor */ -#endif - - -int ff_poll(struct pollfd *fds, nfds_t numfds, int timeout); -#define poll ff_poll -#endif /* HAVE_POLL_H */ -#endif /* CONFIG_NETWORK */ - -#endif /* AVFORMAT_OS_SUPPORT_H */ diff --git a/ffmpeg1/libavformat/paf.c b/ffmpeg1/libavformat/paf.c deleted file mode 100644 index 09786eb..0000000 --- a/ffmpeg1/libavformat/paf.c +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Packed Animation File demuxer - * Copyright (c) 2012 Paul B Mahol - * - * 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 "libavutil/channel_layout.h" -#include "libavcodec/paf.h" -#include "avformat.h" -#include "internal.h" - -#define MAGIC "Packed Animation File V1.0\n(c) 1992-96 Amazing Studio\x0a\x1a" - -typedef struct { - uint32_t buffer_size; - uint32_t frame_blks; - uint32_t nb_frames; - uint32_t start_offset; - uint32_t preload_count; - uint32_t max_video_blks; - uint32_t max_audio_blks; - - uint32_t current_frame; - uint32_t current_frame_count; - uint32_t current_frame_block; - - uint32_t *blocks_count_table; - uint32_t *frames_offset_table; - uint32_t *blocks_offset_table; - - uint8_t *video_frame; - int video_size; - - uint8_t *audio_frame; - uint8_t *temp_audio_frame; - int audio_size; - - int got_audio; -} PAFDemuxContext; - -static int read_probe(AVProbeData *p) -{ - if ((p->buf_size >= strlen(MAGIC)) && - !memcmp(p->buf, MAGIC, strlen(MAGIC))) - return AVPROBE_SCORE_MAX; - return 0; -} - -static int read_close(AVFormatContext *s) -{ - PAFDemuxContext *p = s->priv_data; - - av_freep(&p->blocks_count_table); - av_freep(&p->frames_offset_table); - av_freep(&p->blocks_offset_table); - av_freep(&p->video_frame); - av_freep(&p->audio_frame); - av_freep(&p->temp_audio_frame); - - return 0; -} - -static void read_table(AVFormatContext *s, uint32_t *table, uint32_t count) -{ - int i; - - for (i = 0; i < count; i++) - table[i] = avio_rl32(s->pb); - - avio_skip(s->pb, 4 * (FFALIGN(count, 512) - count)); -} - -static int read_header(AVFormatContext *s) -{ - PAFDemuxContext *p = s->priv_data; - AVIOContext *pb = s->pb; - AVStream *ast, *vst; - int ret = 0; - - avio_skip(pb, 132); - - vst = avformat_new_stream(s, 0); - if (!vst) - return AVERROR(ENOMEM); - - vst->start_time = 0; - vst->nb_frames = - vst->duration = - p->nb_frames = avio_rl32(pb); - avio_skip(pb, 4); - vst->codec->width = avio_rl32(pb); - vst->codec->height = avio_rl32(pb); - avio_skip(pb, 4); - vst->codec->codec_type = AVMEDIA_TYPE_VIDEO; - vst->codec->codec_tag = 0; - vst->codec->codec_id = AV_CODEC_ID_PAF_VIDEO; - avpriv_set_pts_info(vst, 64, 1, 10); - - ast = avformat_new_stream(s, 0); - if (!ast) - return AVERROR(ENOMEM); - - ast->start_time = 0; - ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; - ast->codec->codec_tag = 0; - ast->codec->codec_id = AV_CODEC_ID_PAF_AUDIO; - ast->codec->channels = 2; - ast->codec->channel_layout = AV_CH_LAYOUT_STEREO; - ast->codec->sample_rate = 22050; - avpriv_set_pts_info(ast, 64, 1, 22050); - - p->buffer_size = avio_rl32(pb); - p->preload_count = avio_rl32(pb); - p->frame_blks = avio_rl32(pb); - p->start_offset = avio_rl32(pb); - p->max_video_blks = avio_rl32(pb); - p->max_audio_blks = avio_rl32(pb); - if (p->buffer_size < 175 || - p->max_audio_blks < 2 || - p->max_video_blks < 1 || - p->frame_blks < 1 || - p->nb_frames < 1 || - p->preload_count < 1 || - p->buffer_size > 2048 || - p->max_video_blks > 2048 || - p->max_audio_blks > 2048 || - p->nb_frames > INT_MAX / sizeof(uint32_t) || - p->frame_blks > INT_MAX / sizeof(uint32_t)) - return AVERROR_INVALIDDATA; - - p->blocks_count_table = av_mallocz(p->nb_frames * sizeof(uint32_t)); - p->frames_offset_table = av_mallocz(p->nb_frames * sizeof(uint32_t)); - p->blocks_offset_table = av_mallocz(p->frame_blks * sizeof(uint32_t)); - - p->video_size = p->max_video_blks * p->buffer_size; - p->video_frame = av_mallocz(p->video_size); - - p->audio_size = p->max_audio_blks * p->buffer_size; - p->audio_frame = av_mallocz(p->audio_size); - p->temp_audio_frame = av_mallocz(p->audio_size); - - if (!p->blocks_count_table || - !p->frames_offset_table || - !p->blocks_offset_table || - !p->video_frame || - !p->audio_frame || - !p->temp_audio_frame) { - ret = AVERROR(ENOMEM); - goto fail; - } - - avio_seek(pb, p->buffer_size, SEEK_SET); - - read_table(s, p->blocks_count_table, p->nb_frames); - read_table(s, p->frames_offset_table, p->nb_frames); - read_table(s, p->blocks_offset_table, p->frame_blks); - - p->got_audio = 0; - p->current_frame = 0; - p->current_frame_block = 0; - - avio_seek(pb, p->start_offset, SEEK_SET); - - return 0; - -fail: - read_close(s); - - return ret; -} - -static int read_packet(AVFormatContext *s, AVPacket *pkt) -{ - PAFDemuxContext *p = s->priv_data; - AVIOContext *pb = s->pb; - uint32_t count, offset; - int size, i; - - if (p->current_frame >= p->nb_frames) - return AVERROR_EOF; - - if (url_feof(pb)) - return AVERROR_EOF; - - if (p->got_audio) { - if (av_new_packet(pkt, p->audio_size) < 0) - return AVERROR(ENOMEM); - - memcpy(pkt->data, p->temp_audio_frame, p->audio_size); - pkt->duration = PAF_SOUND_SAMPLES * (p->audio_size / PAF_SOUND_FRAME_SIZE); - pkt->flags |= AV_PKT_FLAG_KEY; - pkt->stream_index = 1; - p->got_audio = 0; - return pkt->size; - } - - count = (p->current_frame == 0) ? p->preload_count : p->blocks_count_table[p->current_frame - 1]; - for (i = 0; i < count; i++) { - if (p->current_frame_block >= p->frame_blks) - return AVERROR_INVALIDDATA; - - offset = p->blocks_offset_table[p->current_frame_block] & ~(1U << 31); - if (p->blocks_offset_table[p->current_frame_block] & (1U << 31)) { - if (offset > p->audio_size - p->buffer_size) - return AVERROR_INVALIDDATA; - - avio_read(pb, p->audio_frame + offset, p->buffer_size); - if (offset == (p->max_audio_blks - 2) * p->buffer_size) { - memcpy(p->temp_audio_frame, p->audio_frame, p->audio_size); - p->got_audio = 1; - } - } else { - if (offset > p->video_size - p->buffer_size) - return AVERROR_INVALIDDATA; - - avio_read(pb, p->video_frame + offset, p->buffer_size); - } - p->current_frame_block++; - } - - size = p->video_size - p->frames_offset_table[p->current_frame]; - if (size < 1) - return AVERROR_INVALIDDATA; - - if (av_new_packet(pkt, size) < 0) - return AVERROR(ENOMEM); - - pkt->stream_index = 0; - pkt->duration = 1; - memcpy(pkt->data, p->video_frame + p->frames_offset_table[p->current_frame], size); - if (pkt->data[0] & 0x20) - pkt->flags |= AV_PKT_FLAG_KEY; - p->current_frame++; - - return pkt->size; -} - -AVInputFormat ff_paf_demuxer = { - .name = "paf", - .long_name = NULL_IF_CONFIG_SMALL("Amazing Studio Packed Animation File"), - .priv_data_size = sizeof(PAFDemuxContext), - .read_probe = read_probe, - .read_header = read_header, - .read_packet = read_packet, - .read_close = read_close, -}; diff --git a/ffmpeg1/libavformat/pcm.c b/ffmpeg1/libavformat/pcm.c deleted file mode 100644 index 2fe44dc..0000000 --- a/ffmpeg1/libavformat/pcm.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * PCM common functions - * Copyright (c) 2003 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 "libavutil/mathematics.h" -#include "avformat.h" -#include "pcm.h" - -#define RAW_SAMPLES 1024 - -int ff_pcm_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - int ret, size; - - size= RAW_SAMPLES*s->streams[0]->codec->block_align; - if (size <= 0) - return AVERROR(EINVAL); - - ret= av_get_packet(s->pb, pkt, size); - - pkt->flags &= ~AV_PKT_FLAG_CORRUPT; - pkt->stream_index = 0; - if (ret < 0) - return ret; - - return ret; -} - -int ff_pcm_read_seek(AVFormatContext *s, - int stream_index, int64_t timestamp, int flags) -{ - AVStream *st; - int block_align, byte_rate; - int64_t pos, ret; - - st = s->streams[0]; - - block_align = st->codec->block_align ? st->codec->block_align : - (av_get_bits_per_sample(st->codec->codec_id) * st->codec->channels) >> 3; - byte_rate = st->codec->bit_rate ? st->codec->bit_rate >> 3 : - block_align * st->codec->sample_rate; - - if (block_align <= 0 || byte_rate <= 0) - return -1; - if (timestamp < 0) timestamp = 0; - - /* compute the position by aligning it to block_align */ - pos = av_rescale_rnd(timestamp * byte_rate, - st->time_base.num, - st->time_base.den * (int64_t)block_align, - (flags & AVSEEK_FLAG_BACKWARD) ? AV_ROUND_DOWN : AV_ROUND_UP); - pos *= block_align; - - /* recompute exact position */ - st->cur_dts = av_rescale(pos, st->time_base.den, byte_rate * (int64_t)st->time_base.num); - if ((ret = avio_seek(s->pb, pos + s->data_offset, SEEK_SET)) < 0) - return ret; - return 0; -} diff --git a/ffmpeg1/libavformat/pcm.h b/ffmpeg1/libavformat/pcm.h deleted file mode 100644 index 9af36d5..0000000 --- a/ffmpeg1/libavformat/pcm.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * PCM common functions - * Copyright (C) 2007 Aurelien Jacobs - * - * 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 AVFORMAT_PCM_H -#define AVFORMAT_PCM_H - -#include "avformat.h" - -int ff_pcm_read_packet(AVFormatContext *s, AVPacket *pkt); -int ff_pcm_read_seek(AVFormatContext *s, - int stream_index, int64_t timestamp, int flags); - -#endif /* AVFORMAT_PCM_H */ diff --git a/ffmpeg1/libavformat/pcmdec.c b/ffmpeg1/libavformat/pcmdec.c deleted file mode 100644 index f4264d9..0000000 --- a/ffmpeg1/libavformat/pcmdec.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - * RAW PCM demuxers - * Copyright (c) 2002 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 "internal.h" -#include "pcm.h" -#include "libavutil/log.h" -#include "libavutil/opt.h" -#include "libavutil/avassert.h" - -typedef struct PCMAudioDemuxerContext { - AVClass *class; - int sample_rate; - int channels; -} PCMAudioDemuxerContext; - -static int pcm_read_header(AVFormatContext *s) -{ - PCMAudioDemuxerContext *s1 = s->priv_data; - AVStream *st; - - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - - - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = s->iformat->raw_codec_id; - st->codec->sample_rate = s1->sample_rate; - st->codec->channels = s1->channels; - - st->codec->bits_per_coded_sample = - av_get_bits_per_sample(st->codec->codec_id); - - av_assert0(st->codec->bits_per_coded_sample > 0); - - st->codec->block_align = - st->codec->bits_per_coded_sample * st->codec->channels / 8; - - avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); - return 0; -} - -static const AVOption pcm_options[] = { - { "sample_rate", "", offsetof(PCMAudioDemuxerContext, sample_rate), AV_OPT_TYPE_INT, {.i64 = 44100}, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM }, - { "channels", "", offsetof(PCMAudioDemuxerContext, channels), AV_OPT_TYPE_INT, {.i64 = 1}, 0, INT_MAX, AV_OPT_FLAG_DECODING_PARAM }, - { NULL }, -}; - -#define PCMDEF(name_, long_name_, ext, codec) \ -static const AVClass name_ ## _demuxer_class = { \ - .class_name = #name_ " demuxer", \ - .item_name = av_default_item_name, \ - .option = pcm_options, \ - .version = LIBAVUTIL_VERSION_INT, \ -}; \ -AVInputFormat ff_pcm_ ## name_ ## _demuxer = { \ - .name = #name_, \ - .long_name = NULL_IF_CONFIG_SMALL(long_name_), \ - .priv_data_size = sizeof(PCMAudioDemuxerContext), \ - .read_header = pcm_read_header, \ - .read_packet = ff_pcm_read_packet, \ - .read_seek = ff_pcm_read_seek, \ - .flags = AVFMT_GENERIC_INDEX, \ - .extensions = ext, \ - .raw_codec_id = codec, \ - .priv_class = &name_ ## _demuxer_class, \ -}; - -PCMDEF(f64be, "PCM 64-bit floating-point big-endian", - NULL, AV_CODEC_ID_PCM_F64BE) - -PCMDEF(f64le, "PCM 64-bit floating-point little-endian", - NULL, AV_CODEC_ID_PCM_F64LE) - -PCMDEF(f32be, "PCM 32-bit floating-point big-endian", - NULL, AV_CODEC_ID_PCM_F32BE) - -PCMDEF(f32le, "PCM 32-bit floating-point little-endian", - NULL, AV_CODEC_ID_PCM_F32LE) - -PCMDEF(s32be, "PCM signed 32-bit big-endian", - NULL, AV_CODEC_ID_PCM_S32BE) - -PCMDEF(s32le, "PCM signed 32-bit little-endian", - NULL, AV_CODEC_ID_PCM_S32LE) - -PCMDEF(s24be, "PCM signed 24-bit big-endian", - NULL, AV_CODEC_ID_PCM_S24BE) - -PCMDEF(s24le, "PCM signed 24-bit little-endian", - NULL, AV_CODEC_ID_PCM_S24LE) - -PCMDEF(s16be, "PCM signed 16-bit big-endian", - AV_NE("sw", NULL), AV_CODEC_ID_PCM_S16BE) - -PCMDEF(s16le, "PCM signed 16-bit little-endian", - AV_NE(NULL, "sw"), AV_CODEC_ID_PCM_S16LE) - -PCMDEF(s8, "PCM signed 8-bit", - "sb", AV_CODEC_ID_PCM_S8) - -PCMDEF(u32be, "PCM unsigned 32-bit big-endian", - NULL, AV_CODEC_ID_PCM_U32BE) - -PCMDEF(u32le, "PCM unsigned 32-bit little-endian", - NULL, AV_CODEC_ID_PCM_U32LE) - -PCMDEF(u24be, "PCM unsigned 24-bit big-endian", - NULL, AV_CODEC_ID_PCM_U24BE) - -PCMDEF(u24le, "PCM unsigned 24-bit little-endian", - NULL, AV_CODEC_ID_PCM_U24LE) - -PCMDEF(u16be, "PCM unsigned 16-bit big-endian", - AV_NE("uw", NULL), AV_CODEC_ID_PCM_U16BE) - -PCMDEF(u16le, "PCM unsigned 16-bit little-endian", - AV_NE(NULL, "uw"), AV_CODEC_ID_PCM_U16LE) - -PCMDEF(u8, "PCM unsigned 8-bit", - "ub", AV_CODEC_ID_PCM_U8) - -PCMDEF(alaw, "PCM A-law", - "al", AV_CODEC_ID_PCM_ALAW) - -PCMDEF(mulaw, "PCM mu-law", - "ul", AV_CODEC_ID_PCM_MULAW) diff --git a/ffmpeg1/libavformat/pcmenc.c b/ffmpeg1/libavformat/pcmenc.c deleted file mode 100644 index 3e4f308..0000000 --- a/ffmpeg1/libavformat/pcmenc.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * RAW PCM muxers - * Copyright (c) 2002 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 "rawenc.h" - -#define PCMDEF(name_, long_name_, ext, codec) \ -AVOutputFormat ff_pcm_ ## name_ ## _muxer = { \ - .name = #name_, \ - .long_name = NULL_IF_CONFIG_SMALL(long_name_), \ - .extensions = ext, \ - .audio_codec = codec, \ - .video_codec = AV_CODEC_ID_NONE, \ - .write_packet = ff_raw_write_packet, \ - .flags = AVFMT_NOTIMESTAMPS, \ -}; - -PCMDEF(f64be, "PCM 64-bit floating-point big-endian", - NULL, AV_CODEC_ID_PCM_F64BE) - -PCMDEF(f64le, "PCM 64-bit floating-point little-endian", - NULL, AV_CODEC_ID_PCM_F64LE) - -PCMDEF(f32be, "PCM 32-bit floating-point big-endian", - NULL, AV_CODEC_ID_PCM_F32BE) - -PCMDEF(f32le, "PCM 32-bit floating-point little-endian", - NULL, AV_CODEC_ID_PCM_F32LE) - -PCMDEF(s32be, "PCM signed 32-bit big-endian", - NULL, AV_CODEC_ID_PCM_S32BE) - -PCMDEF(s32le, "PCM signed 32-bit little-endian", - NULL, AV_CODEC_ID_PCM_S32LE) - -PCMDEF(s24be, "PCM signed 24-bit big-endian", - NULL, AV_CODEC_ID_PCM_S24BE) - -PCMDEF(s24le, "PCM signed 24-bit little-endian", - NULL, AV_CODEC_ID_PCM_S24LE) - -PCMDEF(s16be, "PCM signed 16-bit big-endian", - AV_NE("sw", NULL), AV_CODEC_ID_PCM_S16BE) - -PCMDEF(s16le, "PCM signed 16-bit little-endian", - AV_NE(NULL, "sw"), AV_CODEC_ID_PCM_S16LE) - -PCMDEF(s8, "PCM signed 8-bit", - "sb", AV_CODEC_ID_PCM_S8) - -PCMDEF(u32be, "PCM unsigned 32-bit big-endian", - NULL, AV_CODEC_ID_PCM_U32BE) - -PCMDEF(u32le, "PCM unsigned 32-bit little-endian", - NULL, AV_CODEC_ID_PCM_U32LE) - -PCMDEF(u24be, "PCM unsigned 24-bit big-endian", - NULL, AV_CODEC_ID_PCM_U24BE) - -PCMDEF(u24le, "PCM unsigned 24-bit little-endian", - NULL, AV_CODEC_ID_PCM_U24LE) - -PCMDEF(u16be, "PCM unsigned 16-bit big-endian", - AV_NE("uw", NULL), AV_CODEC_ID_PCM_U16BE) - -PCMDEF(u16le, "PCM unsigned 16-bit little-endian", - AV_NE(NULL, "uw"), AV_CODEC_ID_PCM_U16LE) - -PCMDEF(u8, "PCM unsigned 8-bit", - "ub", AV_CODEC_ID_PCM_U8) - -PCMDEF(alaw, "PCM A-law", - "al", AV_CODEC_ID_PCM_ALAW) - -PCMDEF(mulaw, "PCM mu-law", - "ul", AV_CODEC_ID_PCM_MULAW) diff --git a/ffmpeg1/libavformat/pjsdec.c b/ffmpeg1/libavformat/pjsdec.c deleted file mode 100644 index ef2b626..0000000 --- a/ffmpeg1/libavformat/pjsdec.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2012 Clément BÅ“sch - * - * 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 - */ - -/** - * @file - * PJS (Phoenix Japanimation Society) subtitles format demuxer - * - * @see http://subs.com.ru/page.php?al=pjs - */ - -#include "avformat.h" -#include "internal.h" -#include "subtitles.h" - -typedef struct { - FFDemuxSubtitlesQueue q; -} PJSContext; - -static int pjs_probe(AVProbeData *p) -{ - char c; - int64_t start, end; - const unsigned char *ptr = p->buf; - - if (sscanf(ptr, "%"PRId64",%"PRId64",%c", &start, &end, &c) == 3) { - size_t q1pos = strcspn(ptr, "\""); - size_t q2pos = q1pos + strcspn(ptr + q1pos + 1, "\"") + 1; - if (strcspn(ptr, "\r\n") > q2pos) - return AVPROBE_SCORE_MAX; - } - return 0; -} - -static int64_t read_ts(char **line, int *duration) -{ - int64_t start, end; - - if (sscanf(*line, "%"PRId64",%"PRId64, &start, &end) == 2) { - *line += strcspn(*line, "\"") + 1; - *duration = end - start; - return start; - } - return AV_NOPTS_VALUE; -} - -static int pjs_read_header(AVFormatContext *s) -{ - PJSContext *pjs = s->priv_data; - AVStream *st = avformat_new_stream(s, NULL); - int res = 0; - - if (!st) - return AVERROR(ENOMEM); - avpriv_set_pts_info(st, 64, 1, 10); - st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE; - st->codec->codec_id = AV_CODEC_ID_PJS; - - while (!url_feof(s->pb)) { - char line[4096]; - char *p = line; - const int64_t pos = avio_tell(s->pb); - int len = ff_get_line(s->pb, line, sizeof(line)); - int64_t pts_start; - int duration; - - if (!len) - break; - - line[strcspn(line, "\r\n")] = 0; - - pts_start = read_ts(&p, &duration); - if (pts_start != AV_NOPTS_VALUE) { - AVPacket *sub; - - p[strcspn(p, "\"")] = 0; - sub = ff_subtitles_queue_insert(&pjs->q, p, strlen(p), 0); - if (!sub) - return AVERROR(ENOMEM); - sub->pos = pos; - sub->pts = pts_start; - sub->duration = duration; - } - } - - ff_subtitles_queue_finalize(&pjs->q); - return res; -} - -static int pjs_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - PJSContext *pjs = s->priv_data; - return ff_subtitles_queue_read_packet(&pjs->q, pkt); -} - -static int pjs_read_seek(AVFormatContext *s, int stream_index, - int64_t min_ts, int64_t ts, int64_t max_ts, int flags) -{ - PJSContext *pjs = s->priv_data; - return ff_subtitles_queue_seek(&pjs->q, s, stream_index, - min_ts, ts, max_ts, flags); -} - -static int pjs_read_close(AVFormatContext *s) -{ - PJSContext *pjs = s->priv_data; - ff_subtitles_queue_clean(&pjs->q); - return 0; -} - -AVInputFormat ff_pjs_demuxer = { - .name = "pjs", - .long_name = NULL_IF_CONFIG_SMALL("PJS (Phoenix Japanimation Society) subtitles"), - .priv_data_size = sizeof(PJSContext), - .read_probe = pjs_probe, - .read_header = pjs_read_header, - .read_packet = pjs_read_packet, - .read_seek2 = pjs_read_seek, - .read_close = pjs_read_close, - .extensions = "pjs", -}; diff --git a/ffmpeg1/libavformat/pmpdec.c b/ffmpeg1/libavformat/pmpdec.c deleted file mode 100644 index 2fe6c46..0000000 --- a/ffmpeg1/libavformat/pmpdec.c +++ /dev/null @@ -1,197 +0,0 @@ -/* - * PMP demuxer. - * Copyright (c) 2011 Reimar Döffinger - * - * 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 "libavutil/intreadwrite.h" -#include "avformat.h" -#include "internal.h" - -typedef struct { - int cur_stream; - int num_streams; - int audio_packets; - int current_packet; - uint32_t *packet_sizes; - int packet_sizes_alloc; -} PMPContext; - -static int pmp_probe(AVProbeData *p) { - if (AV_RN32(p->buf) == AV_RN32("pmpm") && - AV_RL32(p->buf + 4) == 1) - return AVPROBE_SCORE_MAX; - return 0; -} - -static int pmp_header(AVFormatContext *s) -{ - PMPContext *pmp = s->priv_data; - AVIOContext *pb = s->pb; - int tb_num, tb_den; - uint32_t index_cnt; - int audio_codec_id = AV_CODEC_ID_NONE; - int srate, channels; - unsigned i; - uint64_t pos; - int64_t fsize = avio_size(pb); - - AVStream *vst = avformat_new_stream(s, NULL); - if (!vst) - return AVERROR(ENOMEM); - vst->codec->codec_type = AVMEDIA_TYPE_VIDEO; - avio_skip(pb, 8); - switch (avio_rl32(pb)) { - case 0: - vst->codec->codec_id = AV_CODEC_ID_MPEG4; - break; - case 1: - vst->codec->codec_id = AV_CODEC_ID_H264; - break; - default: - av_log(s, AV_LOG_ERROR, "Unsupported video format\n"); - break; - } - index_cnt = avio_rl32(pb); - vst->codec->width = avio_rl32(pb); - vst->codec->height = avio_rl32(pb); - - tb_num = avio_rl32(pb); - tb_den = avio_rl32(pb); - avpriv_set_pts_info(vst, 32, tb_num, tb_den); - vst->nb_frames = index_cnt; - vst->duration = index_cnt; - - switch (avio_rl32(pb)) { - case 0: - audio_codec_id = AV_CODEC_ID_MP3; - break; - case 1: - av_log(s, AV_LOG_ERROR, "AAC not yet correctly supported\n"); - audio_codec_id = AV_CODEC_ID_AAC; - break; - default: - av_log(s, AV_LOG_ERROR, "Unsupported audio format\n"); - break; - } - pmp->num_streams = avio_rl16(pb) + 1; - avio_skip(pb, 10); - srate = avio_rl32(pb); - channels = avio_rl32(pb) + 1; - pos = avio_tell(pb) + 4LL*index_cnt; - for (i = 0; i < index_cnt; i++) { - uint32_t size = avio_rl32(pb); - int flags = size & 1 ? AVINDEX_KEYFRAME : 0; - if (url_feof(pb)) { - av_log(s, AV_LOG_FATAL, "Encountered EOF while reading index.\n"); - return AVERROR_INVALIDDATA; - } - size >>= 1; - if (size < 9 + 4*pmp->num_streams) { - av_log(s, AV_LOG_ERROR, "Packet too small\n"); - return AVERROR_INVALIDDATA; - } - av_add_index_entry(vst, pos, i, size, 0, flags); - pos += size; - if (fsize > 0 && i == 0 && pos > fsize) { - av_log(s, AV_LOG_ERROR, "File ends before first packet\n"); - return AVERROR_INVALIDDATA; - } - } - for (i = 1; i < pmp->num_streams; i++) { - AVStream *ast = avformat_new_stream(s, NULL); - if (!ast) - return AVERROR(ENOMEM); - ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; - ast->codec->codec_id = audio_codec_id; - ast->codec->channels = channels; - ast->codec->sample_rate = srate; - avpriv_set_pts_info(ast, 32, 1, srate); - } - return 0; -} - -static int pmp_packet(AVFormatContext *s, AVPacket *pkt) -{ - PMPContext *pmp = s->priv_data; - AVIOContext *pb = s->pb; - int ret = 0; - int i; - - if (url_feof(pb)) - return AVERROR_EOF; - if (pmp->cur_stream == 0) { - int num_packets; - pmp->audio_packets = avio_r8(pb); - if (!pmp->audio_packets) { - avpriv_request_sample(s, "0 audio packets"); - return AVERROR_PATCHWELCOME; - } - num_packets = (pmp->num_streams - 1) * pmp->audio_packets + 1; - avio_skip(pb, 8); - pmp->current_packet = 0; - av_fast_malloc(&pmp->packet_sizes, - &pmp->packet_sizes_alloc, - num_packets * sizeof(*pmp->packet_sizes)); - if (!pmp->packet_sizes_alloc) { - av_log(s, AV_LOG_ERROR, "Cannot (re)allocate packet buffer\n"); - return AVERROR(ENOMEM); - } - for (i = 0; i < num_packets; i++) - pmp->packet_sizes[i] = avio_rl32(pb); - } - ret = av_get_packet(pb, pkt, pmp->packet_sizes[pmp->current_packet]); - if (ret >= 0) { - ret = 0; - // FIXME: this is a hack that should be removed once - // compute_pkt_fields() can handle timestamps properly - if (pmp->cur_stream == 0) - pkt->dts = s->streams[0]->cur_dts++; - pkt->stream_index = pmp->cur_stream; - } - if (pmp->current_packet % pmp->audio_packets == 0) - pmp->cur_stream = (pmp->cur_stream + 1) % pmp->num_streams; - pmp->current_packet++; - return ret; -} - -static int pmp_seek(AVFormatContext *s, int stream_index, int64_t ts, int flags) -{ - PMPContext *pmp = s->priv_data; - pmp->cur_stream = 0; - // fallback to default seek now - return -1; -} - -static int pmp_close(AVFormatContext *s) -{ - PMPContext *pmp = s->priv_data; - av_freep(&pmp->packet_sizes); - return 0; -} - -AVInputFormat ff_pmp_demuxer = { - .name = "pmp", - .long_name = NULL_IF_CONFIG_SMALL("Playstation Portable PMP"), - .priv_data_size = sizeof(PMPContext), - .read_probe = pmp_probe, - .read_header = pmp_header, - .read_packet = pmp_packet, - .read_seek = pmp_seek, - .read_close = pmp_close, -}; diff --git a/ffmpeg1/libavformat/psxstr.c b/ffmpeg1/libavformat/psxstr.c deleted file mode 100644 index 90c933e..0000000 --- a/ffmpeg1/libavformat/psxstr.c +++ /dev/null @@ -1,317 +0,0 @@ -/* - * Sony Playstation (PSX) STR File Demuxer - * Copyright (c) 2003 The ffmpeg Project - * - * 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 - */ - -/** - * @file - * PSX STR file demuxer - * by Mike Melanson (melanson@pcisys.net) - * This module handles streams that have been ripped from Sony Playstation - * CD games. This demuxer can handle either raw STR files (which are just - * concatenations of raw compact disc sectors) or STR files with 0x2C-byte - * RIFF headers, followed by CD sectors. - */ - -#include "libavutil/channel_layout.h" -#include "libavutil/intreadwrite.h" -#include "avformat.h" -#include "internal.h" - -#define RIFF_TAG MKTAG('R', 'I', 'F', 'F') -#define CDXA_TAG MKTAG('C', 'D', 'X', 'A') - -#define RAW_CD_SECTOR_SIZE 2352 -#define RAW_CD_SECTOR_DATA_SIZE 2304 -#define VIDEO_DATA_CHUNK_SIZE 0x7E0 -#define VIDEO_DATA_HEADER_SIZE 0x38 -#define RIFF_HEADER_SIZE 0x2C - -#define CDXA_TYPE_MASK 0x0E -#define CDXA_TYPE_DATA 0x08 -#define CDXA_TYPE_AUDIO 0x04 -#define CDXA_TYPE_VIDEO 0x02 - -#define STR_MAGIC (0x80010160) - -typedef struct StrChannel { - /* video parameters */ - int video_stream_index; - AVPacket tmp_pkt; - - /* audio parameters */ - int audio_stream_index; -} StrChannel; - -typedef struct StrDemuxContext { - - /* a STR file can contain up to 32 channels of data */ - StrChannel channels[32]; -} StrDemuxContext; - -static const uint8_t sync_header[12] = {0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00}; - -static int str_probe(AVProbeData *p) -{ - const uint8_t *sector= p->buf; - const uint8_t *end= sector + p->buf_size; - int aud=0, vid=0; - - if (p->buf_size < RAW_CD_SECTOR_SIZE) - return 0; - - if ((AV_RL32(&p->buf[0]) == RIFF_TAG) && - (AV_RL32(&p->buf[8]) == CDXA_TAG)) { - - /* RIFF header seen; skip 0x2C bytes */ - sector += RIFF_HEADER_SIZE; - } - - while (end - sector >= RAW_CD_SECTOR_SIZE) { - /* look for CD sync header (00, 0xFF x 10, 00) */ - if (memcmp(sector,sync_header,sizeof(sync_header))) - return 0; - - if (sector[0x11] >= 32) - return 0; - - switch (sector[0x12] & CDXA_TYPE_MASK) { - case CDXA_TYPE_DATA: - case CDXA_TYPE_VIDEO: { - int current_sector = AV_RL16(§or[0x1C]); - int sector_count = AV_RL16(§or[0x1E]); - int frame_size = AV_RL32(§or[0x24]); - - if(!( frame_size>=0 - && current_sector < sector_count - && sector_count*VIDEO_DATA_CHUNK_SIZE >=frame_size)){ - return 0; - } - - /*st->codec->width = AV_RL16(§or[0x28]); - st->codec->height = AV_RL16(§or[0x2A]);*/ - -// if (current_sector == sector_count-1) { - vid++; -// } - - } - break; - case CDXA_TYPE_AUDIO: - if(sector[0x13]&0x2A) - return 0; - aud++; - break; - default: - if(sector[0x12] & CDXA_TYPE_MASK) - return 0; - } - sector += RAW_CD_SECTOR_SIZE; - } - /* MPEG files (like those ripped from VCDs) can also look like this; - * only return half certainty */ - if(vid+aud > 3) return 50; - else if(vid+aud) return 1; - else return 0; -} - -static int str_read_header(AVFormatContext *s) -{ - AVIOContext *pb = s->pb; - StrDemuxContext *str = s->priv_data; - unsigned char sector[RAW_CD_SECTOR_SIZE]; - int start; - int i; - - /* skip over any RIFF header */ - if (avio_read(pb, sector, RIFF_HEADER_SIZE) != RIFF_HEADER_SIZE) - return AVERROR(EIO); - if (AV_RL32(§or[0]) == RIFF_TAG) - start = RIFF_HEADER_SIZE; - else - start = 0; - - avio_seek(pb, start, SEEK_SET); - - for(i=0; i<32; i++){ - str->channels[i].video_stream_index= - str->channels[i].audio_stream_index= -1; - } - - s->ctx_flags |= AVFMTCTX_NOHEADER; - - return 0; -} - -static int str_read_packet(AVFormatContext *s, - AVPacket *ret_pkt) -{ - AVIOContext *pb = s->pb; - StrDemuxContext *str = s->priv_data; - unsigned char sector[RAW_CD_SECTOR_SIZE]; - int channel; - AVPacket *pkt; - AVStream *st; - - while (1) { - - if (avio_read(pb, sector, RAW_CD_SECTOR_SIZE) != RAW_CD_SECTOR_SIZE) - return AVERROR(EIO); - - channel = sector[0x11]; - if (channel >= 32) - return AVERROR_INVALIDDATA; - - switch (sector[0x12] & CDXA_TYPE_MASK) { - - case CDXA_TYPE_DATA: - case CDXA_TYPE_VIDEO: - { - - int current_sector = AV_RL16(§or[0x1C]); - int sector_count = AV_RL16(§or[0x1E]); - int frame_size = AV_RL32(§or[0x24]); - - if(!( frame_size>=0 - && current_sector < sector_count - && sector_count*VIDEO_DATA_CHUNK_SIZE >=frame_size)){ - av_log(s, AV_LOG_ERROR, "Invalid parameters %d %d %d\n", current_sector, sector_count, frame_size); - break; - } - - if(str->channels[channel].video_stream_index < 0){ - /* allocate a new AVStream */ - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - avpriv_set_pts_info(st, 64, 1, 15); - - str->channels[channel].video_stream_index = st->index; - - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = AV_CODEC_ID_MDEC; - st->codec->codec_tag = 0; /* no fourcc */ - st->codec->width = AV_RL16(§or[0x28]); - st->codec->height = AV_RL16(§or[0x2A]); - } - - /* if this is the first sector of the frame, allocate a pkt */ - pkt = &str->channels[channel].tmp_pkt; - - if(pkt->size != sector_count*VIDEO_DATA_CHUNK_SIZE){ - if(pkt->data) - av_log(s, AV_LOG_ERROR, "missmatching sector_count\n"); - av_free_packet(pkt); - if (av_new_packet(pkt, sector_count*VIDEO_DATA_CHUNK_SIZE)) - return AVERROR(EIO); - - pkt->pos= avio_tell(pb) - RAW_CD_SECTOR_SIZE; - pkt->stream_index = - str->channels[channel].video_stream_index; - } - - memcpy(pkt->data + current_sector*VIDEO_DATA_CHUNK_SIZE, - sector + VIDEO_DATA_HEADER_SIZE, - VIDEO_DATA_CHUNK_SIZE); - - if (current_sector == sector_count-1) { - pkt->size= frame_size; - *ret_pkt = *pkt; - pkt->data= NULL; - pkt->size= -1; - pkt->buf = NULL; -#if FF_API_DESTRUCT_PACKET - pkt->destruct = NULL; -#endif - return 0; - } - - } - break; - - case CDXA_TYPE_AUDIO: - if(str->channels[channel].audio_stream_index < 0){ - int fmt = sector[0x13]; - /* allocate a new AVStream */ - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - - str->channels[channel].audio_stream_index = st->index; - - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = AV_CODEC_ID_ADPCM_XA; - st->codec->codec_tag = 0; /* no fourcc */ - if (fmt & 1) { - st->codec->channels = 2; - st->codec->channel_layout = AV_CH_LAYOUT_STEREO; - } else { - st->codec->channels = 1; - st->codec->channel_layout = AV_CH_LAYOUT_MONO; - } - st->codec->sample_rate = (fmt&4)?18900:37800; - // st->codec->bit_rate = 0; //FIXME; - st->codec->block_align = 128; - - avpriv_set_pts_info(st, 64, 18 * 224 / st->codec->channels, - st->codec->sample_rate); - st->start_time = 0; - } - pkt = ret_pkt; - if (av_new_packet(pkt, 2304)) - return AVERROR(EIO); - memcpy(pkt->data,sector+24,2304); - - pkt->stream_index = - str->channels[channel].audio_stream_index; - pkt->duration = 1; - return 0; - default: - av_log(s, AV_LOG_WARNING, "Unknown sector type %02X\n", sector[0x12]); - /* drop the sector and move on */ - break; - } - - if (url_feof(pb)) - return AVERROR(EIO); - } -} - -static int str_read_close(AVFormatContext *s) -{ - StrDemuxContext *str = s->priv_data; - int i; - for(i=0; i<32; i++){ - if(str->channels[i].tmp_pkt.data) - av_free_packet(&str->channels[i].tmp_pkt); - } - - return 0; -} - -AVInputFormat ff_str_demuxer = { - .name = "psxstr", - .long_name = NULL_IF_CONFIG_SMALL("Sony Playstation STR"), - .priv_data_size = sizeof(StrDemuxContext), - .read_probe = str_probe, - .read_header = str_read_header, - .read_packet = str_read_packet, - .read_close = str_read_close, - .flags = AVFMT_NO_BYTE_SEEK, -}; diff --git a/ffmpeg1/libavformat/pva.c b/ffmpeg1/libavformat/pva.c deleted file mode 100644 index ae42c83..0000000 --- a/ffmpeg1/libavformat/pva.c +++ /dev/null @@ -1,225 +0,0 @@ -/* - * TechnoTrend PVA (.pva) demuxer - * Copyright (c) 2007, 2008 Ivo van Poorten - * - * 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 "internal.h" -#include "mpeg.h" - -#define PVA_MAX_PAYLOAD_LENGTH 0x17f8 -#define PVA_VIDEO_PAYLOAD 0x01 -#define PVA_AUDIO_PAYLOAD 0x02 -#define PVA_MAGIC (('A' << 8) + 'V') - -typedef struct { - int continue_pes; -} PVAContext; - -static int pva_check(const uint8_t *p) { - int length = AV_RB16(p + 6); - if (AV_RB16(p) != PVA_MAGIC || !p[2] || p[2] > 2 || p[4] != 0x55 || - (p[5] & 0xe0) || length > PVA_MAX_PAYLOAD_LENGTH) - return -1; - return length + 8; -} - -static int pva_probe(AVProbeData * pd) { - const unsigned char *buf = pd->buf; - int len = pva_check(buf); - - if (len < 0) - return 0; - - if (pd->buf_size >= len + 8 && - pva_check(buf + len) >= 0) - return AVPROBE_SCORE_MAX / 2; - - return AVPROBE_SCORE_MAX / 4; -} - -static int pva_read_header(AVFormatContext *s) { - AVStream *st; - - if (!(st = avformat_new_stream(s, NULL))) - return AVERROR(ENOMEM); - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = AV_CODEC_ID_MPEG2VIDEO; - st->need_parsing = AVSTREAM_PARSE_FULL; - avpriv_set_pts_info(st, 32, 1, 90000); - av_add_index_entry(st, 0, 0, 0, 0, AVINDEX_KEYFRAME); - - if (!(st = avformat_new_stream(s, NULL))) - return AVERROR(ENOMEM); - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = AV_CODEC_ID_MP2; - st->need_parsing = AVSTREAM_PARSE_FULL; - avpriv_set_pts_info(st, 33, 1, 90000); - av_add_index_entry(st, 0, 0, 0, 0, AVINDEX_KEYFRAME); - - /* the parameters will be extracted from the compressed bitstream */ - return 0; -} - -#define pva_log if (read_packet) av_log - -static int read_part_of_packet(AVFormatContext *s, int64_t *pts, - int *len, int *strid, int read_packet) { - AVIOContext *pb = s->pb; - PVAContext *pvactx = s->priv_data; - int syncword, streamid, reserved, flags, length, pts_flag; - int64_t pva_pts = AV_NOPTS_VALUE, startpos; - -recover: - startpos = avio_tell(pb); - - syncword = avio_rb16(pb); - streamid = avio_r8(pb); - avio_r8(pb); /* counter not used */ - reserved = avio_r8(pb); - flags = avio_r8(pb); - length = avio_rb16(pb); - - pts_flag = flags & 0x10; - - if (syncword != PVA_MAGIC) { - pva_log(s, AV_LOG_ERROR, "invalid syncword\n"); - return AVERROR(EIO); - } - if (streamid != PVA_VIDEO_PAYLOAD && streamid != PVA_AUDIO_PAYLOAD) { - pva_log(s, AV_LOG_ERROR, "invalid streamid\n"); - return AVERROR(EIO); - } - if (reserved != 0x55) { - pva_log(s, AV_LOG_WARNING, "expected reserved byte to be 0x55\n"); - } - if (length > PVA_MAX_PAYLOAD_LENGTH) { - pva_log(s, AV_LOG_ERROR, "invalid payload length %u\n", length); - return AVERROR(EIO); - } - - if (streamid == PVA_VIDEO_PAYLOAD && pts_flag) { - pva_pts = avio_rb32(pb); - length -= 4; - } else if (streamid == PVA_AUDIO_PAYLOAD) { - /* PVA Audio Packets either start with a signaled PES packet or - * are a continuation of the previous PES packet. New PES packets - * always start at the beginning of a PVA Packet, never somewhere in - * the middle. */ - if (!pvactx->continue_pes) { - int pes_signal, pes_header_data_length, pes_packet_length, - pes_flags; - unsigned char pes_header_data[256]; - - pes_signal = avio_rb24(pb); - avio_r8(pb); - pes_packet_length = avio_rb16(pb); - pes_flags = avio_rb16(pb); - pes_header_data_length = avio_r8(pb); - - if (pes_signal != 1) { - pva_log(s, AV_LOG_WARNING, "expected signaled PES packet, " - "trying to recover\n"); - avio_skip(pb, length - 9); - if (!read_packet) - return AVERROR(EIO); - goto recover; - } - - avio_read(pb, pes_header_data, pes_header_data_length); - length -= 9 + pes_header_data_length; - - pes_packet_length -= 3 + pes_header_data_length; - - pvactx->continue_pes = pes_packet_length; - - if (pes_flags & 0x80 && (pes_header_data[0] & 0xf0) == 0x20) - pva_pts = ff_parse_pes_pts(pes_header_data); - } - - pvactx->continue_pes -= length; - - if (pvactx->continue_pes < 0) { - pva_log(s, AV_LOG_WARNING, "audio data corruption\n"); - pvactx->continue_pes = 0; - } - } - - if (pva_pts != AV_NOPTS_VALUE) - av_add_index_entry(s->streams[streamid-1], startpos, pva_pts, 0, 0, AVINDEX_KEYFRAME); - - *pts = pva_pts; - *len = length; - *strid = streamid; - return 0; -} - -static int pva_read_packet(AVFormatContext *s, AVPacket *pkt) { - AVIOContext *pb = s->pb; - int64_t pva_pts; - int ret, length, streamid; - - if (read_part_of_packet(s, &pva_pts, &length, &streamid, 1) < 0 || - (ret = av_get_packet(pb, pkt, length)) <= 0) - return AVERROR(EIO); - - pkt->stream_index = streamid - 1; - pkt->pts = pva_pts; - - return ret; -} - -static int64_t pva_read_timestamp(struct AVFormatContext *s, int stream_index, - int64_t *pos, int64_t pos_limit) { - AVIOContext *pb = s->pb; - PVAContext *pvactx = s->priv_data; - int length, streamid; - int64_t res = AV_NOPTS_VALUE; - - pos_limit = FFMIN(*pos+PVA_MAX_PAYLOAD_LENGTH*8, (uint64_t)*pos+pos_limit); - - while (*pos < pos_limit) { - res = AV_NOPTS_VALUE; - avio_seek(pb, *pos, SEEK_SET); - - pvactx->continue_pes = 0; - if (read_part_of_packet(s, &res, &length, &streamid, 0)) { - (*pos)++; - continue; - } - if (streamid - 1 != stream_index || res == AV_NOPTS_VALUE) { - *pos = avio_tell(pb) + length; - continue; - } - break; - } - - pvactx->continue_pes = 0; - return res; -} - -AVInputFormat ff_pva_demuxer = { - .name = "pva", - .long_name = NULL_IF_CONFIG_SMALL("TechnoTrend PVA"), - .priv_data_size = sizeof(PVAContext), - .read_probe = pva_probe, - .read_header = pva_read_header, - .read_packet = pva_read_packet, - .read_timestamp = pva_read_timestamp, -}; diff --git a/ffmpeg1/libavformat/pvfdec.c b/ffmpeg1/libavformat/pvfdec.c deleted file mode 100644 index c678046..0000000 --- a/ffmpeg1/libavformat/pvfdec.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * PVF demuxer - * Copyright (c) 2012 Paul B Mahol - * - * 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 "internal.h" -#include "pcm.h" - -static int pvf_probe(AVProbeData *p) -{ - if (!memcmp(p->buf, "PVF1\n", 5)) - return AVPROBE_SCORE_MAX; - return 0; -} - -static int pvf_read_header(AVFormatContext *s) -{ - char buffer[32]; - AVStream *st; - int bps, channels, sample_rate; - - avio_skip(s->pb, 5); - ff_get_line(s->pb, buffer, sizeof(buffer)); - if (sscanf(buffer, "%d %d %d", - &channels, - &sample_rate, - &bps) != 3) - return AVERROR_INVALIDDATA; - - if (channels <= 0 || bps <= 0 || sample_rate <= 0) - return AVERROR_INVALIDDATA; - - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->channels = channels; - st->codec->sample_rate = sample_rate; - st->codec->codec_id = ff_get_pcm_codec_id(bps, 0, 1, 0xFFFF); - st->codec->bits_per_coded_sample = bps; - st->codec->block_align = bps * st->codec->channels / 8; - - avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); - - return 0; -} - -AVInputFormat ff_pvf_demuxer = { - .name = "pvf", - .long_name = NULL_IF_CONFIG_SMALL("PVF (Portable Voice Format)"), - .read_probe = pvf_probe, - .read_header = pvf_read_header, - .read_packet = ff_pcm_read_packet, - .read_seek = ff_pcm_read_seek, - .extensions = "pvf", - .flags = AVFMT_GENERIC_INDEX, -}; diff --git a/ffmpeg1/libavformat/qcp.c b/ffmpeg1/libavformat/qcp.c deleted file mode 100644 index 1ef86fe..0000000 --- a/ffmpeg1/libavformat/qcp.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - * QCP format (.qcp) demuxer - * Copyright (c) 2009 Kenan Gillet - * - * 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 - */ - -/** - * @file - * QCP format (.qcp) demuxer - * @author Kenan Gillet - * @see RFC 3625: "The QCP File Format and Media Types for Speech Data" - * http://tools.ietf.org/html/rfc3625 - */ - -#include "libavutil/channel_layout.h" -#include "libavutil/intreadwrite.h" -#include "avformat.h" - -typedef struct { - uint32_t data_size; ///< size of data chunk - -#define QCP_MAX_MODE 4 - int16_t rates_per_mode[QCP_MAX_MODE+1]; ///< contains the packet size corresponding - ///< to each mode, -1 if no size. -} QCPContext; - -/** - * Last 15 out of 16 bytes of QCELP-13K GUID, as stored in the file; - * the first byte of the GUID can be either 0x41 or 0x42. - */ -static const uint8_t guid_qcelp_13k_part[15] = { - 0x6d, 0x7f, 0x5e, 0x15, 0xb1, 0xd0, 0x11, 0xba, - 0x91, 0x00, 0x80, 0x5f, 0xb4, 0xb9, 0x7e -}; - -/** - * EVRC GUID as stored in the file - */ -static const uint8_t guid_evrc[16] = { - 0x8d, 0xd4, 0x89, 0xe6, 0x76, 0x90, 0xb5, 0x46, - 0x91, 0xef, 0x73, 0x6a, 0x51, 0x00, 0xce, 0xb4 -}; - -/** - * SMV GUID as stored in the file - */ -static const uint8_t guid_smv[16] = { - 0x75, 0x2b, 0x7c, 0x8d, 0x97, 0xa7, 0x49, 0xed, - 0x98, 0x5e, 0xd5, 0x3c, 0x8c, 0xc7, 0x5f, 0x84 -}; - -/** - * @param guid contains at least 16 bytes - * @return 1 if the guid is a qcelp_13k guid, 0 otherwise - */ -static int is_qcelp_13k_guid(const uint8_t *guid) { - return (guid[0] == 0x41 || guid[0] == 0x42) - && !memcmp(guid+1, guid_qcelp_13k_part, sizeof(guid_qcelp_13k_part)); -} - -static int qcp_probe(AVProbeData *pd) -{ - if (AV_RL32(pd->buf ) == AV_RL32("RIFF") && - AV_RL64(pd->buf+8) == AV_RL64("QLCMfmt ")) - return AVPROBE_SCORE_MAX; - return 0; -} - -static int qcp_read_header(AVFormatContext *s) -{ - AVIOContext *pb = s->pb; - QCPContext *c = s->priv_data; - AVStream *st = avformat_new_stream(s, NULL); - uint8_t buf[16]; - int i, nb_rates; - - if (!st) - return AVERROR(ENOMEM); - - avio_rb32(pb); // "RIFF" - avio_skip(pb, 4 + 8 + 4 + 1 + 1); // filesize + "QLCMfmt " + chunk-size + major-version + minor-version - - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->channels = 1; - st->codec->channel_layout = AV_CH_LAYOUT_MONO; - avio_read(pb, buf, 16); - if (is_qcelp_13k_guid(buf)) { - st->codec->codec_id = AV_CODEC_ID_QCELP; - } else if (!memcmp(buf, guid_evrc, 16)) { - st->codec->codec_id = AV_CODEC_ID_EVRC; - } else if (!memcmp(buf, guid_smv, 16)) { - st->codec->codec_id = AV_CODEC_ID_SMV; - } else { - av_log(s, AV_LOG_ERROR, "Unknown codec GUID.\n"); - return AVERROR_INVALIDDATA; - } - avio_skip(pb, 2 + 80); // codec-version + codec-name - st->codec->bit_rate = avio_rl16(pb); - - s->packet_size = avio_rl16(pb); - avio_skip(pb, 2); // block-size - st->codec->sample_rate = avio_rl16(pb); - avio_skip(pb, 2); // sample-size - - memset(c->rates_per_mode, -1, sizeof(c->rates_per_mode)); - nb_rates = avio_rl32(pb); - nb_rates = FFMIN(nb_rates, 8); - for (i=0; i QCP_MAX_MODE) { - av_log(s, AV_LOG_WARNING, "Unknown entry %d=>%d in rate-map-table.\n ", mode, size); - } else - c->rates_per_mode[mode] = size; - } - avio_skip(pb, 16 - 2*nb_rates + 20); // empty entries of rate-map-table + reserved - - return 0; -} - -static int qcp_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - AVIOContext *pb = s->pb; - QCPContext *c = s->priv_data; - unsigned int chunk_size, tag; - - while(!url_feof(pb)) { - if (c->data_size) { - int pkt_size, ret, mode = avio_r8(pb); - - if (s->packet_size) { - pkt_size = s->packet_size - 1; - } else if (mode > QCP_MAX_MODE || (pkt_size = c->rates_per_mode[mode]) < 0) { - c->data_size--; - continue; - } - - if (c->data_size <= pkt_size) { - av_log(s, AV_LOG_WARNING, "Data chunk is too small.\n"); - pkt_size = c->data_size - 1; - } - - if ((ret = av_get_packet(pb, pkt, pkt_size)) >= 0) { - if (pkt_size != ret) - av_log(s, AV_LOG_ERROR, "Packet size is too small.\n"); - - c->data_size -= pkt_size + 1; - } - return ret; - } - - if (avio_tell(pb) & 1 && avio_r8(pb)) - av_log(s, AV_LOG_WARNING, "Padding should be 0.\n"); - - tag = avio_rl32(pb); - chunk_size = avio_rl32(pb); - switch (tag) { - case MKTAG('v', 'r', 'a', 't'): - if (avio_rl32(pb)) // var-rate-flag - s->packet_size = 0; - avio_skip(pb, 4); // size-in-packets - break; - case MKTAG('d', 'a', 't', 'a'): - c->data_size = chunk_size; - break; - - default: - avio_skip(pb, chunk_size); - } - } - return AVERROR_EOF; -} - -AVInputFormat ff_qcp_demuxer = { - .name = "qcp", - .long_name = NULL_IF_CONFIG_SMALL("QCP"), - .priv_data_size = sizeof(QCPContext), - .read_probe = qcp_probe, - .read_header = qcp_read_header, - .read_packet = qcp_read_packet, -}; diff --git a/ffmpeg1/libavformat/qtpalette.h b/ffmpeg1/libavformat/qtpalette.h deleted file mode 100644 index 7d6802f..0000000 --- a/ffmpeg1/libavformat/qtpalette.h +++ /dev/null @@ -1,313 +0,0 @@ -/* - * Default Palettes for Quicktime Files - * Automatically generated from a utility derived from XAnim: - * http://xanim.va.pubnix.com/home.html - * - * 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 AVFORMAT_QTPALETTE_H -#define AVFORMAT_QTPALETTE_H - -#include - -static const uint8_t ff_qt_default_palette_4[4 * 3] = { - 0x93, 0x65, 0x5E, - 0xFF, 0xFF, 0xFF, - 0xDF, 0xD0, 0xAB, - 0x00, 0x00, 0x00 -}; - -static const uint8_t ff_qt_default_palette_16[16 * 3] = { - 0xFF, 0xFB, 0xFF, - 0xEF, 0xD9, 0xBB, - 0xE8, 0xC9, 0xB1, - 0x93, 0x65, 0x5E, - 0xFC, 0xDE, 0xE8, - 0x9D, 0x88, 0x91, - 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, - 0xFF, 0xFF, 0xFF, - 0x47, 0x48, 0x37, - 0x7A, 0x5E, 0x55, - 0xDF, 0xD0, 0xAB, - 0xFF, 0xFB, 0xF9, - 0xE8, 0xCA, 0xC5, - 0x8A, 0x7C, 0x77, - 0x00, 0x00, 0x00 -}; - -static const uint8_t ff_qt_default_palette_256[256 * 3] = { - /* 0, 0x00 */ 0xFF, 0xFF, 0xFF, - /* 1, 0x01 */ 0xFF, 0xFF, 0xCC, - /* 2, 0x02 */ 0xFF, 0xFF, 0x99, - /* 3, 0x03 */ 0xFF, 0xFF, 0x66, - /* 4, 0x04 */ 0xFF, 0xFF, 0x33, - /* 5, 0x05 */ 0xFF, 0xFF, 0x00, - /* 6, 0x06 */ 0xFF, 0xCC, 0xFF, - /* 7, 0x07 */ 0xFF, 0xCC, 0xCC, - /* 8, 0x08 */ 0xFF, 0xCC, 0x99, - /* 9, 0x09 */ 0xFF, 0xCC, 0x66, - /* 10, 0x0A */ 0xFF, 0xCC, 0x33, - /* 11, 0x0B */ 0xFF, 0xCC, 0x00, - /* 12, 0x0C */ 0xFF, 0x99, 0xFF, - /* 13, 0x0D */ 0xFF, 0x99, 0xCC, - /* 14, 0x0E */ 0xFF, 0x99, 0x99, - /* 15, 0x0F */ 0xFF, 0x99, 0x66, - /* 16, 0x10 */ 0xFF, 0x99, 0x33, - /* 17, 0x11 */ 0xFF, 0x99, 0x00, - /* 18, 0x12 */ 0xFF, 0x66, 0xFF, - /* 19, 0x13 */ 0xFF, 0x66, 0xCC, - /* 20, 0x14 */ 0xFF, 0x66, 0x99, - /* 21, 0x15 */ 0xFF, 0x66, 0x66, - /* 22, 0x16 */ 0xFF, 0x66, 0x33, - /* 23, 0x17 */ 0xFF, 0x66, 0x00, - /* 24, 0x18 */ 0xFF, 0x33, 0xFF, - /* 25, 0x19 */ 0xFF, 0x33, 0xCC, - /* 26, 0x1A */ 0xFF, 0x33, 0x99, - /* 27, 0x1B */ 0xFF, 0x33, 0x66, - /* 28, 0x1C */ 0xFF, 0x33, 0x33, - /* 29, 0x1D */ 0xFF, 0x33, 0x00, - /* 30, 0x1E */ 0xFF, 0x00, 0xFF, - /* 31, 0x1F */ 0xFF, 0x00, 0xCC, - /* 32, 0x20 */ 0xFF, 0x00, 0x99, - /* 33, 0x21 */ 0xFF, 0x00, 0x66, - /* 34, 0x22 */ 0xFF, 0x00, 0x33, - /* 35, 0x23 */ 0xFF, 0x00, 0x00, - /* 36, 0x24 */ 0xCC, 0xFF, 0xFF, - /* 37, 0x25 */ 0xCC, 0xFF, 0xCC, - /* 38, 0x26 */ 0xCC, 0xFF, 0x99, - /* 39, 0x27 */ 0xCC, 0xFF, 0x66, - /* 40, 0x28 */ 0xCC, 0xFF, 0x33, - /* 41, 0x29 */ 0xCC, 0xFF, 0x00, - /* 42, 0x2A */ 0xCC, 0xCC, 0xFF, - /* 43, 0x2B */ 0xCC, 0xCC, 0xCC, - /* 44, 0x2C */ 0xCC, 0xCC, 0x99, - /* 45, 0x2D */ 0xCC, 0xCC, 0x66, - /* 46, 0x2E */ 0xCC, 0xCC, 0x33, - /* 47, 0x2F */ 0xCC, 0xCC, 0x00, - /* 48, 0x30 */ 0xCC, 0x99, 0xFF, - /* 49, 0x31 */ 0xCC, 0x99, 0xCC, - /* 50, 0x32 */ 0xCC, 0x99, 0x99, - /* 51, 0x33 */ 0xCC, 0x99, 0x66, - /* 52, 0x34 */ 0xCC, 0x99, 0x33, - /* 53, 0x35 */ 0xCC, 0x99, 0x00, - /* 54, 0x36 */ 0xCC, 0x66, 0xFF, - /* 55, 0x37 */ 0xCC, 0x66, 0xCC, - /* 56, 0x38 */ 0xCC, 0x66, 0x99, - /* 57, 0x39 */ 0xCC, 0x66, 0x66, - /* 58, 0x3A */ 0xCC, 0x66, 0x33, - /* 59, 0x3B */ 0xCC, 0x66, 0x00, - /* 60, 0x3C */ 0xCC, 0x33, 0xFF, - /* 61, 0x3D */ 0xCC, 0x33, 0xCC, - /* 62, 0x3E */ 0xCC, 0x33, 0x99, - /* 63, 0x3F */ 0xCC, 0x33, 0x66, - /* 64, 0x40 */ 0xCC, 0x33, 0x33, - /* 65, 0x41 */ 0xCC, 0x33, 0x00, - /* 66, 0x42 */ 0xCC, 0x00, 0xFF, - /* 67, 0x43 */ 0xCC, 0x00, 0xCC, - /* 68, 0x44 */ 0xCC, 0x00, 0x99, - /* 69, 0x45 */ 0xCC, 0x00, 0x66, - /* 70, 0x46 */ 0xCC, 0x00, 0x33, - /* 71, 0x47 */ 0xCC, 0x00, 0x00, - /* 72, 0x48 */ 0x99, 0xFF, 0xFF, - /* 73, 0x49 */ 0x99, 0xFF, 0xCC, - /* 74, 0x4A */ 0x99, 0xFF, 0x99, - /* 75, 0x4B */ 0x99, 0xFF, 0x66, - /* 76, 0x4C */ 0x99, 0xFF, 0x33, - /* 77, 0x4D */ 0x99, 0xFF, 0x00, - /* 78, 0x4E */ 0x99, 0xCC, 0xFF, - /* 79, 0x4F */ 0x99, 0xCC, 0xCC, - /* 80, 0x50 */ 0x99, 0xCC, 0x99, - /* 81, 0x51 */ 0x99, 0xCC, 0x66, - /* 82, 0x52 */ 0x99, 0xCC, 0x33, - /* 83, 0x53 */ 0x99, 0xCC, 0x00, - /* 84, 0x54 */ 0x99, 0x99, 0xFF, - /* 85, 0x55 */ 0x99, 0x99, 0xCC, - /* 86, 0x56 */ 0x99, 0x99, 0x99, - /* 87, 0x57 */ 0x99, 0x99, 0x66, - /* 88, 0x58 */ 0x99, 0x99, 0x33, - /* 89, 0x59 */ 0x99, 0x99, 0x00, - /* 90, 0x5A */ 0x99, 0x66, 0xFF, - /* 91, 0x5B */ 0x99, 0x66, 0xCC, - /* 92, 0x5C */ 0x99, 0x66, 0x99, - /* 93, 0x5D */ 0x99, 0x66, 0x66, - /* 94, 0x5E */ 0x99, 0x66, 0x33, - /* 95, 0x5F */ 0x99, 0x66, 0x00, - /* 96, 0x60 */ 0x99, 0x33, 0xFF, - /* 97, 0x61 */ 0x99, 0x33, 0xCC, - /* 98, 0x62 */ 0x99, 0x33, 0x99, - /* 99, 0x63 */ 0x99, 0x33, 0x66, - /* 100, 0x64 */ 0x99, 0x33, 0x33, - /* 101, 0x65 */ 0x99, 0x33, 0x00, - /* 102, 0x66 */ 0x99, 0x00, 0xFF, - /* 103, 0x67 */ 0x99, 0x00, 0xCC, - /* 104, 0x68 */ 0x99, 0x00, 0x99, - /* 105, 0x69 */ 0x99, 0x00, 0x66, - /* 106, 0x6A */ 0x99, 0x00, 0x33, - /* 107, 0x6B */ 0x99, 0x00, 0x00, - /* 108, 0x6C */ 0x66, 0xFF, 0xFF, - /* 109, 0x6D */ 0x66, 0xFF, 0xCC, - /* 110, 0x6E */ 0x66, 0xFF, 0x99, - /* 111, 0x6F */ 0x66, 0xFF, 0x66, - /* 112, 0x70 */ 0x66, 0xFF, 0x33, - /* 113, 0x71 */ 0x66, 0xFF, 0x00, - /* 114, 0x72 */ 0x66, 0xCC, 0xFF, - /* 115, 0x73 */ 0x66, 0xCC, 0xCC, - /* 116, 0x74 */ 0x66, 0xCC, 0x99, - /* 117, 0x75 */ 0x66, 0xCC, 0x66, - /* 118, 0x76 */ 0x66, 0xCC, 0x33, - /* 119, 0x77 */ 0x66, 0xCC, 0x00, - /* 120, 0x78 */ 0x66, 0x99, 0xFF, - /* 121, 0x79 */ 0x66, 0x99, 0xCC, - /* 122, 0x7A */ 0x66, 0x99, 0x99, - /* 123, 0x7B */ 0x66, 0x99, 0x66, - /* 124, 0x7C */ 0x66, 0x99, 0x33, - /* 125, 0x7D */ 0x66, 0x99, 0x00, - /* 126, 0x7E */ 0x66, 0x66, 0xFF, - /* 127, 0x7F */ 0x66, 0x66, 0xCC, - /* 128, 0x80 */ 0x66, 0x66, 0x99, - /* 129, 0x81 */ 0x66, 0x66, 0x66, - /* 130, 0x82 */ 0x66, 0x66, 0x33, - /* 131, 0x83 */ 0x66, 0x66, 0x00, - /* 132, 0x84 */ 0x66, 0x33, 0xFF, - /* 133, 0x85 */ 0x66, 0x33, 0xCC, - /* 134, 0x86 */ 0x66, 0x33, 0x99, - /* 135, 0x87 */ 0x66, 0x33, 0x66, - /* 136, 0x88 */ 0x66, 0x33, 0x33, - /* 137, 0x89 */ 0x66, 0x33, 0x00, - /* 138, 0x8A */ 0x66, 0x00, 0xFF, - /* 139, 0x8B */ 0x66, 0x00, 0xCC, - /* 140, 0x8C */ 0x66, 0x00, 0x99, - /* 141, 0x8D */ 0x66, 0x00, 0x66, - /* 142, 0x8E */ 0x66, 0x00, 0x33, - /* 143, 0x8F */ 0x66, 0x00, 0x00, - /* 144, 0x90 */ 0x33, 0xFF, 0xFF, - /* 145, 0x91 */ 0x33, 0xFF, 0xCC, - /* 146, 0x92 */ 0x33, 0xFF, 0x99, - /* 147, 0x93 */ 0x33, 0xFF, 0x66, - /* 148, 0x94 */ 0x33, 0xFF, 0x33, - /* 149, 0x95 */ 0x33, 0xFF, 0x00, - /* 150, 0x96 */ 0x33, 0xCC, 0xFF, - /* 151, 0x97 */ 0x33, 0xCC, 0xCC, - /* 152, 0x98 */ 0x33, 0xCC, 0x99, - /* 153, 0x99 */ 0x33, 0xCC, 0x66, - /* 154, 0x9A */ 0x33, 0xCC, 0x33, - /* 155, 0x9B */ 0x33, 0xCC, 0x00, - /* 156, 0x9C */ 0x33, 0x99, 0xFF, - /* 157, 0x9D */ 0x33, 0x99, 0xCC, - /* 158, 0x9E */ 0x33, 0x99, 0x99, - /* 159, 0x9F */ 0x33, 0x99, 0x66, - /* 160, 0xA0 */ 0x33, 0x99, 0x33, - /* 161, 0xA1 */ 0x33, 0x99, 0x00, - /* 162, 0xA2 */ 0x33, 0x66, 0xFF, - /* 163, 0xA3 */ 0x33, 0x66, 0xCC, - /* 164, 0xA4 */ 0x33, 0x66, 0x99, - /* 165, 0xA5 */ 0x33, 0x66, 0x66, - /* 166, 0xA6 */ 0x33, 0x66, 0x33, - /* 167, 0xA7 */ 0x33, 0x66, 0x00, - /* 168, 0xA8 */ 0x33, 0x33, 0xFF, - /* 169, 0xA9 */ 0x33, 0x33, 0xCC, - /* 170, 0xAA */ 0x33, 0x33, 0x99, - /* 171, 0xAB */ 0x33, 0x33, 0x66, - /* 172, 0xAC */ 0x33, 0x33, 0x33, - /* 173, 0xAD */ 0x33, 0x33, 0x00, - /* 174, 0xAE */ 0x33, 0x00, 0xFF, - /* 175, 0xAF */ 0x33, 0x00, 0xCC, - /* 176, 0xB0 */ 0x33, 0x00, 0x99, - /* 177, 0xB1 */ 0x33, 0x00, 0x66, - /* 178, 0xB2 */ 0x33, 0x00, 0x33, - /* 179, 0xB3 */ 0x33, 0x00, 0x00, - /* 180, 0xB4 */ 0x00, 0xFF, 0xFF, - /* 181, 0xB5 */ 0x00, 0xFF, 0xCC, - /* 182, 0xB6 */ 0x00, 0xFF, 0x99, - /* 183, 0xB7 */ 0x00, 0xFF, 0x66, - /* 184, 0xB8 */ 0x00, 0xFF, 0x33, - /* 185, 0xB9 */ 0x00, 0xFF, 0x00, - /* 186, 0xBA */ 0x00, 0xCC, 0xFF, - /* 187, 0xBB */ 0x00, 0xCC, 0xCC, - /* 188, 0xBC */ 0x00, 0xCC, 0x99, - /* 189, 0xBD */ 0x00, 0xCC, 0x66, - /* 190, 0xBE */ 0x00, 0xCC, 0x33, - /* 191, 0xBF */ 0x00, 0xCC, 0x00, - /* 192, 0xC0 */ 0x00, 0x99, 0xFF, - /* 193, 0xC1 */ 0x00, 0x99, 0xCC, - /* 194, 0xC2 */ 0x00, 0x99, 0x99, - /* 195, 0xC3 */ 0x00, 0x99, 0x66, - /* 196, 0xC4 */ 0x00, 0x99, 0x33, - /* 197, 0xC5 */ 0x00, 0x99, 0x00, - /* 198, 0xC6 */ 0x00, 0x66, 0xFF, - /* 199, 0xC7 */ 0x00, 0x66, 0xCC, - /* 200, 0xC8 */ 0x00, 0x66, 0x99, - /* 201, 0xC9 */ 0x00, 0x66, 0x66, - /* 202, 0xCA */ 0x00, 0x66, 0x33, - /* 203, 0xCB */ 0x00, 0x66, 0x00, - /* 204, 0xCC */ 0x00, 0x33, 0xFF, - /* 205, 0xCD */ 0x00, 0x33, 0xCC, - /* 206, 0xCE */ 0x00, 0x33, 0x99, - /* 207, 0xCF */ 0x00, 0x33, 0x66, - /* 208, 0xD0 */ 0x00, 0x33, 0x33, - /* 209, 0xD1 */ 0x00, 0x33, 0x00, - /* 210, 0xD2 */ 0x00, 0x00, 0xFF, - /* 211, 0xD3 */ 0x00, 0x00, 0xCC, - /* 212, 0xD4 */ 0x00, 0x00, 0x99, - /* 213, 0xD5 */ 0x00, 0x00, 0x66, - /* 214, 0xD6 */ 0x00, 0x00, 0x33, - /* 215, 0xD7 */ 0xEE, 0x00, 0x00, - /* 216, 0xD8 */ 0xDD, 0x00, 0x00, - /* 217, 0xD9 */ 0xBB, 0x00, 0x00, - /* 218, 0xDA */ 0xAA, 0x00, 0x00, - /* 219, 0xDB */ 0x88, 0x00, 0x00, - /* 220, 0xDC */ 0x77, 0x00, 0x00, - /* 221, 0xDD */ 0x55, 0x00, 0x00, - /* 222, 0xDE */ 0x44, 0x00, 0x00, - /* 223, 0xDF */ 0x22, 0x00, 0x00, - /* 224, 0xE0 */ 0x11, 0x00, 0x00, - /* 225, 0xE1 */ 0x00, 0xEE, 0x00, - /* 226, 0xE2 */ 0x00, 0xDD, 0x00, - /* 227, 0xE3 */ 0x00, 0xBB, 0x00, - /* 228, 0xE4 */ 0x00, 0xAA, 0x00, - /* 229, 0xE5 */ 0x00, 0x88, 0x00, - /* 230, 0xE6 */ 0x00, 0x77, 0x00, - /* 231, 0xE7 */ 0x00, 0x55, 0x00, - /* 232, 0xE8 */ 0x00, 0x44, 0x00, - /* 233, 0xE9 */ 0x00, 0x22, 0x00, - /* 234, 0xEA */ 0x00, 0x11, 0x00, - /* 235, 0xEB */ 0x00, 0x00, 0xEE, - /* 236, 0xEC */ 0x00, 0x00, 0xDD, - /* 237, 0xED */ 0x00, 0x00, 0xBB, - /* 238, 0xEE */ 0x00, 0x00, 0xAA, - /* 239, 0xEF */ 0x00, 0x00, 0x88, - /* 240, 0xF0 */ 0x00, 0x00, 0x77, - /* 241, 0xF1 */ 0x00, 0x00, 0x55, - /* 242, 0xF2 */ 0x00, 0x00, 0x44, - /* 243, 0xF3 */ 0x00, 0x00, 0x22, - /* 244, 0xF4 */ 0x00, 0x00, 0x11, - /* 245, 0xF5 */ 0xEE, 0xEE, 0xEE, - /* 246, 0xF6 */ 0xDD, 0xDD, 0xDD, - /* 247, 0xF7 */ 0xBB, 0xBB, 0xBB, - /* 248, 0xF8 */ 0xAA, 0xAA, 0xAA, - /* 249, 0xF9 */ 0x88, 0x88, 0x88, - /* 250, 0xFA */ 0x77, 0x77, 0x77, - /* 251, 0xFB */ 0x55, 0x55, 0x55, - /* 252, 0xFC */ 0x44, 0x44, 0x44, - /* 253, 0xFD */ 0x22, 0x22, 0x22, - /* 254, 0xFE */ 0x11, 0x11, 0x11, - /* 255, 0xFF */ 0x00, 0x00, 0x00 -}; - -#endif /* AVFORMAT_QTPALETTE_H */ diff --git a/ffmpeg1/libavformat/r3d.c b/ffmpeg1/libavformat/r3d.c deleted file mode 100644 index 3b3ecce..0000000 --- a/ffmpeg1/libavformat/r3d.c +++ /dev/null @@ -1,410 +0,0 @@ -/* - * R3D REDCODE demuxer - * Copyright (c) 2008 Baptiste Coudurier - * - * 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 - */ - -//#define DEBUG - -#include "libavutil/intreadwrite.h" -#include "libavutil/dict.h" -#include "libavutil/mathematics.h" -#include "avformat.h" -#include "internal.h" - -typedef struct { - unsigned video_offsets_count; - unsigned *video_offsets; - unsigned rdvo_offset; -} R3DContext; - -typedef struct { - unsigned size; - uint32_t tag; - uint64_t offset; -} Atom; - -static int read_atom(AVFormatContext *s, Atom *atom) -{ - atom->offset = avio_tell(s->pb); - atom->size = avio_rb32(s->pb); - if (atom->size < 8) - return -1; - atom->tag = avio_rl32(s->pb); - av_dlog(s, "atom %u %.4s offset %#"PRIx64"\n", - atom->size, (char*)&atom->tag, atom->offset); - return atom->size; -} - -static int r3d_read_red1(AVFormatContext *s) -{ - AVStream *st = avformat_new_stream(s, NULL); - char filename[258]; - int tmp; - int av_unused tmp2; - AVRational framerate; - - if (!st) - return AVERROR(ENOMEM); - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = AV_CODEC_ID_JPEG2000; - - tmp = avio_r8(s->pb); // major version - tmp2 = avio_r8(s->pb); // minor version - av_dlog(s, "version %d.%d\n", tmp, tmp2); - - tmp = avio_rb16(s->pb); // unknown - av_dlog(s, "unknown1 %d\n", tmp); - - tmp = avio_rb32(s->pb); - avpriv_set_pts_info(st, 32, 1, tmp); - - tmp = avio_rb32(s->pb); // filenum - av_dlog(s, "filenum %d\n", tmp); - - avio_skip(s->pb, 32); // unknown - - st->codec->width = avio_rb32(s->pb); - st->codec->height = avio_rb32(s->pb); - - tmp = avio_rb16(s->pb); // unknown - av_dlog(s, "unknown2 %d\n", tmp); - - framerate.num = avio_rb16(s->pb); - framerate.den = avio_rb16(s->pb); - if (framerate.num && framerate.den) { -#if FF_API_R_FRAME_RATE - st->r_frame_rate = -#endif - st->avg_frame_rate = framerate; - } - - tmp = avio_r8(s->pb); // audio channels - av_dlog(s, "audio channels %d\n", tmp); - if (tmp > 0) { - AVStream *ast = avformat_new_stream(s, NULL); - if (!ast) - return AVERROR(ENOMEM); - ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; - ast->codec->codec_id = AV_CODEC_ID_PCM_S32BE; - ast->codec->channels = tmp; - avpriv_set_pts_info(ast, 32, 1, st->time_base.den); - } - - avio_read(s->pb, filename, 257); - filename[sizeof(filename)-1] = 0; - av_dict_set(&st->metadata, "filename", filename, 0); - - av_dlog(s, "filename %s\n", filename); - av_dlog(s, "resolution %dx%d\n", st->codec->width, st->codec->height); - av_dlog(s, "timescale %d\n", st->time_base.den); - av_dlog(s, "frame rate %d/%d\n", - framerate.num, framerate.den); - - return 0; -} - -static int r3d_read_rdvo(AVFormatContext *s, Atom *atom) -{ - R3DContext *r3d = s->priv_data; - AVStream *st = s->streams[0]; - int i; - - r3d->video_offsets_count = (atom->size - 8) / 4; - r3d->video_offsets = av_malloc(atom->size); - if (!r3d->video_offsets) - return AVERROR(ENOMEM); - - for (i = 0; i < r3d->video_offsets_count; i++) { - r3d->video_offsets[i] = avio_rb32(s->pb); - if (!r3d->video_offsets[i]) { - r3d->video_offsets_count = i; - break; - } - av_dlog(s, "video offset %d: %#x\n", i, r3d->video_offsets[i]); - } - - if (st->avg_frame_rate.num) - st->duration = av_rescale_q(r3d->video_offsets_count, - av_inv_q(st->avg_frame_rate), - st->time_base); - av_dlog(s, "duration %"PRId64"\n", st->duration); - - return 0; -} - -static void r3d_read_reos(AVFormatContext *s) -{ - R3DContext *r3d = s->priv_data; - int av_unused tmp; - - r3d->rdvo_offset = avio_rb32(s->pb); - avio_rb32(s->pb); // rdvs offset - avio_rb32(s->pb); // rdao offset - avio_rb32(s->pb); // rdas offset - - tmp = avio_rb32(s->pb); - av_dlog(s, "num video chunks %d\n", tmp); - - tmp = avio_rb32(s->pb); - av_dlog(s, "num audio chunks %d\n", tmp); - - avio_skip(s->pb, 6*4); -} - -static int r3d_read_header(AVFormatContext *s) -{ - R3DContext *r3d = s->priv_data; - Atom atom; - int ret; - - if (read_atom(s, &atom) < 0) { - av_log(s, AV_LOG_ERROR, "error reading atom\n"); - return -1; - } - if (atom.tag == MKTAG('R','E','D','1')) { - if ((ret = r3d_read_red1(s)) < 0) { - av_log(s, AV_LOG_ERROR, "error parsing 'red1' atom\n"); - return ret; - } - } else { - av_log(s, AV_LOG_ERROR, "could not find 'red1' atom\n"); - return -1; - } - - s->data_offset = avio_tell(s->pb); - av_dlog(s, "data offset %#"PRIx64"\n", s->data_offset); - if (!s->pb->seekable) - return 0; - // find REOB/REOF/REOS to load index - avio_seek(s->pb, avio_size(s->pb)-48-8, SEEK_SET); - if (read_atom(s, &atom) < 0) - av_log(s, AV_LOG_ERROR, "error reading end atom\n"); - - if (atom.tag != MKTAG('R','E','O','B') && - atom.tag != MKTAG('R','E','O','F') && - atom.tag != MKTAG('R','E','O','S')) - goto out; - - r3d_read_reos(s); - - if (r3d->rdvo_offset) { - avio_seek(s->pb, r3d->rdvo_offset, SEEK_SET); - if (read_atom(s, &atom) < 0) - av_log(s, AV_LOG_ERROR, "error reading 'rdvo' atom\n"); - if (atom.tag == MKTAG('R','D','V','O')) { - if (r3d_read_rdvo(s, &atom) < 0) - av_log(s, AV_LOG_ERROR, "error parsing 'rdvo' atom\n"); - } - } - - out: - avio_seek(s->pb, s->data_offset, SEEK_SET); - return 0; -} - -static int r3d_read_redv(AVFormatContext *s, AVPacket *pkt, Atom *atom) -{ - AVStream *st = s->streams[0]; - int tmp; - int av_unused tmp2; - uint64_t pos = avio_tell(s->pb); - unsigned dts; - int ret; - - dts = avio_rb32(s->pb); - - tmp = avio_rb32(s->pb); - av_dlog(s, "frame num %d\n", tmp); - - tmp = avio_r8(s->pb); // major version - tmp2 = avio_r8(s->pb); // minor version - av_dlog(s, "version %d.%d\n", tmp, tmp2); - - tmp = avio_rb16(s->pb); // unknown - av_dlog(s, "unknown %d\n", tmp); - - if (tmp > 4) { - tmp = avio_rb16(s->pb); // unknown - av_dlog(s, "unknown %d\n", tmp); - - tmp = avio_rb16(s->pb); // unknown - av_dlog(s, "unknown %d\n", tmp); - - tmp = avio_rb32(s->pb); - av_dlog(s, "width %d\n", tmp); - tmp = avio_rb32(s->pb); - av_dlog(s, "height %d\n", tmp); - - tmp = avio_rb32(s->pb); - av_dlog(s, "metadata len %d\n", tmp); - } - tmp = atom->size - 8 - (avio_tell(s->pb) - pos); - if (tmp < 0) - return -1; - ret = av_get_packet(s->pb, pkt, tmp); - if (ret < 0) { - av_log(s, AV_LOG_ERROR, "error reading video packet\n"); - return -1; - } - - pkt->stream_index = 0; - pkt->dts = dts; - if (st->avg_frame_rate.num) - pkt->duration = (uint64_t)st->time_base.den* - st->avg_frame_rate.den/st->avg_frame_rate.num; - av_dlog(s, "pkt dts %"PRId64" duration %d\n", pkt->dts, pkt->duration); - - return 0; -} - -static int r3d_read_reda(AVFormatContext *s, AVPacket *pkt, Atom *atom) -{ - AVStream *st = s->streams[1]; - int av_unused tmp, tmp2; - int samples, size; - uint64_t pos = avio_tell(s->pb); - unsigned dts; - int ret; - - dts = avio_rb32(s->pb); - - st->codec->sample_rate = avio_rb32(s->pb); - if (st->codec->sample_rate < 0) { - av_log(s, AV_LOG_ERROR, "negative sample rate\n"); - return AVERROR_INVALIDDATA; - } - - samples = avio_rb32(s->pb); - - tmp = avio_rb32(s->pb); - av_dlog(s, "packet num %d\n", tmp); - - tmp = avio_rb16(s->pb); // unknown - av_dlog(s, "unknown %d\n", tmp); - - tmp = avio_r8(s->pb); // major version - tmp2 = avio_r8(s->pb); // minor version - av_dlog(s, "version %d.%d\n", tmp, tmp2); - - tmp = avio_rb32(s->pb); // unknown - av_dlog(s, "unknown %d\n", tmp); - - size = atom->size - 8 - (avio_tell(s->pb) - pos); - if (size < 0) - return -1; - ret = av_get_packet(s->pb, pkt, size); - if (ret < 0) { - av_log(s, AV_LOG_ERROR, "error reading audio packet\n"); - return ret; - } - - pkt->stream_index = 1; - pkt->dts = dts; - if (st->codec->sample_rate) - pkt->duration = av_rescale(samples, st->time_base.den, st->codec->sample_rate); - av_dlog(s, "pkt dts %"PRId64" duration %d samples %d sample rate %d\n", - pkt->dts, pkt->duration, samples, st->codec->sample_rate); - - return 0; -} - -static int r3d_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - Atom atom; - int err = 0; - - while (!err) { - if (read_atom(s, &atom) < 0) { - err = -1; - break; - } - switch (atom.tag) { - case MKTAG('R','E','D','V'): - if (s->streams[0]->discard == AVDISCARD_ALL) - goto skip; - if (!(err = r3d_read_redv(s, pkt, &atom))) - return 0; - break; - case MKTAG('R','E','D','A'): - if (s->nb_streams < 2) - return -1; - if (s->streams[1]->discard == AVDISCARD_ALL) - goto skip; - if (!(err = r3d_read_reda(s, pkt, &atom))) - return 0; - break; - default: - skip: - avio_skip(s->pb, atom.size-8); - } - } - return err; -} - -static int r3d_probe(AVProbeData *p) -{ - if (AV_RL32(p->buf + 4) == MKTAG('R','E','D','1')) - return AVPROBE_SCORE_MAX; - return 0; -} - -static int r3d_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags) -{ - AVStream *st = s->streams[0]; // video stream - R3DContext *r3d = s->priv_data; - int frame_num; - - if (!st->avg_frame_rate.num) - return -1; - - frame_num = av_rescale_q(sample_time, st->time_base, - av_inv_q(st->avg_frame_rate)); - av_dlog(s, "seek frame num %d timestamp %"PRId64"\n", - frame_num, sample_time); - - if (frame_num < r3d->video_offsets_count) { - if (avio_seek(s->pb, r3d->video_offsets_count, SEEK_SET) < 0) - return -1; - } else { - av_log(s, AV_LOG_ERROR, "could not seek to frame %d\n", frame_num); - return -1; - } - - return 0; -} - -static int r3d_close(AVFormatContext *s) -{ - R3DContext *r3d = s->priv_data; - - av_freep(&r3d->video_offsets); - - return 0; -} - -AVInputFormat ff_r3d_demuxer = { - .name = "r3d", - .long_name = NULL_IF_CONFIG_SMALL("REDCODE R3D"), - .priv_data_size = sizeof(R3DContext), - .read_probe = r3d_probe, - .read_header = r3d_read_header, - .read_packet = r3d_read_packet, - .read_close = r3d_close, - .read_seek = r3d_seek, -}; diff --git a/ffmpeg1/libavformat/rawdec.c b/ffmpeg1/libavformat/rawdec.c deleted file mode 100644 index 07c2782..0000000 --- a/ffmpeg1/libavformat/rawdec.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - * RAW demuxers - * Copyright (c) 2001 Fabrice Bellard - * Copyright (c) 2005 Alex Beregszaszi - * - * 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 "internal.h" -#include "avio_internal.h" -#include "rawdec.h" -#include "libavutil/opt.h" -#include "libavutil/parseutils.h" -#include "libavutil/pixdesc.h" -#include "libavutil/avassert.h" - -#define RAW_PACKET_SIZE 1024 - -int ff_raw_read_partial_packet(AVFormatContext *s, AVPacket *pkt) -{ - int ret, size; - - size = RAW_PACKET_SIZE; - - if (av_new_packet(pkt, size) < 0) - return AVERROR(ENOMEM); - - pkt->pos= avio_tell(s->pb); - pkt->stream_index = 0; - ret = ffio_read_partial(s->pb, pkt->data, size); - if (ret < 0) { - av_free_packet(pkt); - return ret; - } - av_shrink_packet(pkt, ret); - return ret; -} - -int ff_raw_audio_read_header(AVFormatContext *s) -{ - AVStream *st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - st->codec->codec_id = s->iformat->raw_codec_id; - st->need_parsing = AVSTREAM_PARSE_FULL_RAW; - st->start_time = 0; - /* the parameters will be extracted from the compressed bitstream */ - - return 0; -} - -/* MPEG-1/H.263 input */ -int ff_raw_video_read_header(AVFormatContext *s) -{ - AVStream *st; - FFRawVideoDemuxerContext *s1 = s->priv_data; - AVRational framerate; - int ret = 0; - - - st = avformat_new_stream(s, NULL); - if (!st) { - ret = AVERROR(ENOMEM); - goto fail; - } - - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - st->codec->codec_id = s->iformat->raw_codec_id; - st->need_parsing = AVSTREAM_PARSE_FULL_RAW; - - if ((ret = av_parse_video_rate(&framerate, s1->framerate)) < 0) { - av_log(s, AV_LOG_ERROR, "Could not parse framerate: %s.\n", s1->framerate); - goto fail; - } - - st->codec->time_base = av_inv_q(framerate); - avpriv_set_pts_info(st, 64, 1, 1200000); - -fail: - return ret; -} - -/* Note: Do not forget to add new entries to the Makefile as well. */ - -#define OFFSET(x) offsetof(FFRawVideoDemuxerContext, x) -#define DEC AV_OPT_FLAG_DECODING_PARAM -const AVOption ff_rawvideo_options[] = { - { "framerate", "", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = "25"}, 0, 0, DEC}, - { NULL }, -}; - -#if CONFIG_LATM_DEMUXER -AVInputFormat ff_latm_demuxer = { - .name = "latm", - .long_name = NULL_IF_CONFIG_SMALL("raw LOAS/LATM"), - .read_header = ff_raw_audio_read_header, - .read_packet = ff_raw_read_partial_packet, - .flags = AVFMT_GENERIC_INDEX, - .extensions = "latm", - .raw_codec_id = AV_CODEC_ID_AAC_LATM, -}; -#endif - -#if CONFIG_MJPEG_DEMUXER -FF_DEF_RAWVIDEO_DEMUXER(mjpeg, "raw MJPEG video", NULL, "mjpg,mjpeg,mpo", AV_CODEC_ID_MJPEG) -#endif - -#if CONFIG_MLP_DEMUXER -AVInputFormat ff_mlp_demuxer = { - .name = "mlp", - .long_name = NULL_IF_CONFIG_SMALL("raw MLP"), - .read_header = ff_raw_audio_read_header, - .read_packet = ff_raw_read_partial_packet, - .flags = AVFMT_GENERIC_INDEX, - .extensions = "mlp", - .raw_codec_id = AV_CODEC_ID_MLP, -}; -#endif - -#if CONFIG_TRUEHD_DEMUXER -AVInputFormat ff_truehd_demuxer = { - .name = "truehd", - .long_name = NULL_IF_CONFIG_SMALL("raw TrueHD"), - .read_header = ff_raw_audio_read_header, - .read_packet = ff_raw_read_partial_packet, - .flags = AVFMT_GENERIC_INDEX, - .extensions = "thd", - .raw_codec_id = AV_CODEC_ID_TRUEHD, -}; -#endif - -#if CONFIG_SHORTEN_DEMUXER -AVInputFormat ff_shorten_demuxer = { - .name = "shn", - .long_name = NULL_IF_CONFIG_SMALL("raw Shorten"), - .read_header = ff_raw_audio_read_header, - .read_packet = ff_raw_read_partial_packet, - .flags = AVFMT_NOBINSEARCH | AVFMT_NOGENSEARCH | AVFMT_NO_BYTE_SEEK, - .extensions = "shn", - .raw_codec_id = AV_CODEC_ID_SHORTEN, -}; -#endif - -#if CONFIG_VC1_DEMUXER -FF_DEF_RAWVIDEO_DEMUXER(vc1, "raw VC-1", NULL, "vc1", AV_CODEC_ID_VC1) -#endif diff --git a/ffmpeg1/libavformat/rawdec.h b/ffmpeg1/libavformat/rawdec.h deleted file mode 100644 index d978295..0000000 --- a/ffmpeg1/libavformat/rawdec.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * RAW demuxers - * Copyright (C) 2007 Aurelien Jacobs - * - * 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 AVFORMAT_RAWDEC_H -#define AVFORMAT_RAWDEC_H - -#include "avformat.h" -#include "libavutil/log.h" -#include "libavutil/opt.h" - -typedef struct FFRawVideoDemuxerContext { - const AVClass *class; /**< Class for private options. */ - char *video_size; /**< String describing video size, set by a private option. */ - char *pixel_format; /**< Set by a private option. */ - char *framerate; /**< String describing framerate, set by a private option. */ -} FFRawVideoDemuxerContext; - -extern const AVOption ff_rawvideo_options[]; - -int ff_raw_read_partial_packet(AVFormatContext *s, AVPacket *pkt); - -int ff_raw_audio_read_header(AVFormatContext *s); - -int ff_raw_video_read_header(AVFormatContext *s); - -#define FF_RAWVIDEO_DEMUXER_CLASS(name)\ -static const AVClass name ## _demuxer_class = {\ - .class_name = #name " demuxer",\ - .item_name = av_default_item_name,\ - .option = ff_rawvideo_options,\ - .version = LIBAVUTIL_VERSION_INT,\ -}; - -#define FF_DEF_RAWVIDEO_DEMUXER(shortname, longname, probe, ext, id)\ -FF_RAWVIDEO_DEMUXER_CLASS(shortname)\ -AVInputFormat ff_ ## shortname ## _demuxer = {\ - .name = #shortname,\ - .long_name = NULL_IF_CONFIG_SMALL(longname),\ - .read_probe = probe,\ - .read_header = ff_raw_video_read_header,\ - .read_packet = ff_raw_read_partial_packet,\ - .extensions = ext,\ - .flags = AVFMT_GENERIC_INDEX,\ - .raw_codec_id = id,\ - .priv_data_size = sizeof(FFRawVideoDemuxerContext),\ - .priv_class = &shortname ## _demuxer_class,\ -}; - -#endif /* AVFORMAT_RAWDEC_H */ diff --git a/ffmpeg1/libavformat/rawenc.c b/ffmpeg1/libavformat/rawenc.c deleted file mode 100644 index b804c24..0000000 --- a/ffmpeg1/libavformat/rawenc.c +++ /dev/null @@ -1,282 +0,0 @@ -/* - * RAW muxers - * Copyright (c) 2001 Fabrice Bellard - * Copyright (c) 2005 Alex Beregszaszi - * - * 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 "rawenc.h" - -int ff_raw_write_packet(AVFormatContext *s, AVPacket *pkt) -{ - avio_write(s->pb, pkt->data, pkt->size); - avio_flush(s->pb); - return 0; -} - -/* Note: Do not forget to add new entries to the Makefile as well. */ - -#if CONFIG_AC3_MUXER -AVOutputFormat ff_ac3_muxer = { - .name = "ac3", - .long_name = NULL_IF_CONFIG_SMALL("raw AC-3"), - .mime_type = "audio/x-ac3", - .extensions = "ac3", - .audio_codec = AV_CODEC_ID_AC3, - .video_codec = AV_CODEC_ID_NONE, - .write_packet = ff_raw_write_packet, - .flags = AVFMT_NOTIMESTAMPS, -}; -#endif - -#if CONFIG_ADX_MUXER -AVOutputFormat ff_adx_muxer = { - .name = "adx", - .long_name = NULL_IF_CONFIG_SMALL("CRI ADX"), - .extensions = "adx", - .audio_codec = AV_CODEC_ID_ADPCM_ADX, - .video_codec = AV_CODEC_ID_NONE, - .write_packet = ff_raw_write_packet, - .flags = AVFMT_NOTIMESTAMPS, -}; -#endif - -#if CONFIG_CAVSVIDEO_MUXER -AVOutputFormat ff_cavsvideo_muxer = { - .name = "cavsvideo", - .long_name = NULL_IF_CONFIG_SMALL("raw Chinese AVS (Audio Video Standard) video"), - .extensions = "cavs", - .audio_codec = AV_CODEC_ID_NONE, - .video_codec = AV_CODEC_ID_CAVS, - .write_packet = ff_raw_write_packet, - .flags = AVFMT_NOTIMESTAMPS, -}; -#endif - -#if CONFIG_DIRAC_MUXER -AVOutputFormat ff_dirac_muxer = { - .name = "dirac", - .long_name = NULL_IF_CONFIG_SMALL("raw Dirac"), - .extensions = "drc", - .audio_codec = AV_CODEC_ID_NONE, - .video_codec = AV_CODEC_ID_DIRAC, - .write_packet = ff_raw_write_packet, - .flags = AVFMT_NOTIMESTAMPS, -}; -#endif - -#if CONFIG_DNXHD_MUXER -AVOutputFormat ff_dnxhd_muxer = { - .name = "dnxhd", - .long_name = NULL_IF_CONFIG_SMALL("raw DNxHD (SMPTE VC-3)"), - .extensions = "dnxhd", - .audio_codec = AV_CODEC_ID_NONE, - .video_codec = AV_CODEC_ID_DNXHD, - .write_packet = ff_raw_write_packet, - .flags = AVFMT_NOTIMESTAMPS, -}; -#endif - -#if CONFIG_DTS_MUXER -AVOutputFormat ff_dts_muxer = { - .name = "dts", - .long_name = NULL_IF_CONFIG_SMALL("raw DTS"), - .mime_type = "audio/x-dca", - .extensions = "dts", - .audio_codec = AV_CODEC_ID_DTS, - .video_codec = AV_CODEC_ID_NONE, - .write_packet = ff_raw_write_packet, - .flags = AVFMT_NOTIMESTAMPS, -}; -#endif - -#if CONFIG_EAC3_MUXER -AVOutputFormat ff_eac3_muxer = { - .name = "eac3", - .long_name = NULL_IF_CONFIG_SMALL("raw E-AC-3"), - .mime_type = "audio/x-eac3", - .extensions = "eac3", - .audio_codec = AV_CODEC_ID_EAC3, - .video_codec = AV_CODEC_ID_NONE, - .write_packet = ff_raw_write_packet, - .flags = AVFMT_NOTIMESTAMPS, -}; -#endif - -#if CONFIG_G722_MUXER -AVOutputFormat ff_g722_muxer = { - .name = "g722", - .long_name = NULL_IF_CONFIG_SMALL("raw G.722"), - .mime_type = "audio/G722", - .extensions = "g722", - .audio_codec = AV_CODEC_ID_ADPCM_G722, - .video_codec = AV_CODEC_ID_NONE, - .write_packet = ff_raw_write_packet, - .flags = AVFMT_NOTIMESTAMPS, -}; -#endif - -#if CONFIG_G723_1_MUXER -AVOutputFormat ff_g723_1_muxer = { - .name = "g723_1", - .long_name = NULL_IF_CONFIG_SMALL("raw G.723.1"), - .mime_type = "audio/g723", - .extensions = "tco,rco", - .audio_codec = AV_CODEC_ID_G723_1, - .video_codec = AV_CODEC_ID_NONE, - .write_packet = ff_raw_write_packet, - .flags = AVFMT_NOTIMESTAMPS, -}; -#endif - -#if CONFIG_H261_MUXER -AVOutputFormat ff_h261_muxer = { - .name = "h261", - .long_name = NULL_IF_CONFIG_SMALL("raw H.261"), - .mime_type = "video/x-h261", - .extensions = "h261", - .audio_codec = AV_CODEC_ID_NONE, - .video_codec = AV_CODEC_ID_H261, - .write_packet = ff_raw_write_packet, - .flags = AVFMT_NOTIMESTAMPS, -}; -#endif - -#if CONFIG_H263_MUXER -AVOutputFormat ff_h263_muxer = { - .name = "h263", - .long_name = NULL_IF_CONFIG_SMALL("raw H.263"), - .mime_type = "video/x-h263", - .extensions = "h263", - .audio_codec = AV_CODEC_ID_NONE, - .video_codec = AV_CODEC_ID_H263, - .write_packet = ff_raw_write_packet, - .flags = AVFMT_NOTIMESTAMPS, -}; -#endif - -#if CONFIG_H264_MUXER -AVOutputFormat ff_h264_muxer = { - .name = "h264", - .long_name = NULL_IF_CONFIG_SMALL("raw H.264 video"), - .extensions = "h264", - .audio_codec = AV_CODEC_ID_NONE, - .video_codec = AV_CODEC_ID_H264, - .write_packet = ff_raw_write_packet, - .flags = AVFMT_NOTIMESTAMPS, -}; -#endif - -#if CONFIG_M4V_MUXER -AVOutputFormat ff_m4v_muxer = { - .name = "m4v", - .long_name = NULL_IF_CONFIG_SMALL("raw MPEG-4 video"), - .extensions = "m4v", - .audio_codec = AV_CODEC_ID_NONE, - .video_codec = AV_CODEC_ID_MPEG4, - .write_packet = ff_raw_write_packet, - .flags = AVFMT_NOTIMESTAMPS, -}; -#endif - -#if CONFIG_MJPEG_MUXER -AVOutputFormat ff_mjpeg_muxer = { - .name = "mjpeg", - .long_name = NULL_IF_CONFIG_SMALL("raw MJPEG video"), - .mime_type = "video/x-mjpeg", - .extensions = "mjpg,mjpeg", - .audio_codec = AV_CODEC_ID_NONE, - .video_codec = AV_CODEC_ID_MJPEG, - .write_packet = ff_raw_write_packet, - .flags = AVFMT_NOTIMESTAMPS, -}; -#endif - -#if CONFIG_MLP_MUXER -AVOutputFormat ff_mlp_muxer = { - .name = "mlp", - .long_name = NULL_IF_CONFIG_SMALL("raw MLP"), - .extensions = "mlp", - .audio_codec = AV_CODEC_ID_MLP, - .video_codec = AV_CODEC_ID_NONE, - .write_packet = ff_raw_write_packet, - .flags = AVFMT_NOTIMESTAMPS, -}; -#endif - -#if CONFIG_MPEG1VIDEO_MUXER -AVOutputFormat ff_mpeg1video_muxer = { - .name = "mpeg1video", - .long_name = NULL_IF_CONFIG_SMALL("raw MPEG-1 video"), - .mime_type = "video/x-mpeg", - .extensions = "mpg,mpeg,m1v", - .audio_codec = AV_CODEC_ID_NONE, - .video_codec = AV_CODEC_ID_MPEG1VIDEO, - .write_packet = ff_raw_write_packet, - .flags = AVFMT_NOTIMESTAMPS, -}; -#endif - -#if CONFIG_MPEG2VIDEO_MUXER -AVOutputFormat ff_mpeg2video_muxer = { - .name = "mpeg2video", - .long_name = NULL_IF_CONFIG_SMALL("raw MPEG-2 video"), - .extensions = "m2v", - .audio_codec = AV_CODEC_ID_NONE, - .video_codec = AV_CODEC_ID_MPEG2VIDEO, - .write_packet = ff_raw_write_packet, - .flags = AVFMT_NOTIMESTAMPS, -}; -#endif - -#if CONFIG_RAWVIDEO_MUXER -AVOutputFormat ff_rawvideo_muxer = { - .name = "rawvideo", - .long_name = NULL_IF_CONFIG_SMALL("raw video"), - .extensions = "yuv,rgb", - .audio_codec = AV_CODEC_ID_NONE, - .video_codec = AV_CODEC_ID_RAWVIDEO, - .write_packet = ff_raw_write_packet, - .flags = AVFMT_NOTIMESTAMPS, -}; -#endif - -#if CONFIG_TRUEHD_MUXER -AVOutputFormat ff_truehd_muxer = { - .name = "truehd", - .long_name = NULL_IF_CONFIG_SMALL("raw TrueHD"), - .extensions = "thd", - .audio_codec = AV_CODEC_ID_TRUEHD, - .video_codec = AV_CODEC_ID_NONE, - .write_packet = ff_raw_write_packet, - .flags = AVFMT_NOTIMESTAMPS, -}; -#endif - -#if CONFIG_VC1_MUXER -AVOutputFormat ff_vc1_muxer = { - .name = "vc1", - .long_name = NULL_IF_CONFIG_SMALL("raw VC-1 video"), - .extensions = "vc1", - .audio_codec = AV_CODEC_ID_NONE, - .video_codec = AV_CODEC_ID_VC1, - .write_packet = ff_raw_write_packet, - .flags = AVFMT_NOTIMESTAMPS, -}; -#endif diff --git a/ffmpeg1/libavformat/rawenc.h b/ffmpeg1/libavformat/rawenc.h deleted file mode 100644 index b552309..0000000 --- a/ffmpeg1/libavformat/rawenc.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * RAW muxers - * Copyright (C) 2007 Aurelien Jacobs - * - * 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 AVFORMAT_RAWENC_H -#define AVFORMAT_RAWENC_H - -#include "avformat.h" - -int ff_raw_write_packet(AVFormatContext *s, AVPacket *pkt); - -#endif /* AVFORMAT_RAWENC_H */ diff --git a/ffmpeg1/libavformat/rawvideodec.c b/ffmpeg1/libavformat/rawvideodec.c deleted file mode 100644 index 8460781..0000000 --- a/ffmpeg1/libavformat/rawvideodec.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * RAW video demuxer - * 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 - */ - -#include "libavutil/parseutils.h" -#include "libavutil/pixdesc.h" -#include "libavutil/opt.h" -#include "internal.h" -#include "avformat.h" - -typedef struct RawVideoDemuxerContext { - const AVClass *class; /**< Class for private options. */ - char *video_size; /**< String describing video size, set by a private option. */ - char *pixel_format; /**< Set by a private option. */ - char *framerate; /**< String describing framerate, set by a private option. */ -} RawVideoDemuxerContext; - - -static int rawvideo_read_header(AVFormatContext *ctx) -{ - RawVideoDemuxerContext *s = ctx->priv_data; - int width = 0, height = 0, ret = 0; - enum AVPixelFormat pix_fmt; - AVRational framerate; - AVStream *st; - - st = avformat_new_stream(ctx, NULL); - if (!st) - return AVERROR(ENOMEM); - - st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - - st->codec->codec_id = ctx->iformat->raw_codec_id; - - if (s->video_size && - (ret = av_parse_video_size(&width, &height, s->video_size)) < 0) { - av_log(ctx, AV_LOG_ERROR, "Couldn't parse video size.\n"); - return ret; - } - - if ((pix_fmt = av_get_pix_fmt(s->pixel_format)) == AV_PIX_FMT_NONE) { - av_log(ctx, AV_LOG_ERROR, "No such pixel format: %s.\n", - s->pixel_format); - return AVERROR(EINVAL); - } - - if ((ret = av_parse_video_rate(&framerate, s->framerate)) < 0) { - av_log(ctx, AV_LOG_ERROR, "Could not parse framerate: %s.\n", - s->framerate); - return ret; - } - - avpriv_set_pts_info(st, 64, framerate.den, framerate.num); - - st->codec->width = width; - st->codec->height = height; - st->codec->pix_fmt = pix_fmt; - st->codec->bit_rate = av_rescale_q(avpicture_get_size(st->codec->pix_fmt, width, height), - (AVRational){8,1}, st->time_base); - - return 0; -} - - -static int rawvideo_read_packet(AVFormatContext *s, AVPacket *pkt) -{ - int packet_size, ret, width, height; - AVStream *st = s->streams[0]; - - width = st->codec->width; - height = st->codec->height; - - packet_size = avpicture_get_size(st->codec->pix_fmt, width, height); - if (packet_size < 0) - return -1; - - ret = av_get_packet(s->pb, pkt, packet_size); - pkt->pts = pkt->dts = pkt->pos / packet_size; - - pkt->stream_index = 0; - if (ret < 0) - return ret; - return 0; -} - -#define OFFSET(x) offsetof(RawVideoDemuxerContext, x) -#define DEC AV_OPT_FLAG_DECODING_PARAM -static const AVOption rawvideo_options[] = { - { "video_size", "set frame size", OFFSET(video_size), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, DEC }, - { "pixel_format", "set pixel format", OFFSET(pixel_format), AV_OPT_TYPE_STRING, {.str = "yuv420p"}, 0, 0, DEC }, - { "framerate", "set frame rate", OFFSET(framerate), AV_OPT_TYPE_STRING, {.str = "25"}, 0, 0, DEC }, - { NULL }, -}; - -static const AVClass rawvideo_demuxer_class = { - .class_name = "rawvideo demuxer", - .item_name = av_default_item_name, - .option = rawvideo_options, - .version = LIBAVUTIL_VERSION_INT, -}; - -AVInputFormat ff_rawvideo_demuxer = { - .name = "rawvideo", - .long_name = NULL_IF_CONFIG_SMALL("raw video"), - .priv_data_size = sizeof(RawVideoDemuxerContext), - .read_header = rawvideo_read_header, - .read_packet = rawvideo_read_packet, - .flags = AVFMT_GENERIC_INDEX, - .extensions = "yuv,cif,qcif,rgb", - .raw_codec_id = AV_CODEC_ID_RAWVIDEO, - .priv_class = &rawvideo_demuxer_class, -}; diff --git a/ffmpeg1/libavformat/rdt.c b/ffmpeg1/libavformat/rdt.c deleted file mode 100644 index 695323a..0000000 --- a/ffmpeg1/libavformat/rdt.c +++ /dev/null @@ -1,572 +0,0 @@ -/* - * Realmedia RTSP protocol (RDT) support. - * Copyright (c) 2007 Ronald S. Bultje - * - * 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 - */ - -/** - * @file - * @brief Realmedia RTSP protocol (RDT) support - * @author Ronald S. Bultje - */ - -#include "avformat.h" -#include "libavutil/avstring.h" -#include "rtpdec.h" -#include "rdt.h" -#include "libavutil/base64.h" -#include "libavutil/md5.h" -#include "rm.h" -#include "internal.h" -#include "avio_internal.h" -#include "libavcodec/get_bits.h" - -struct RDTDemuxContext { - AVFormatContext *ic; /**< the containing (RTSP) demux context */ - /** Each RDT stream-set (represented by one RTSPStream) can contain - * multiple streams (of the same content, but with possibly different - * codecs/bitrates). Each such stream is represented by one AVStream - * in the AVFormatContext, and this variable points to the offset in - * that array such that the first is the first stream of this set. */ - AVStream **streams; - int n_streams; /**< streams with identifical content in this set */ - void *dynamic_protocol_context; - DynamicPayloadPacketHandlerProc parse_packet; - uint32_t prev_timestamp; - int prev_set_id, prev_stream_id; -}; - -RDTDemuxContext * -ff_rdt_parse_open(AVFormatContext *ic, int first_stream_of_set_idx, - void *priv_data, RTPDynamicProtocolHandler *handler) -{ - RDTDemuxContext *s = av_mallocz(sizeof(RDTDemuxContext)); - if (!s) - return NULL; - - s->ic = ic; - s->streams = &ic->streams[first_stream_of_set_idx]; - do { - s->n_streams++; - } while (first_stream_of_set_idx + s->n_streams < ic->nb_streams && - s->streams[s->n_streams]->id == s->streams[0]->id); - s->prev_set_id = -1; - s->prev_stream_id = -1; - s->prev_timestamp = -1; - s->parse_packet = handler ? handler->parse_packet : NULL; - s->dynamic_protocol_context = priv_data; - - return s; -} - -void -ff_rdt_parse_close(RDTDemuxContext *s) -{ - av_free(s); -} - -struct PayloadContext { - AVFormatContext *rmctx; - int nb_rmst; - RMStream **rmst; - uint8_t *mlti_data; - unsigned int mlti_data_size; - char buffer[RTP_MAX_PACKET_LENGTH + FF_INPUT_BUFFER_PADDING_SIZE]; - int audio_pkt_cnt; /**< remaining audio packets in rmdec */ -}; - -void -ff_rdt_calc_response_and_checksum(char response[41], char chksum[9], - const char *challenge) -{ - int ch_len = strlen (challenge), i; - unsigned char zres[16], - buf[64] = { 0xa1, 0xe9, 0x14, 0x9d, 0x0e, 0x6b, 0x3b, 0x59 }; -#define XOR_TABLE_SIZE 37 - const unsigned char xor_table[XOR_TABLE_SIZE] = { - 0x05, 0x18, 0x74, 0xd0, 0x0d, 0x09, 0x02, 0x53, - 0xc0, 0x01, 0x05, 0x05, 0x67, 0x03, 0x19, 0x70, - 0x08, 0x27, 0x66, 0x10, 0x10, 0x72, 0x08, 0x09, - 0x63, 0x11, 0x03, 0x71, 0x08, 0x08, 0x70, 0x02, - 0x10, 0x57, 0x05, 0x18, 0x54 }; - - /* some (length) checks */ - if (ch_len == 40) /* what a hack... */ - ch_len = 32; - else if (ch_len > 56) - ch_len = 56; - memcpy(buf + 8, challenge, ch_len); - - /* xor challenge bytewise with xor_table */ - for (i = 0; i < XOR_TABLE_SIZE; i++) - buf[8 + i] ^= xor_table[i]; - - av_md5_sum(zres, buf, 64); - ff_data_to_hex(response, zres, 16, 1); - - /* add tail */ - strcpy (response + 32, "01d0a8e3"); - - /* calculate checksum */ - for (i = 0; i < 8; i++) - chksum[i] = response[i * 4]; - chksum[8] = 0; -} - -static int -rdt_load_mdpr (PayloadContext *rdt, AVStream *st, int rule_nr) -{ - AVIOContext pb; - int size; - uint32_t tag; - - /** - * Layout of the MLTI chunk: - * 4: MLTI - * 2: number of streams - * Then for each stream ([number_of_streams] times): - * 2: mdpr index - * 2: number of mdpr chunks - * Then for each mdpr chunk ([number_of_mdpr_chunks] times): - * 4: size - * [size]: data - * we skip MDPR chunks until we reach the one of the stream - * we're interested in, and forward that ([size]+[data]) to - * the RM demuxer to parse the stream-specific header data. - */ - if (!rdt->mlti_data) - return -1; - ffio_init_context(&pb, rdt->mlti_data, rdt->mlti_data_size, 0, - NULL, NULL, NULL, NULL); - tag = avio_rl32(&pb); - if (tag == MKTAG('M', 'L', 'T', 'I')) { - int num, chunk_nr; - - /* read index of MDPR chunk numbers */ - num = avio_rb16(&pb); - if (rule_nr < 0 || rule_nr >= num) - return -1; - avio_skip(&pb, rule_nr * 2); - chunk_nr = avio_rb16(&pb); - avio_skip(&pb, (num - 1 - rule_nr) * 2); - - /* read MDPR chunks */ - num = avio_rb16(&pb); - if (chunk_nr >= num) - return -1; - while (chunk_nr--) - avio_skip(&pb, avio_rb32(&pb)); - size = avio_rb32(&pb); - } else { - size = rdt->mlti_data_size; - avio_seek(&pb, 0, SEEK_SET); - } - if (ff_rm_read_mdpr_codecdata(rdt->rmctx, &pb, st, rdt->rmst[st->index], size, NULL) < 0) - return -1; - - return 0; -} - -/** - * Actual data handling. - */ - -int -ff_rdt_parse_header(const uint8_t *buf, int len, - int *pset_id, int *pseq_no, int *pstream_id, - int *pis_keyframe, uint32_t *ptimestamp) -{ - GetBitContext gb; - int consumed = 0, set_id, seq_no, stream_id, is_keyframe, - len_included, need_reliable; - uint32_t timestamp; - - /* skip status packets */ - while (len >= 5 && buf[1] == 0xFF /* status packet */) { - int pkt_len; - - if (!(buf[0] & 0x80)) - return -1; /* not followed by a data packet */ - - pkt_len = AV_RB16(buf+3); - buf += pkt_len; - len -= pkt_len; - consumed += pkt_len; - } - if (len < 16) - return -1; - /** - * Layout of the header (in bits): - * 1: len_included - * Flag indicating whether this header includes a length field; - * this can be used to concatenate multiple RDT packets in a - * single UDP/TCP data frame and is used to precede RDT data - * by stream status packets - * 1: need_reliable - * Flag indicating whether this header includes a "reliable - * sequence number"; these are apparently sequence numbers of - * data packets alone. For data packets, this flag is always - * set, according to the Real documentation [1] - * 5: set_id - * ID of a set of streams of identical content, possibly with - * different codecs or bitrates - * 1: is_reliable - * Flag set for certain streams deemed less tolerable for packet - * loss - * 16: seq_no - * Packet sequence number; if >=0xFF00, this is a non-data packet - * containing stream status info, the second byte indicates the - * type of status packet (see wireshark docs / source code [2]) - * if (len_included) { - * 16: packet_len - * } else { - * packet_len = remainder of UDP/TCP frame - * } - * 1: is_back_to_back - * Back-to-Back flag; used for timing, set for one in every 10 - * packets, according to the Real documentation [1] - * 1: is_slow_data - * Slow-data flag; currently unused, according to Real docs [1] - * 5: stream_id - * ID of the stream within this particular set of streams - * 1: is_no_keyframe - * Non-keyframe flag (unset if packet belongs to a keyframe) - * 32: timestamp (PTS) - * if (set_id == 0x1F) { - * 16: set_id (extended set-of-streams ID; see set_id) - * } - * if (need_reliable) { - * 16: reliable_seq_no - * Reliable sequence number (see need_reliable) - * } - * if (stream_id == 0x3F) { - * 16: stream_id (extended stream ID; see stream_id) - * } - * [1] https://protocol.helixcommunity.org/files/2005/devdocs/RDT_Feature_Level_20.txt - * [2] http://www.wireshark.org/docs/dfref/r/rdt.html and - * http://anonsvn.wireshark.org/viewvc/trunk/epan/dissectors/packet-rdt.c - */ - init_get_bits(&gb, buf, len << 3); - len_included = get_bits1(&gb); - need_reliable = get_bits1(&gb); - set_id = get_bits(&gb, 5); - skip_bits(&gb, 1); - seq_no = get_bits(&gb, 16); - if (len_included) - skip_bits(&gb, 16); - skip_bits(&gb, 2); - stream_id = get_bits(&gb, 5); - is_keyframe = !get_bits1(&gb); - timestamp = get_bits_long(&gb, 32); - if (set_id == 0x1f) - set_id = get_bits(&gb, 16); - if (need_reliable) - skip_bits(&gb, 16); - if (stream_id == 0x1f) - stream_id = get_bits(&gb, 16); - - if (pset_id) *pset_id = set_id; - if (pseq_no) *pseq_no = seq_no; - if (pstream_id) *pstream_id = stream_id; - if (pis_keyframe) *pis_keyframe = is_keyframe; - if (ptimestamp) *ptimestamp = timestamp; - - return consumed + (get_bits_count(&gb) >> 3); -} - -/**< return 0 on packet, no more left, 1 on packet, 1 on partial packet... */ -static int -rdt_parse_packet (AVFormatContext *ctx, PayloadContext *rdt, AVStream *st, - AVPacket *pkt, uint32_t *timestamp, - const uint8_t *buf, int len, uint16_t rtp_seq, int flags) -{ - int seq = 1, res; - AVIOContext pb; - - if (rdt->audio_pkt_cnt == 0) { - int pos; - - ffio_init_context(&pb, buf, len, 0, NULL, NULL, NULL, NULL); - flags = (flags & RTP_FLAG_KEY) ? 2 : 0; - res = ff_rm_parse_packet (rdt->rmctx, &pb, st, rdt->rmst[st->index], len, pkt, - &seq, flags, *timestamp); - pos = avio_tell(&pb); - if (res < 0) - return res; - if (res > 0) { - if (st->codec->codec_id == AV_CODEC_ID_AAC) { - memcpy (rdt->buffer, buf + pos, len - pos); - rdt->rmctx->pb = avio_alloc_context (rdt->buffer, len - pos, 0, - NULL, NULL, NULL, NULL); - } - goto get_cache; - } - } else { -get_cache: - rdt->audio_pkt_cnt = - ff_rm_retrieve_cache (rdt->rmctx, rdt->rmctx->pb, - st, rdt->rmst[st->index], pkt); - if (rdt->audio_pkt_cnt == 0 && - st->codec->codec_id == AV_CODEC_ID_AAC) - av_freep(&rdt->rmctx->pb); - } - pkt->stream_index = st->index; - pkt->pts = *timestamp; - - return rdt->audio_pkt_cnt > 0; -} - -int -ff_rdt_parse_packet(RDTDemuxContext *s, AVPacket *pkt, - uint8_t **bufptr, int len) -{ - uint8_t *buf = bufptr ? *bufptr : NULL; - int seq_no, flags = 0, stream_id, set_id, is_keyframe; - uint32_t timestamp; - int rv= 0; - - if (!s->parse_packet) - return -1; - - if (!buf && s->prev_stream_id != -1) { - /* return the next packets, if any */ - timestamp= 0; ///< Should not be used if buf is NULL, but should be set to the timestamp of the packet returned.... - rv= s->parse_packet(s->ic, s->dynamic_protocol_context, - s->streams[s->prev_stream_id], - pkt, ×tamp, NULL, 0, 0, flags); - return rv; - } - - if (len < 12) - return -1; - rv = ff_rdt_parse_header(buf, len, &set_id, &seq_no, &stream_id, &is_keyframe, ×tamp); - if (rv < 0) - return rv; - if (is_keyframe && - (set_id != s->prev_set_id || timestamp != s->prev_timestamp || - stream_id != s->prev_stream_id)) { - flags |= RTP_FLAG_KEY; - s->prev_set_id = set_id; - s->prev_timestamp = timestamp; - } - s->prev_stream_id = stream_id; - buf += rv; - len -= rv; - - if (s->prev_stream_id >= s->n_streams) { - s->prev_stream_id = -1; - return -1; - } - - rv = s->parse_packet(s->ic, s->dynamic_protocol_context, - s->streams[s->prev_stream_id], - pkt, ×tamp, buf, len, 0, flags); - - return rv; -} - -void -ff_rdt_subscribe_rule (char *cmd, int size, - int stream_nr, int rule_nr) -{ - av_strlcatf(cmd, size, "stream=%d;rule=%d,stream=%d;rule=%d", - stream_nr, rule_nr * 2, stream_nr, rule_nr * 2 + 1); -} - -static unsigned char * -rdt_parse_b64buf (unsigned int *target_len, const char *p) -{ - unsigned char *target; - int len = strlen(p); - if (*p == '\"') { - p++; - len -= 2; /* skip embracing " at start/end */ - } - *target_len = len * 3 / 4; - target = av_mallocz(*target_len + FF_INPUT_BUFFER_PADDING_SIZE); - av_base64_decode(target, p, *target_len); - return target; -} - -static int -rdt_parse_sdp_line (AVFormatContext *s, int st_index, - PayloadContext *rdt, const char *line) -{ - AVStream *stream = s->streams[st_index]; - const char *p = line; - - if (av_strstart(p, "OpaqueData:buffer;", &p)) { - rdt->mlti_data = rdt_parse_b64buf(&rdt->mlti_data_size, p); - } else if (av_strstart(p, "StartTime:integer;", &p)) - stream->first_dts = atoi(p); - else if (av_strstart(p, "ASMRuleBook:string;", &p)) { - int n, first = -1; - - for (n = 0; n < s->nb_streams; n++) - if (s->streams[n]->id == stream->id) { - int count = s->streams[n]->index + 1; - if (first == -1) first = n; - if (rdt->nb_rmst < count) { - RMStream **rmst= av_realloc(rdt->rmst, count*sizeof(*rmst)); - if (!rmst) - return AVERROR(ENOMEM); - memset(rmst + rdt->nb_rmst, 0, - (count - rdt->nb_rmst) * sizeof(*rmst)); - rdt->rmst = rmst; - rdt->nb_rmst = count; - } - rdt->rmst[s->streams[n]->index] = ff_rm_alloc_rmstream(); - rdt_load_mdpr(rdt, s->streams[n], (n - first) * 2); - } - } - - return 0; -} - -static void -real_parse_asm_rule(AVStream *st, const char *p, const char *end) -{ - do { - /* can be either averagebandwidth= or AverageBandwidth= */ - if (sscanf(p, " %*1[Aa]verage%*1[Bb]andwidth=%d", &st->codec->bit_rate) == 1) - break; - if (!(p = strchr(p, ',')) || p > end) - p = end; - p++; - } while (p < end); -} - -static AVStream * -add_dstream(AVFormatContext *s, AVStream *orig_st) -{ - AVStream *st; - - if (!(st = avformat_new_stream(s, NULL))) - return NULL; - st->id = orig_st->id; - st->codec->codec_type = orig_st->codec->codec_type; - st->first_dts = orig_st->first_dts; - - return st; -} - -static void -real_parse_asm_rulebook(AVFormatContext *s, AVStream *orig_st, - const char *p) -{ - const char *end; - int n_rules = 0, odd = 0; - AVStream *st; - - /** - * The ASMRuleBook contains a list of comma-separated strings per rule, - * and each rule is separated by a ;. The last one also has a ; at the - * end so we can use it as delimiter. - * Every rule occurs twice, once for when the RTSP packet header marker - * is set and once for if it isn't. We only read the first because we - * don't care much (that's what the "odd" variable is for). - * Each rule contains a set of one or more statements, optionally - * preceded by a single condition. If there's a condition, the rule - * starts with a '#'. Multiple conditions are merged between brackets, - * so there are never multiple conditions spread out over separate - * statements. Generally, these conditions are bitrate limits (min/max) - * for multi-bitrate streams. - */ - if (*p == '\"') p++; - while (1) { - if (!(end = strchr(p, ';'))) - break; - if (!odd && end != p) { - if (n_rules > 0) - st = add_dstream(s, orig_st); - else - st = orig_st; - if (!st) - break; - real_parse_asm_rule(st, p, end); - n_rules++; - } - p = end + 1; - odd ^= 1; - } -} - -void -ff_real_parse_sdp_a_line (AVFormatContext *s, int stream_index, - const char *line) -{ - const char *p = line; - - if (av_strstart(p, "ASMRuleBook:string;", &p)) - real_parse_asm_rulebook(s, s->streams[stream_index], p); -} - -static PayloadContext * -rdt_new_context (void) -{ - PayloadContext *rdt = av_mallocz(sizeof(PayloadContext)); - - int ret = avformat_open_input(&rdt->rmctx, "", &ff_rdt_demuxer, NULL); - if (ret < 0) { - av_free(rdt); - return NULL; - } - - return rdt; -} - -static void -rdt_free_context (PayloadContext *rdt) -{ - int i; - - for (i = 0; i < rdt->nb_rmst; i++) - if (rdt->rmst[i]) { - ff_rm_free_rmstream(rdt->rmst[i]); - av_freep(&rdt->rmst[i]); - } - if (rdt->rmctx) - avformat_close_input(&rdt->rmctx); - av_freep(&rdt->mlti_data); - av_freep(&rdt->rmst); - av_free(rdt); -} - -#define RDT_HANDLER(n, s, t) \ -static RTPDynamicProtocolHandler ff_rdt_ ## n ## _handler = { \ - .enc_name = s, \ - .codec_type = t, \ - .codec_id = AV_CODEC_ID_NONE, \ - .parse_sdp_a_line = rdt_parse_sdp_line, \ - .alloc = rdt_new_context, \ - .free = rdt_free_context, \ - .parse_packet = rdt_parse_packet \ -} - -RDT_HANDLER(live_video, "x-pn-multirate-realvideo-live", AVMEDIA_TYPE_VIDEO); -RDT_HANDLER(live_audio, "x-pn-multirate-realaudio-live", AVMEDIA_TYPE_AUDIO); -RDT_HANDLER(video, "x-pn-realvideo", AVMEDIA_TYPE_VIDEO); -RDT_HANDLER(audio, "x-pn-realaudio", AVMEDIA_TYPE_AUDIO); - -void av_register_rdt_dynamic_payload_handlers(void) -{ - ff_register_dynamic_payload_handler(&ff_rdt_video_handler); - ff_register_dynamic_payload_handler(&ff_rdt_audio_handler); - ff_register_dynamic_payload_handler(&ff_rdt_live_video_handler); - ff_register_dynamic_payload_handler(&ff_rdt_live_audio_handler); -} diff --git a/ffmpeg1/libavformat/rdt.h b/ffmpeg1/libavformat/rdt.h deleted file mode 100644 index c2ec94b..0000000 --- a/ffmpeg1/libavformat/rdt.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Realmedia RTSP (RDT) definitions - * Copyright (c) 2007 Ronald S. Bultje - * - * 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 AVFORMAT_RDT_H -#define AVFORMAT_RDT_H - -#include -#include "avformat.h" -#include "rtpdec.h" - -typedef struct RDTDemuxContext RDTDemuxContext; - -/** - * Allocate and init the RDT parsing context. - * @param ic the containing RTSP demuxer context - * @param first_stream_of_set_idx index to the first AVStream in the RTSP - * demuxer context's ic->streams array that is part of this - * particular stream's set of streams (with identical content) - * @param priv_data private data of the payload data handler context - * @param handler pointer to the parse_packet() payload parsing function - * @return a newly allocated RDTDemuxContext. Free with ff_rdt_parse_close(). - */ -RDTDemuxContext *ff_rdt_parse_open(AVFormatContext *ic, - int first_stream_of_set_idx, - void *priv_data, - RTPDynamicProtocolHandler *handler); -void ff_rdt_parse_close(RDTDemuxContext *s); - -/** - * Calculate the response (RealChallenge2 in the RTSP header) to the - * challenge (RealChallenge1 in the RTSP header from the Real/Helix - * server), which is used as some sort of client validation. - * - * @param response pointer to response buffer, it should be at least 41 bytes - * (40 data + 1 zero) bytes long. - * @param chksum pointer to buffer containing a checksum of the response, - * it should be at least 9 (8 data + 1 zero) bytes long. - * @param challenge pointer to the RealChallenge1 value provided by the - * server. - */ -void ff_rdt_calc_response_and_checksum(char response[41], char chksum[9], - const char *challenge); - -/** - * Register RDT-related dynamic payload handlers with our cache. - */ -void av_register_rdt_dynamic_payload_handlers(void); - -/** - * Add subscription information to Subscribe parameter string. - * - * @param cmd string to write the subscription information into. - * @param size size of cmd. - * @param stream_nr stream number. - * @param rule_nr rule number to conform to. - */ -void ff_rdt_subscribe_rule(char *cmd, int size, - int stream_nr, int rule_nr); - -/** - * Parse RDT-style packet header. - * - * @param buf input buffer - * @param len length of input buffer - * @param pset_id will be set to the set ID this packet belongs to - * @param pseq_no will be set to the sequence number of the packet - * @param pstream_id will be set to the stream ID this packet belongs to - * @param pis_keyframe will be whether this packet belongs to a keyframe - * @param ptimestamp will be set to the timestamp of the packet - * @return the amount of bytes consumed, or negative on error - */ -int ff_rdt_parse_header(const uint8_t *buf, int len, - int *pset_id, int *pseq_no, int *pstream_id, - int *pis_keyframe, uint32_t *ptimestamp); - -/** - * Parse RDT-style packet data (header + media data). - * Usage similar to rtp_parse_packet(). - */ -int ff_rdt_parse_packet(RDTDemuxContext *s, AVPacket *pkt, - uint8_t **buf, int len); - -/** - * Parse a server-related SDP line. - * - * @param s the RTSP AVFormatContext - * @param stream_index the index of the first stream in the set represented - * by the SDP m= line (in s->streams) - * @param buf the SDP line - */ -void ff_real_parse_sdp_a_line(AVFormatContext *s, int stream_index, - const char *buf); - -#endif /* AVFORMAT_RDT_H */ diff --git a/ffmpeg1/libavformat/realtextdec.c b/ffmpeg1/libavformat/realtextdec.c deleted file mode 100644 index 67bc339..0000000 --- a/ffmpeg1/libavformat/realtextdec.c +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (c) 2012 Clément BÅ“sch - * - * 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 - */ - -/** - * @file - * RealText subtitle demuxer - * @see http://service.real.com/help/library/guides/ProductionGuide/prodguide/htmfiles/realtext.htm - */ - -#include "avformat.h" -#include "internal.h" -#include "subtitles.h" -#include "libavutil/avstring.h" -#include "libavutil/bprint.h" -#include "libavutil/intreadwrite.h" - -typedef struct { - FFDemuxSubtitlesQueue q; -} RealTextContext; - -static int realtext_probe(AVProbeData *p) -{ - const unsigned char *ptr = p->buf; - - if (AV_RB24(ptr) == 0xEFBBBF) - ptr += 3; /* skip UTF-8 BOM */ - return !av_strncasecmp(ptr, "priv_data; - AVStream *st = avformat_new_stream(s, NULL); - AVBPrint buf; - char c = 0; - int res = 0, duration = read_ts("60"); // default duration is 60 seconds - - if (!st) - return AVERROR(ENOMEM); - avpriv_set_pts_info(st, 64, 1, 100); - st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE; - st->codec->codec_id = AV_CODEC_ID_REALTEXT; - - av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED); - - while (!url_feof(s->pb)) { - AVPacket *sub; - const int64_t pos = avio_tell(s->pb) - (c != 0); - int n = ff_smil_extract_next_chunk(s->pb, &buf, &c); - - if (n == 0) - break; - - if (!av_strncasecmp(buf.str, "codec->extradata = av_strdup(buf.str); - if (!st->codec->extradata) { - res = AVERROR(ENOMEM); - goto end; - } - st->codec->extradata_size = buf.len + 1; - } else { - /* if we just read a