Added MPEG Audio support to FFMPEG plugin, which also supports proper seeking in VBR files; Fixed decoding of files which contain multiple streams
parent
707bc85e24
commit
bbb5549873
|
@ -390,7 +390,7 @@ static float db_to_scale(float db)
|
|||
|
||||
- (void)cleanUp
|
||||
{
|
||||
[[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self];
|
||||
[[NSUserDefaultsController sharedUserDefaultsController] removeObserver:self forKeyPath:@"values.volumeScaling"];
|
||||
|
||||
[rgInfo release];
|
||||
rgInfo = nil;
|
||||
|
|
|
@ -304,6 +304,31 @@
|
|||
833C37D318032E4800CBA602 /* dsputil_init.c in Sources */ = {isa = PBXBuildFile; fileRef = 833C37D218032E4800CBA602 /* dsputil_init.c */; };
|
||||
833C37D518032E7000CBA602 /* jrevdct.c in Sources */ = {isa = PBXBuildFile; fileRef = 833C37D418032E7000CBA602 /* jrevdct.c */; };
|
||||
833C37D718032EA500CBA602 /* idct_xvid.h in Headers */ = {isa = PBXBuildFile; fileRef = 833C37D618032EA500CBA602 /* idct_xvid.h */; };
|
||||
8393B7E218052BB000913C76 /* mp3dec.c in Sources */ = {isa = PBXBuildFile; fileRef = 8393B7DF18052BB000913C76 /* mp3dec.c */; };
|
||||
8393B7E318052BB000913C76 /* mpeg.c in Sources */ = {isa = PBXBuildFile; fileRef = 8393B7E018052BB000913C76 /* mpeg.c */; };
|
||||
8393B7E418052BB000913C76 /* mpeg.h in Headers */ = {isa = PBXBuildFile; fileRef = 8393B7E118052BB000913C76 /* mpeg.h */; };
|
||||
8393B7F918052BC200913C76 /* mpegaudio_parser.c in Sources */ = {isa = PBXBuildFile; fileRef = 8393B7E518052BC200913C76 /* mpegaudio_parser.c */; };
|
||||
8393B7FA18052BC200913C76 /* mpegaudio_tablegen.c in Sources */ = {isa = PBXBuildFile; fileRef = 8393B7E618052BC200913C76 /* mpegaudio_tablegen.c */; };
|
||||
8393B7FB18052BC200913C76 /* mpegaudio_tablegen.h in Headers */ = {isa = PBXBuildFile; fileRef = 8393B7E718052BC200913C76 /* mpegaudio_tablegen.h */; };
|
||||
8393B7FC18052BC200913C76 /* mpegaudio.c in Sources */ = {isa = PBXBuildFile; fileRef = 8393B7E818052BC200913C76 /* mpegaudio.c */; };
|
||||
8393B7FD18052BC200913C76 /* mpegaudio.h in Headers */ = {isa = PBXBuildFile; fileRef = 8393B7E918052BC200913C76 /* mpegaudio.h */; };
|
||||
8393B7FE18052BC200913C76 /* mpegaudiodata.c in Sources */ = {isa = PBXBuildFile; fileRef = 8393B7EA18052BC200913C76 /* mpegaudiodata.c */; };
|
||||
8393B7FF18052BC200913C76 /* mpegaudiodata.h in Headers */ = {isa = PBXBuildFile; fileRef = 8393B7EB18052BC200913C76 /* mpegaudiodata.h */; };
|
||||
8393B80018052BC200913C76 /* mpegaudiodec_float.c in Sources */ = {isa = PBXBuildFile; fileRef = 8393B7EC18052BC200913C76 /* mpegaudiodec_float.c */; };
|
||||
8393B80118052BC200913C76 /* mpegaudiodec.c in Sources */ = {isa = PBXBuildFile; fileRef = 8393B7ED18052BC200913C76 /* mpegaudiodec.c */; };
|
||||
8393B80218052BC200913C76 /* mpegaudiodecheader.c in Sources */ = {isa = PBXBuildFile; fileRef = 8393B7EE18052BC200913C76 /* mpegaudiodecheader.c */; };
|
||||
8393B80318052BC200913C76 /* mpegaudiodecheader.h in Headers */ = {isa = PBXBuildFile; fileRef = 8393B7EF18052BC200913C76 /* mpegaudiodecheader.h */; };
|
||||
8393B80418052BC200913C76 /* mpegaudiodectab.h in Headers */ = {isa = PBXBuildFile; fileRef = 8393B7F018052BC200913C76 /* mpegaudiodectab.h */; };
|
||||
8393B80518052BC200913C76 /* mpegaudiodsp_data.c in Sources */ = {isa = PBXBuildFile; fileRef = 8393B7F118052BC200913C76 /* mpegaudiodsp_data.c */; };
|
||||
8393B80718052BC200913C76 /* mpegaudiodsp_float.c in Sources */ = {isa = PBXBuildFile; fileRef = 8393B7F318052BC200913C76 /* mpegaudiodsp_float.c */; };
|
||||
8393B80A18052BC200913C76 /* mpegaudiodsp.h in Headers */ = {isa = PBXBuildFile; fileRef = 8393B7F618052BC200913C76 /* mpegaudiodsp.h */; };
|
||||
8393B80B18052BC200913C76 /* mpegaudioenc.c in Sources */ = {isa = PBXBuildFile; fileRef = 8393B7F718052BC200913C76 /* mpegaudioenc.c */; };
|
||||
8393B80C18052BC200913C76 /* mpegaudiotab.h in Headers */ = {isa = PBXBuildFile; fileRef = 8393B7F818052BC200913C76 /* mpegaudiotab.h */; };
|
||||
8393B80E18052BD500913C76 /* mpegaudiodsp.c in Sources */ = {isa = PBXBuildFile; fileRef = 8393B80D18052BD500913C76 /* mpegaudiodsp.c */; };
|
||||
8393B81118052DB700913C76 /* bitstream_filter.c in Sources */ = {isa = PBXBuildFile; fileRef = 8393B80F18052DB700913C76 /* bitstream_filter.c */; };
|
||||
8393B81218052DB700913C76 /* mp3_header_decompress_bsf.c in Sources */ = {isa = PBXBuildFile; fileRef = 8393B81018052DB700913C76 /* mp3_header_decompress_bsf.c */; };
|
||||
8393B81418052E7400913C76 /* mpegaudiodsp.c in Sources */ = {isa = PBXBuildFile; fileRef = 8393B81318052E7400913C76 /* mpegaudiodsp.c */; };
|
||||
8393B81618052E9900913C76 /* mpegaudiodsp_fixed.c in Sources */ = {isa = PBXBuildFile; fileRef = 8393B81518052E9900913C76 /* mpegaudiodsp_fixed.c */; };
|
||||
83BCB8E217FCA64400760340 /* avconfig.h in Headers */ = {isa = PBXBuildFile; fileRef = 83BCB8DF17FCA64400760340 /* avconfig.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
83BCB8E317FCA64400760340 /* timecode.c in Sources */ = {isa = PBXBuildFile; fileRef = 83BCB8E017FCA64400760340 /* timecode.c */; };
|
||||
83BCB8E417FCA64400760340 /* timecode.h in Headers */ = {isa = PBXBuildFile; fileRef = 83BCB8E117FCA64400760340 /* timecode.h */; };
|
||||
|
@ -614,6 +639,31 @@
|
|||
833C37D218032E4800CBA602 /* dsputil_init.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dsputil_init.c; sourceTree = "<group>"; };
|
||||
833C37D418032E7000CBA602 /* jrevdct.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = jrevdct.c; sourceTree = "<group>"; };
|
||||
833C37D618032EA500CBA602 /* idct_xvid.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = idct_xvid.h; sourceTree = "<group>"; };
|
||||
8393B7DF18052BB000913C76 /* mp3dec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mp3dec.c; sourceTree = "<group>"; };
|
||||
8393B7E018052BB000913C76 /* mpeg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mpeg.c; sourceTree = "<group>"; };
|
||||
8393B7E118052BB000913C76 /* mpeg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mpeg.h; sourceTree = "<group>"; };
|
||||
8393B7E518052BC200913C76 /* mpegaudio_parser.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mpegaudio_parser.c; sourceTree = "<group>"; };
|
||||
8393B7E618052BC200913C76 /* mpegaudio_tablegen.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mpegaudio_tablegen.c; sourceTree = "<group>"; };
|
||||
8393B7E718052BC200913C76 /* mpegaudio_tablegen.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mpegaudio_tablegen.h; sourceTree = "<group>"; };
|
||||
8393B7E818052BC200913C76 /* mpegaudio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mpegaudio.c; sourceTree = "<group>"; };
|
||||
8393B7E918052BC200913C76 /* mpegaudio.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mpegaudio.h; sourceTree = "<group>"; };
|
||||
8393B7EA18052BC200913C76 /* mpegaudiodata.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mpegaudiodata.c; sourceTree = "<group>"; };
|
||||
8393B7EB18052BC200913C76 /* mpegaudiodata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mpegaudiodata.h; sourceTree = "<group>"; };
|
||||
8393B7EC18052BC200913C76 /* mpegaudiodec_float.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mpegaudiodec_float.c; sourceTree = "<group>"; };
|
||||
8393B7ED18052BC200913C76 /* mpegaudiodec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mpegaudiodec.c; sourceTree = "<group>"; };
|
||||
8393B7EE18052BC200913C76 /* mpegaudiodecheader.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mpegaudiodecheader.c; sourceTree = "<group>"; };
|
||||
8393B7EF18052BC200913C76 /* mpegaudiodecheader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mpegaudiodecheader.h; sourceTree = "<group>"; };
|
||||
8393B7F018052BC200913C76 /* mpegaudiodectab.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mpegaudiodectab.h; sourceTree = "<group>"; };
|
||||
8393B7F118052BC200913C76 /* mpegaudiodsp_data.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mpegaudiodsp_data.c; sourceTree = "<group>"; };
|
||||
8393B7F318052BC200913C76 /* mpegaudiodsp_float.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mpegaudiodsp_float.c; sourceTree = "<group>"; };
|
||||
8393B7F618052BC200913C76 /* mpegaudiodsp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mpegaudiodsp.h; sourceTree = "<group>"; };
|
||||
8393B7F718052BC200913C76 /* mpegaudioenc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mpegaudioenc.c; sourceTree = "<group>"; };
|
||||
8393B7F818052BC200913C76 /* mpegaudiotab.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = mpegaudiotab.h; sourceTree = "<group>"; };
|
||||
8393B80D18052BD500913C76 /* mpegaudiodsp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mpegaudiodsp.c; sourceTree = "<group>"; };
|
||||
8393B80F18052DB700913C76 /* bitstream_filter.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bitstream_filter.c; sourceTree = "<group>"; };
|
||||
8393B81018052DB700913C76 /* mp3_header_decompress_bsf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mp3_header_decompress_bsf.c; sourceTree = "<group>"; };
|
||||
8393B81318052E7400913C76 /* mpegaudiodsp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mpegaudiodsp.c; sourceTree = "<group>"; };
|
||||
8393B81518052E9900913C76 /* mpegaudiodsp_fixed.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mpegaudiodsp_fixed.c; sourceTree = "<group>"; };
|
||||
83BCB8DF17FCA64400760340 /* avconfig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = avconfig.h; sourceTree = "<group>"; };
|
||||
83BCB8E017FCA64400760340 /* timecode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = timecode.c; sourceTree = "<group>"; };
|
||||
83BCB8E117FCA64400760340 /* timecode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = timecode.h; sourceTree = "<group>"; };
|
||||
|
@ -701,6 +751,27 @@
|
|||
830F0B8E17FC4FB900042E8F /* libavcodec */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8393B81518052E9900913C76 /* mpegaudiodsp_fixed.c */,
|
||||
8393B81318052E7400913C76 /* mpegaudiodsp.c */,
|
||||
8393B80F18052DB700913C76 /* bitstream_filter.c */,
|
||||
8393B81018052DB700913C76 /* mp3_header_decompress_bsf.c */,
|
||||
8393B7E518052BC200913C76 /* mpegaudio_parser.c */,
|
||||
8393B7E618052BC200913C76 /* mpegaudio_tablegen.c */,
|
||||
8393B7E718052BC200913C76 /* mpegaudio_tablegen.h */,
|
||||
8393B7E818052BC200913C76 /* mpegaudio.c */,
|
||||
8393B7E918052BC200913C76 /* mpegaudio.h */,
|
||||
8393B7EA18052BC200913C76 /* mpegaudiodata.c */,
|
||||
8393B7EB18052BC200913C76 /* mpegaudiodata.h */,
|
||||
8393B7EC18052BC200913C76 /* mpegaudiodec_float.c */,
|
||||
8393B7ED18052BC200913C76 /* mpegaudiodec.c */,
|
||||
8393B7EE18052BC200913C76 /* mpegaudiodecheader.c */,
|
||||
8393B7EF18052BC200913C76 /* mpegaudiodecheader.h */,
|
||||
8393B7F018052BC200913C76 /* mpegaudiodectab.h */,
|
||||
8393B7F118052BC200913C76 /* mpegaudiodsp_data.c */,
|
||||
8393B7F318052BC200913C76 /* mpegaudiodsp_float.c */,
|
||||
8393B7F618052BC200913C76 /* mpegaudiodsp.h */,
|
||||
8393B7F718052BC200913C76 /* mpegaudioenc.c */,
|
||||
8393B7F818052BC200913C76 /* mpegaudiotab.h */,
|
||||
833C37D418032E7000CBA602 /* jrevdct.c */,
|
||||
833C37CA18032D4800CBA602 /* golomb.c */,
|
||||
833C37CB18032D4800CBA602 /* golomb.h */,
|
||||
|
@ -853,6 +924,9 @@
|
|||
830F0BAD17FC4FB900042E8F /* libavformat */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8393B7DF18052BB000913C76 /* mp3dec.c */,
|
||||
8393B7E018052BB000913C76 /* mpeg.c */,
|
||||
8393B7E118052BB000913C76 /* mpeg.h */,
|
||||
833C37A818032AAD00CBA602 /* img2.c */,
|
||||
833C37A418032A5000CBA602 /* apetag.c */,
|
||||
833C37A518032A5000CBA602 /* apetag.h */,
|
||||
|
@ -1043,6 +1117,7 @@
|
|||
830F0D0717FC80B400042E8F /* x86 */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
8393B80D18052BD500913C76 /* mpegaudiodsp.c */,
|
||||
833C37D618032EA500CBA602 /* idct_xvid.h */,
|
||||
833C37D218032E4800CBA602 /* dsputil_init.c */,
|
||||
833C37CC18032D4800CBA602 /* dirac_dwt.c */,
|
||||
|
@ -1091,6 +1166,7 @@
|
|||
830F0C0617FC4FB900042E8F /* log.h in Headers */,
|
||||
830F0C0317FC4FB900042E8F /* frame.h in Headers */,
|
||||
830F0C0117FC4FB900042E8F /* dict.h in Headers */,
|
||||
8393B80418052BC200913C76 /* mpegaudiodectab.h in Headers */,
|
||||
830F0BFE17FC4FB900042E8F /* channel_layout.h in Headers */,
|
||||
830F0C0017FC4FB900042E8F /* cpu.h in Headers */,
|
||||
830F0C0217FC4FB900042E8F /* error.h in Headers */,
|
||||
|
@ -1101,6 +1177,7 @@
|
|||
830F0BFB17FC4FB900042E8F /* avutil.h in Headers */,
|
||||
830F0C0D17FC4FB900042E8F /* samplefmt.h in Headers */,
|
||||
830F0BFD17FC4FB900042E8F /* buffer.h in Headers */,
|
||||
8393B80A18052BC200913C76 /* mpegaudiodsp.h in Headers */,
|
||||
830F0C1217FC4FF400042E8F /* avfft.h in Headers */,
|
||||
830F0BF017FC4FB900042E8F /* avformat.h in Headers */,
|
||||
B09E94940D74834B0064F138 /* config.h in Headers */,
|
||||
|
@ -1112,10 +1189,12 @@
|
|||
830F0C6C17FC7DB100042E8F /* bprint.h in Headers */,
|
||||
830F0CE117FC7F1E00042E8F /* fmtconvert.h in Headers */,
|
||||
830F0D7717FC8C7300042E8F /* aac.h in Headers */,
|
||||
8393B7FF18052BC200913C76 /* mpegaudiodata.h in Headers */,
|
||||
830F0CD417FC7F1E00042E8F /* dct32.h in Headers */,
|
||||
830F0CCF17FC7F1E00042E8F /* copy_block.h in Headers */,
|
||||
830F0D9317FC8EAC00042E8F /* dvdata.h in Headers */,
|
||||
830F0CEA17FC7F1E00042E8F /* imgconvert.h in Headers */,
|
||||
8393B7FB18052BC200913C76 /* mpegaudio_tablegen.h in Headers */,
|
||||
830F0D4717FC85ED00042E8F /* integer.h in Headers */,
|
||||
830F0D7F17FC8E4800042E8F /* dv.h in Headers */,
|
||||
830F0D0F17FC80B400042E8F /* mathops.h in Headers */,
|
||||
|
@ -1159,6 +1238,7 @@
|
|||
830F0C5017FC7CA300042E8F /* riff.h in Headers */,
|
||||
830F0D5B17FC893E00042E8F /* tableprint.h in Headers */,
|
||||
830F0BE117FC4FB900042E8F /* simple_idct.h in Headers */,
|
||||
8393B7FD18052BC200913C76 /* mpegaudio.h in Headers */,
|
||||
830F0D0C17FC80B400042E8F /* rectangle.h in Headers */,
|
||||
830F0C2F17FC551F00042E8F /* asfcrypt.h in Headers */,
|
||||
830F0C0A17FC4FB900042E8F /* old_pix_fmts.h in Headers */,
|
||||
|
@ -1178,6 +1258,7 @@
|
|||
830F0D6D17FC8C0700042E8F /* aactab.h in Headers */,
|
||||
830F0BEC17FC4FB900042E8F /* wmavoice_data.h in Headers */,
|
||||
833C37D118032D4800CBA602 /* dirac_dwt.h in Headers */,
|
||||
8393B80318052BC200913C76 /* mpegaudiodecheader.h in Headers */,
|
||||
830F0D7917FC8C7300042E8F /* mpeg4audio.h in Headers */,
|
||||
830F0C3A17FC554D00042E8F /* des.h in Headers */,
|
||||
830F0BF117FC4FB900042E8F /* avi.h in Headers */,
|
||||
|
@ -1202,6 +1283,7 @@
|
|||
830F0D8B17FC8E8B00042E8F /* aacpsdsp.h in Headers */,
|
||||
830F0CD617FC7F1E00042E8F /* dctref.h in Headers */,
|
||||
830F0C1917FC523000042E8F /* rdt.h in Headers */,
|
||||
8393B80C18052BC200913C76 /* mpegaudiotab.h in Headers */,
|
||||
830F0CF117FC7F1E00042E8F /* ratecontrol.h in Headers */,
|
||||
830F0C1417FC500B00042E8F /* fft-internal.h in Headers */,
|
||||
830F0D8E17FC8E8B00042E8F /* sbr.h in Headers */,
|
||||
|
@ -1225,6 +1307,7 @@
|
|||
830F0C5717FC7CC300042E8F /* avlanguage.h in Headers */,
|
||||
830F0D2417FC82AB00042E8F /* fifo.h in Headers */,
|
||||
830F0BD917FC4FB900042E8F /* mathops.h in Headers */,
|
||||
8393B7E418052BB000913C76 /* mpeg.h in Headers */,
|
||||
830F0C3C17FC554D00042E8F /* float_dsp.h in Headers */,
|
||||
833C37CF18032D4800CBA602 /* golomb.h in Headers */,
|
||||
830F0C8117FC7ED100042E8F /* crc.h in Headers */,
|
||||
|
@ -1324,21 +1407,27 @@
|
|||
830F0DCD17FC933100042E8F /* w64.c in Sources */,
|
||||
833C37D518032E7000CBA602 /* jrevdct.c in Sources */,
|
||||
830F0BE217FC4FB900042E8F /* utils.c in Sources */,
|
||||
8393B80E18052BD500913C76 /* mpegaudiodsp.c in Sources */,
|
||||
8393B81418052E7400913C76 /* mpegaudiodsp.c in Sources */,
|
||||
830F0CF917FC7F1E00042E8F /* sinewin.c in Sources */,
|
||||
833C37C418032CF600CBA602 /* dirac_dwt.c in Sources */,
|
||||
830F0CE417FC7F1E00042E8F /* h264chroma_template.c in Sources */,
|
||||
830F0BEF17FC4FB900042E8F /* asf.c in Sources */,
|
||||
830F0BD517FC4FB900042E8F /* fft.c in Sources */,
|
||||
830F0CFE17FC7F1E00042E8F /* wma.c in Sources */,
|
||||
8393B7E218052BB000913C76 /* mp3dec.c in Sources */,
|
||||
830F0BD117FC4FB900042E8F /* allcodecs.c in Sources */,
|
||||
8393B80718052BC200913C76 /* mpegaudiodsp_float.c in Sources */,
|
||||
830F0D5917FC893E00042E8F /* codec_desc.c in Sources */,
|
||||
830F0DBE17FC922C00042E8F /* h264chroma_init.c in Sources */,
|
||||
830F0BF217FC4FB900042E8F /* avio.c in Sources */,
|
||||
830F0CE217FC7F1E00042E8F /* frame_thread_encoder.c in Sources */,
|
||||
8393B80118052BC200913C76 /* mpegaudiodec.c in Sources */,
|
||||
830F0C3817FC554D00042E8F /* buffer.c in Sources */,
|
||||
830F0C6B17FC7DB100042E8F /* bprint.c in Sources */,
|
||||
830F0BE017FC4FB900042E8F /* simple_idct.c in Sources */,
|
||||
830F0D6917FC8A3D00042E8F /* avpicture.c in Sources */,
|
||||
8393B80518052BC200913C76 /* mpegaudiodsp_data.c in Sources */,
|
||||
830F0CDA17FC7F1E00042E8F /* error_resilience.c in Sources */,
|
||||
830F0D3317FC841B00042E8F /* opt.c in Sources */,
|
||||
830F0D7317FC8C1300042E8F /* astdec.c in Sources */,
|
||||
|
@ -1346,16 +1435,19 @@
|
|||
833C379D180328B300CBA602 /* takdec.c in Sources */,
|
||||
830F0D7B17FC8E2400042E8F /* avidec.c in Sources */,
|
||||
830F0D4F17FC862400042E8F /* utils.c in Sources */,
|
||||
8393B81218052DB700913C76 /* mp3_header_decompress_bsf.c in Sources */,
|
||||
830F0BEB17FC4FB900042E8F /* wmavoice.c in Sources */,
|
||||
833C37B318032AEF00CBA602 /* dsputil.c in Sources */,
|
||||
830F0CC217FC7F1E00042E8F /* acelp_filters.c in Sources */,
|
||||
830F0DB017FC8FBD00042E8F /* hpeldsp_init.c in Sources */,
|
||||
830F0C1B17FC523000042E8F /* url.c in Sources */,
|
||||
830F0CC417FC7F1E00042E8F /* acelp_pitch_delay.c in Sources */,
|
||||
8393B80218052BC200913C76 /* mpegaudiodecheader.c in Sources */,
|
||||
833C37C218032CF600CBA602 /* dirac_arith.c in Sources */,
|
||||
830F0CEB17FC7F1E00042E8F /* lsp.c in Sources */,
|
||||
830F0D1317FC815000042E8F /* constants.c in Sources */,
|
||||
830F0BE417FC4FB900042E8F /* wma_common.c in Sources */,
|
||||
8393B7FA18052BC200913C76 /* mpegaudio_tablegen.c in Sources */,
|
||||
830F0C5617FC7CC300042E8F /* avlanguage.c in Sources */,
|
||||
830F0C5117FC7CA300042E8F /* riffdec.c in Sources */,
|
||||
830F0D4617FC85ED00042E8F /* integer.c in Sources */,
|
||||
|
@ -1381,6 +1473,7 @@
|
|||
830F0CDE17FC7F1E00042E8F /* faanidct.c in Sources */,
|
||||
833C379B180328B300CBA602 /* tak.c in Sources */,
|
||||
830F0CC917FC7F1E00042E8F /* bit_depth_template.c in Sources */,
|
||||
8393B7E318052BB000913C76 /* mpeg.c in Sources */,
|
||||
830F0D4017FC848D00042E8F /* sha.c in Sources */,
|
||||
830F0BF417FC4FB900042E8F /* aviobuf.c in Sources */,
|
||||
830F0C1117FC4FF400042E8F /* avfft.c in Sources */,
|
||||
|
@ -1400,11 +1493,13 @@
|
|||
830F0C8217FC7ED100042E8F /* dict.c in Sources */,
|
||||
830F0D7817FC8C7300042E8F /* mpeg4audio.c in Sources */,
|
||||
830F0D5F17FC89BD00042E8F /* options.c in Sources */,
|
||||
8393B7FE18052BC200913C76 /* mpegaudiodata.c in Sources */,
|
||||
833C37D318032E4800CBA602 /* dsputil_init.c in Sources */,
|
||||
830F0DB917FC921D00042E8F /* cpu.c in Sources */,
|
||||
830F0C7D17FC7E4E00042E8F /* mathematics.c in Sources */,
|
||||
830F0BDD17FC4FB900042E8F /* parser.c in Sources */,
|
||||
830F0C5C17FC7CEA00042E8F /* id3v1.c in Sources */,
|
||||
8393B7F918052BC200913C76 /* mpegaudio_parser.c in Sources */,
|
||||
830F0CFC17FC7F1E00042E8F /* videodsp.c in Sources */,
|
||||
830F0D8C17FC8E8B00042E8F /* dv_profile.c in Sources */,
|
||||
833C37B118032AEF00CBA602 /* diracdsp.c in Sources */,
|
||||
|
@ -1412,6 +1507,7 @@
|
|||
833C3795180328A300CBA602 /* takdec.c in Sources */,
|
||||
830F0DC217FC929E00042E8F /* mux.c in Sources */,
|
||||
830F0BF517FC4FB900042E8F /* cutils.c in Sources */,
|
||||
8393B81618052E9900913C76 /* mpegaudiodsp_fixed.c in Sources */,
|
||||
830F0D2E17FC841B00042E8F /* channel_layout.c in Sources */,
|
||||
830F0CE517FC7F1E00042E8F /* h264chroma.c in Sources */,
|
||||
830F0BE717FC4FB900042E8F /* wmadec.c in Sources */,
|
||||
|
@ -1425,6 +1521,7 @@
|
|||
830F0BF617FC4FB900042E8F /* file.c in Sources */,
|
||||
830F0D3817FC844E00042E8F /* parseutils.c in Sources */,
|
||||
830F0D2017FC82AB00042E8F /* cpu.c in Sources */,
|
||||
8393B7FC18052BC200913C76 /* mpegaudio.c in Sources */,
|
||||
833C37C618032CF600CBA602 /* dirac_parser.c in Sources */,
|
||||
830F0CED17FC7F1E00042E8F /* mpeg12data.c in Sources */,
|
||||
833C37C718032CF600CBA602 /* dirac.c in Sources */,
|
||||
|
@ -1432,16 +1529,19 @@
|
|||
830F0C7B17FC7E4E00042E8F /* crc.c in Sources */,
|
||||
830F0BE817FC4FB900042E8F /* wmalosslessdec.c in Sources */,
|
||||
83BCB8E317FCA64400760340 /* timecode.c in Sources */,
|
||||
8393B80B18052BC200913C76 /* mpegaudioenc.c in Sources */,
|
||||
830F0D3517FC841B00042E8F /* samplefmt.c in Sources */,
|
||||
830F0BEA17FC4FB900042E8F /* wmaprodec.c in Sources */,
|
||||
830F0CCD17FC7F1E00042E8F /* celp_math.c in Sources */,
|
||||
830F0DC017FC927D00042E8F /* float_dsp_init.c in Sources */,
|
||||
830F0C8317FC7ED100042E8F /* rational.c in Sources */,
|
||||
830F0CD517FC7F1E00042E8F /* dctref.c in Sources */,
|
||||
8393B81118052DB700913C76 /* bitstream_filter.c in Sources */,
|
||||
830F0D2317FC82AB00042E8F /* fifo.c in Sources */,
|
||||
830F0D3C17FC846C00042E8F /* random_seed.c in Sources */,
|
||||
830F0C4F17FC7CA300042E8F /* riff.c in Sources */,
|
||||
830F0C4D17FC7CA300042E8F /* metadata.c in Sources */,
|
||||
8393B80018052BC200913C76 /* mpegaudiodec_float.c in Sources */,
|
||||
830F0C7C17FC7E4E00042E8F /* log.c in Sources */,
|
||||
830F0D6417FC8A3300042E8F /* audiointerleave.c in Sources */,
|
||||
);
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#define HAVE_AVX_EXTERNAL 0
|
||||
#define HAVE_YASM 0
|
||||
#define HAVE_MIPSFPU 0
|
||||
#define HAVE_MIPSDSPR1 0
|
||||
#define __CPU__ 586
|
||||
#define HAVE_BUILTIN_VECTOR 1
|
||||
#define HAVE_LOCALTIME_R 1
|
||||
|
@ -34,7 +35,7 @@
|
|||
#undef HAVE_VHOOK
|
||||
#define CONFIG_ENCODERS 0
|
||||
#define CONFIG_DECODERS 1
|
||||
#undef CONFIG_MPEGAUDIO_HP
|
||||
#define CONFIG_MPEGAUDIO_HP 0
|
||||
#undef CONFIG_VIDEO4LINUX
|
||||
#undef CONFIG_DV1394
|
||||
#define CONFIG_HAVE_DLOPEN 1
|
||||
|
@ -416,12 +417,12 @@
|
|||
#define CONFIG_METASOUND_DECODER 0
|
||||
#define CONFIG_MLP_DECODER 0
|
||||
#define CONFIG_MP1_DECODER 0
|
||||
#define CONFIG_MP1FLOAT_DECODER 0
|
||||
#define CONFIG_MP1FLOAT_DECODER 1
|
||||
#define CONFIG_MP2_ENCODER 0
|
||||
#define CONFIG_MP2_DECODER 0
|
||||
#define CONFIG_MP2FLOAT_DECODER 0
|
||||
#define CONFIG_MP2FLOAT_DECODER 1
|
||||
#define CONFIG_MP3_DECODER 0
|
||||
#define CONFIG_MP3FLOAT_DECODER 0
|
||||
#define CONFIG_MP3FLOAT_DECODER 1
|
||||
#define CONFIG_MP3ADU_DECODER 0
|
||||
#define CONFIG_MP3ADUFLOAT_DECODER 0
|
||||
#define CONFIG_MP3ON4_DECODER 0
|
||||
|
@ -669,7 +670,7 @@
|
|||
#define CONFIG_MJPEG_PARSER 0
|
||||
#define CONFIG_MLP_PARSER 0
|
||||
#define CONFIG_MPEG4VIDEO_PARSER 0
|
||||
#define CONFIG_MPEGAUDIO_PARSER 0
|
||||
#define CONFIG_MPEGAUDIO_PARSER 1
|
||||
#define CONFIG_MPEGVIDEO_PARSER 0
|
||||
#define CONFIG_PNG_PARSER 0
|
||||
#define CONFIG_PNM_PARSER 0
|
||||
|
@ -689,7 +690,7 @@
|
|||
#define CONFIG_MJPEG2JPEG_BSF 0
|
||||
#define CONFIG_MJPEGA_DUMP_HEADER_BSF 0
|
||||
#define CONFIG_MP3_HEADER_COMPRESS_BSF 0
|
||||
#define CONFIG_MP3_HEADER_DECOMPRESS_BSF 0
|
||||
#define CONFIG_MP3_HEADER_DECOMPRESS_BSF 1
|
||||
#define CONFIG_MOV2TEXTSUB_BSF 0
|
||||
#define CONFIG_NOISE_BSF 0
|
||||
#define CONFIG_REMOVE_EXTRADATA_BSF 0
|
||||
|
@ -855,7 +856,7 @@
|
|||
#define CONFIG_MOV_DEMUXER 0
|
||||
#define CONFIG_MP2_MUXER 0
|
||||
#define CONFIG_MP3_MUXER 0
|
||||
#define CONFIG_MP3_DEMUXER 0
|
||||
#define CONFIG_MP3_DEMUXER 1
|
||||
#define CONFIG_MP4_MUXER 0
|
||||
#define CONFIG_MPC_DEMUXER 0
|
||||
#define CONFIG_MPC8_DEMUXER 0
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
|
||||
*
|
||||
* 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 <string.h>
|
||||
|
||||
#include "avcodec.h"
|
||||
#include "libavutil/atomic.h"
|
||||
#include "libavutil/mem.h"
|
||||
|
||||
static AVBitStreamFilter *first_bitstream_filter = NULL;
|
||||
|
||||
AVBitStreamFilter *av_bitstream_filter_next(AVBitStreamFilter *f)
|
||||
{
|
||||
if (f)
|
||||
return f->next;
|
||||
else
|
||||
return first_bitstream_filter;
|
||||
}
|
||||
|
||||
void av_register_bitstream_filter(AVBitStreamFilter *bsf)
|
||||
{
|
||||
do {
|
||||
bsf->next = first_bitstream_filter;
|
||||
} while(bsf->next != avpriv_atomic_ptr_cas((void * volatile *)&first_bitstream_filter, bsf->next, bsf));
|
||||
}
|
||||
|
||||
AVBitStreamFilterContext *av_bitstream_filter_init(const char *name)
|
||||
{
|
||||
AVBitStreamFilter *bsf = first_bitstream_filter;
|
||||
|
||||
while (bsf) {
|
||||
if (!strcmp(name, bsf->name)) {
|
||||
AVBitStreamFilterContext *bsfc =
|
||||
av_mallocz(sizeof(AVBitStreamFilterContext));
|
||||
bsfc->filter = bsf;
|
||||
bsfc->priv_data =
|
||||
bsf->priv_data_size ? av_mallocz(bsf->priv_data_size) : NULL;
|
||||
return bsfc;
|
||||
}
|
||||
bsf = bsf->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void av_bitstream_filter_close(AVBitStreamFilterContext *bsfc)
|
||||
{
|
||||
if (!bsfc)
|
||||
return;
|
||||
if (bsfc->filter->close)
|
||||
bsfc->filter->close(bsfc);
|
||||
av_freep(&bsfc->priv_data);
|
||||
av_parser_close(bsfc->parser);
|
||||
av_free(bsfc);
|
||||
}
|
||||
|
||||
int av_bitstream_filter_filter(AVBitStreamFilterContext *bsfc,
|
||||
AVCodecContext *avctx, const char *args,
|
||||
uint8_t **poutbuf, int *poutbuf_size,
|
||||
const uint8_t *buf, int buf_size, int keyframe)
|
||||
{
|
||||
*poutbuf = (uint8_t *)buf;
|
||||
*poutbuf_size = buf_size;
|
||||
return bsfc->filter->filter(bsfc, avctx, args, poutbuf, poutbuf_size,
|
||||
buf, buf_size, keyframe);
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
|
||||
*
|
||||
* 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 "libavutil/intreadwrite.h"
|
||||
#include "avcodec.h"
|
||||
#include "mpegaudiodecheader.h"
|
||||
#include "mpegaudiodata.h"
|
||||
|
||||
|
||||
static int mp3_header_decompress(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const char *args,
|
||||
uint8_t **poutbuf, int *poutbuf_size,
|
||||
const uint8_t *buf, int buf_size, int keyframe){
|
||||
uint32_t header;
|
||||
int sample_rate= avctx->sample_rate;
|
||||
int sample_rate_index=0;
|
||||
int lsf, mpeg25, bitrate_index, frame_size;
|
||||
|
||||
header = AV_RB32(buf);
|
||||
if(ff_mpa_check_header(header) >= 0){
|
||||
*poutbuf= (uint8_t *) buf;
|
||||
*poutbuf_size= buf_size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(avctx->extradata_size != 15 || strcmp(avctx->extradata, "FFCMP3 0.0")){
|
||||
av_log(avctx, AV_LOG_ERROR, "Extradata invalid %d\n", avctx->extradata_size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
header= AV_RB32(avctx->extradata+11) & MP3_MASK;
|
||||
|
||||
lsf = sample_rate < (24000+32000)/2;
|
||||
mpeg25 = sample_rate < (12000+16000)/2;
|
||||
sample_rate_index= (header>>10)&3;
|
||||
sample_rate= avpriv_mpa_freq_tab[sample_rate_index] >> (lsf + mpeg25); //in case sample rate is a little off
|
||||
|
||||
for(bitrate_index=2; bitrate_index<30; bitrate_index++){
|
||||
frame_size = avpriv_mpa_bitrate_tab[lsf][2][bitrate_index>>1];
|
||||
frame_size = (frame_size * 144000) / (sample_rate << lsf) + (bitrate_index&1);
|
||||
if(frame_size == buf_size + 4)
|
||||
break;
|
||||
if(frame_size == buf_size + 6)
|
||||
break;
|
||||
}
|
||||
if(bitrate_index == 30){
|
||||
av_log(avctx, AV_LOG_ERROR, "Could not find bitrate_index.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
header |= (bitrate_index&1)<<9;
|
||||
header |= (bitrate_index>>1)<<12;
|
||||
header |= (frame_size == buf_size + 4)<<16; //FIXME actually set a correct crc instead of 0
|
||||
|
||||
*poutbuf_size= frame_size;
|
||||
*poutbuf= av_malloc(frame_size + FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
memcpy(*poutbuf + frame_size - buf_size, buf, buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
|
||||
if(avctx->channels==2){
|
||||
uint8_t *p= *poutbuf + frame_size - buf_size;
|
||||
if(lsf){
|
||||
FFSWAP(int, p[1], p[2]);
|
||||
header |= (p[1] & 0xC0)>>2;
|
||||
p[1] &= 0x3F;
|
||||
}else{
|
||||
header |= p[1] & 0x30;
|
||||
p[1] &= 0xCF;
|
||||
}
|
||||
}
|
||||
|
||||
AV_WB32(*poutbuf, header);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
AVBitStreamFilter ff_mp3_header_decompress_bsf={
|
||||
.name = "mp3decomp",
|
||||
.filter = mp3_header_decompress,
|
||||
};
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* MPEG Audio common code
|
||||
* Copyright (c) 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
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* MPEG Audio common code.
|
||||
*/
|
||||
|
||||
#include "mpegaudio.h"
|
||||
|
||||
|
||||
/* bitrate is in kb/s */
|
||||
int ff_mpa_l2_select_table(int bitrate, int nb_channels, int freq, int lsf)
|
||||
{
|
||||
int ch_bitrate, table;
|
||||
|
||||
ch_bitrate = bitrate / nb_channels;
|
||||
if (!lsf) {
|
||||
if ((freq == 48000 && ch_bitrate >= 56) ||
|
||||
(ch_bitrate >= 56 && ch_bitrate <= 80))
|
||||
table = 0;
|
||||
else if (freq != 48000 && ch_bitrate >= 96)
|
||||
table = 1;
|
||||
else if (freq != 32000 && ch_bitrate <= 48)
|
||||
table = 2;
|
||||
else
|
||||
table = 3;
|
||||
} else {
|
||||
table = 4;
|
||||
}
|
||||
return table;
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* mpeg audio declarations for both encoder and decoder.
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_MPEGAUDIO_H
|
||||
#define AVCODEC_MPEGAUDIO_H
|
||||
|
||||
#ifndef CONFIG_FLOAT
|
||||
# define CONFIG_FLOAT 0
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* max frame size, in samples */
|
||||
#define MPA_FRAME_SIZE 1152
|
||||
|
||||
/* max compressed frame size */
|
||||
#define MPA_MAX_CODED_FRAME_SIZE 1792
|
||||
|
||||
#define MPA_MAX_CHANNELS 2
|
||||
|
||||
#define SBLIMIT 32 /* number of subbands */
|
||||
|
||||
#define MPA_STEREO 0
|
||||
#define MPA_JSTEREO 1
|
||||
#define MPA_DUAL 2
|
||||
#define MPA_MONO 3
|
||||
|
||||
#ifndef FRAC_BITS
|
||||
#define FRAC_BITS 23 /* fractional bits for sb_samples and dct */
|
||||
#define WFRAC_BITS 16 /* fractional bits for window */
|
||||
#endif
|
||||
|
||||
#define IMDCT_SCALAR 1.759
|
||||
|
||||
#define FRAC_ONE (1 << FRAC_BITS)
|
||||
|
||||
#define FIX(a) ((int)((a) * FRAC_ONE))
|
||||
|
||||
#if CONFIG_FLOAT
|
||||
# define INTFLOAT float
|
||||
typedef float MPA_INT;
|
||||
typedef float OUT_INT;
|
||||
#elif FRAC_BITS <= 15
|
||||
# define INTFLOAT int
|
||||
typedef int16_t MPA_INT;
|
||||
typedef int16_t OUT_INT;
|
||||
#else
|
||||
# define INTFLOAT int
|
||||
typedef int32_t MPA_INT;
|
||||
typedef int16_t OUT_INT;
|
||||
#endif
|
||||
|
||||
int ff_mpa_l2_select_table(int bitrate, int nb_channels, int freq, int lsf);
|
||||
|
||||
#endif /* AVCODEC_MPEGAUDIO_H */
|
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* MPEG Audio parser
|
||||
* Copyright (c) 2003 Fabrice Bellard
|
||||
* Copyright (c) 2003 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 "parser.h"
|
||||
#include "mpegaudiodecheader.h"
|
||||
#include "libavutil/common.h"
|
||||
|
||||
|
||||
typedef struct MpegAudioParseContext {
|
||||
ParseContext pc;
|
||||
int frame_size;
|
||||
uint32_t header;
|
||||
int header_count;
|
||||
int no_bitrate;
|
||||
} MpegAudioParseContext;
|
||||
|
||||
#define MPA_HEADER_SIZE 4
|
||||
|
||||
/* header + layer + bitrate + freq + lsf/mpeg25 */
|
||||
#define SAME_HEADER_MASK \
|
||||
(0xffe00000 | (3 << 17) | (3 << 10) | (3 << 19))
|
||||
|
||||
static int mpegaudio_parse(AVCodecParserContext *s1,
|
||||
AVCodecContext *avctx,
|
||||
const uint8_t **poutbuf, int *poutbuf_size,
|
||||
const uint8_t *buf, int buf_size)
|
||||
{
|
||||
MpegAudioParseContext *s = s1->priv_data;
|
||||
ParseContext *pc = &s->pc;
|
||||
uint32_t state= pc->state;
|
||||
int i;
|
||||
int next= END_NOT_FOUND;
|
||||
|
||||
for(i=0; i<buf_size; ){
|
||||
if(s->frame_size){
|
||||
int inc= FFMIN(buf_size - i, s->frame_size);
|
||||
i += inc;
|
||||
s->frame_size -= inc;
|
||||
state = 0;
|
||||
|
||||
if(!s->frame_size){
|
||||
next= i;
|
||||
break;
|
||||
}
|
||||
}else{
|
||||
while(i<buf_size){
|
||||
int ret, sr, channels, bit_rate, frame_size;
|
||||
|
||||
state= (state<<8) + buf[i++];
|
||||
|
||||
ret = avpriv_mpa_decode_header(avctx, state, &sr, &channels, &frame_size, &bit_rate);
|
||||
if (ret < 4) {
|
||||
if (i > 4)
|
||||
s->header_count = -2;
|
||||
} else {
|
||||
if((state&SAME_HEADER_MASK) != (s->header&SAME_HEADER_MASK) && s->header)
|
||||
s->header_count= -3;
|
||||
s->header= state;
|
||||
s->header_count++;
|
||||
s->frame_size = ret-4;
|
||||
|
||||
if (s->header_count > 0) {
|
||||
avctx->sample_rate= sr;
|
||||
avctx->channels = channels;
|
||||
s1->duration = frame_size;
|
||||
if (s->no_bitrate || !avctx->bit_rate) {
|
||||
s->no_bitrate = 1;
|
||||
avctx->bit_rate += (bit_rate - avctx->bit_rate) / s->header_count;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pc->state= state;
|
||||
if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
|
||||
*poutbuf = NULL;
|
||||
*poutbuf_size = 0;
|
||||
return buf_size;
|
||||
}
|
||||
|
||||
*poutbuf = buf;
|
||||
*poutbuf_size = buf_size;
|
||||
return next;
|
||||
}
|
||||
|
||||
|
||||
AVCodecParser ff_mpegaudio_parser = {
|
||||
.codec_ids = { AV_CODEC_ID_MP1, AV_CODEC_ID_MP2, AV_CODEC_ID_MP3 },
|
||||
.priv_data_size = sizeof(MpegAudioParseContext),
|
||||
.parser_parse = mpegaudio_parse,
|
||||
.parser_close = ff_parse_close,
|
||||
};
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Generate a header file for hardcoded mpegaudiodec tables
|
||||
*
|
||||
* Copyright (c) 2009 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
|
||||
*
|
||||
* 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 <stdlib.h>
|
||||
#define CONFIG_HARDCODED_TABLES 0
|
||||
#include "mpegaudio_tablegen.h"
|
||||
#include "tableprint.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
mpegaudio_tableinit();
|
||||
|
||||
write_fileheader();
|
||||
|
||||
WRITE_ARRAY("static const", int8_t, table_4_3_exp);
|
||||
WRITE_ARRAY("static const", uint32_t, table_4_3_value);
|
||||
WRITE_ARRAY("static const", uint32_t, exp_table_fixed);
|
||||
WRITE_ARRAY("static const", float, exp_table_float);
|
||||
WRITE_2D_ARRAY("static const", uint32_t, expval_table_fixed);
|
||||
WRITE_2D_ARRAY("static const", float, expval_table_float);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Header file for hardcoded mpegaudiodec tables
|
||||
*
|
||||
* Copyright (c) 2009 Reimar Döffinger <Reimar.Doeffinger@gmx.de>
|
||||
*
|
||||
* 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 AVCODEC_MPEGAUDIO_TABLEGEN_H
|
||||
#define AVCODEC_MPEGAUDIO_TABLEGEN_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
|
||||
#define TABLE_4_3_SIZE (8191 + 16)*4
|
||||
#if CONFIG_HARDCODED_TABLES
|
||||
#define mpegaudio_tableinit()
|
||||
#include "libavcodec/mpegaudio_tables.h"
|
||||
#else
|
||||
static int8_t table_4_3_exp[TABLE_4_3_SIZE];
|
||||
static uint32_t table_4_3_value[TABLE_4_3_SIZE];
|
||||
static uint32_t exp_table_fixed[512];
|
||||
static uint32_t expval_table_fixed[512][16];
|
||||
static float exp_table_float[512];
|
||||
static float expval_table_float[512][16];
|
||||
|
||||
#define FRAC_BITS 23
|
||||
#define IMDCT_SCALAR 1.759
|
||||
|
||||
static void mpegaudio_tableinit(void)
|
||||
{
|
||||
int i, value, exponent;
|
||||
for (i = 1; i < TABLE_4_3_SIZE; i++) {
|
||||
double value = i / 4;
|
||||
double f, fm;
|
||||
int e, m;
|
||||
f = value / IMDCT_SCALAR * cbrtf(value) * pow(2, (i & 3) * 0.25);
|
||||
fm = frexp(f, &e);
|
||||
m = (uint32_t)(fm * (1LL << 31) + 0.5);
|
||||
e += FRAC_BITS - 31 + 5 - 100;
|
||||
|
||||
/* normalized to FRAC_BITS */
|
||||
table_4_3_value[i] = m;
|
||||
table_4_3_exp[i] = -e;
|
||||
}
|
||||
for (exponent = 0; exponent < 512; exponent++) {
|
||||
for (value = 0; value < 16; value++) {
|
||||
double f = (double)value * cbrtf(value) * pow(2, (exponent - 400) * 0.25 + FRAC_BITS + 5) / IMDCT_SCALAR;
|
||||
expval_table_fixed[exponent][value] = llrint(f);
|
||||
expval_table_float[exponent][value] = f;
|
||||
}
|
||||
exp_table_fixed[exponent] = expval_table_fixed[exponent][1];
|
||||
exp_table_float[exponent] = expval_table_float[exponent][1];
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_HARDCODED_TABLES */
|
||||
|
||||
#endif /* AVCODEC_MPEGAUDIO_TABLEGEN_H */
|
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
* MPEG Audio common tables
|
||||
* 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
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* mpeg audio layer common tables.
|
||||
*/
|
||||
|
||||
#include "mpegaudiodata.h"
|
||||
|
||||
|
||||
const uint16_t avpriv_mpa_bitrate_tab[2][3][15] = {
|
||||
{ {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448 },
|
||||
{0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384 },
|
||||
{0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 } },
|
||||
{ {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256},
|
||||
{0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160},
|
||||
{0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160}
|
||||
}
|
||||
};
|
||||
|
||||
const uint16_t avpriv_mpa_freq_tab[3] = { 44100, 48000, 32000 };
|
||||
|
||||
/*******************************************************/
|
||||
/* layer 2 tables */
|
||||
|
||||
const int ff_mpa_sblimit_table[5] = { 27 , 30 , 8, 12 , 30 };
|
||||
|
||||
const int ff_mpa_quant_steps[17] = {
|
||||
3, 5, 7, 9, 15,
|
||||
31, 63, 127, 255, 511,
|
||||
1023, 2047, 4095, 8191, 16383,
|
||||
32767, 65535
|
||||
};
|
||||
|
||||
/* we use a negative value if grouped */
|
||||
const int ff_mpa_quant_bits[17] = {
|
||||
-5, -7, 3, -10, 4,
|
||||
5, 6, 7, 8, 9,
|
||||
10, 11, 12, 13, 14,
|
||||
15, 16
|
||||
};
|
||||
|
||||
/* encoding tables which give the quantization index. Note how it is
|
||||
possible to store them efficiently ! */
|
||||
static const unsigned char alloc_table_1[] = {
|
||||
4, 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
|
||||
4, 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
|
||||
4, 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
|
||||
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
|
||||
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
|
||||
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
|
||||
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
|
||||
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
|
||||
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
|
||||
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
|
||||
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16,
|
||||
3, 0, 1, 2, 3, 4, 5, 16,
|
||||
3, 0, 1, 2, 3, 4, 5, 16,
|
||||
3, 0, 1, 2, 3, 4, 5, 16,
|
||||
3, 0, 1, 2, 3, 4, 5, 16,
|
||||
3, 0, 1, 2, 3, 4, 5, 16,
|
||||
3, 0, 1, 2, 3, 4, 5, 16,
|
||||
3, 0, 1, 2, 3, 4, 5, 16,
|
||||
3, 0, 1, 2, 3, 4, 5, 16,
|
||||
3, 0, 1, 2, 3, 4, 5, 16,
|
||||
3, 0, 1, 2, 3, 4, 5, 16,
|
||||
3, 0, 1, 2, 3, 4, 5, 16,
|
||||
3, 0, 1, 2, 3, 4, 5, 16,
|
||||
2, 0, 1, 16,
|
||||
2, 0, 1, 16,
|
||||
2, 0, 1, 16,
|
||||
2, 0, 1, 16,
|
||||
2, 0, 1, 16,
|
||||
2, 0, 1, 16,
|
||||
2, 0, 1, 16,
|
||||
};
|
||||
|
||||
static const unsigned char alloc_table_3[] = {
|
||||
4, 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
4, 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
3, 0, 1, 3, 4, 5, 6, 7,
|
||||
3, 0, 1, 3, 4, 5, 6, 7,
|
||||
3, 0, 1, 3, 4, 5, 6, 7,
|
||||
3, 0, 1, 3, 4, 5, 6, 7,
|
||||
3, 0, 1, 3, 4, 5, 6, 7,
|
||||
3, 0, 1, 3, 4, 5, 6, 7,
|
||||
3, 0, 1, 3, 4, 5, 6, 7,
|
||||
3, 0, 1, 3, 4, 5, 6, 7,
|
||||
3, 0, 1, 3, 4, 5, 6, 7,
|
||||
3, 0, 1, 3, 4, 5, 6, 7,
|
||||
};
|
||||
|
||||
static const unsigned char alloc_table_4[] = {
|
||||
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||
4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
|
||||
3, 0, 1, 3, 4, 5, 6, 7,
|
||||
3, 0, 1, 3, 4, 5, 6, 7,
|
||||
3, 0, 1, 3, 4, 5, 6, 7,
|
||||
3, 0, 1, 3, 4, 5, 6, 7,
|
||||
3, 0, 1, 3, 4, 5, 6, 7,
|
||||
3, 0, 1, 3, 4, 5, 6, 7,
|
||||
3, 0, 1, 3, 4, 5, 6, 7,
|
||||
2, 0, 1, 3,
|
||||
2, 0, 1, 3,
|
||||
2, 0, 1, 3,
|
||||
2, 0, 1, 3,
|
||||
2, 0, 1, 3,
|
||||
2, 0, 1, 3,
|
||||
2, 0, 1, 3,
|
||||
2, 0, 1, 3,
|
||||
2, 0, 1, 3,
|
||||
2, 0, 1, 3,
|
||||
2, 0, 1, 3,
|
||||
2, 0, 1, 3,
|
||||
2, 0, 1, 3,
|
||||
2, 0, 1, 3,
|
||||
2, 0, 1, 3,
|
||||
2, 0, 1, 3,
|
||||
2, 0, 1, 3,
|
||||
2, 0, 1, 3,
|
||||
2, 0, 1, 3,
|
||||
};
|
||||
|
||||
const unsigned char * const ff_mpa_alloc_tables[5] =
|
||||
{ alloc_table_1, alloc_table_1, alloc_table_3, alloc_table_3, alloc_table_4, };
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* MPEG Audio common tables
|
||||
* 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
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* mpeg audio layer common tables.
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_MPEGAUDIODATA_H
|
||||
#define AVCODEC_MPEGAUDIODATA_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "libavutil/internal.h"
|
||||
|
||||
#define MODE_EXT_MS_STEREO 2
|
||||
#define MODE_EXT_I_STEREO 1
|
||||
|
||||
extern av_export const uint16_t avpriv_mpa_bitrate_tab[2][3][15];
|
||||
extern av_export const uint16_t avpriv_mpa_freq_tab[3];
|
||||
extern const int ff_mpa_sblimit_table[5];
|
||||
extern const int ff_mpa_quant_steps[17];
|
||||
extern const int ff_mpa_quant_bits[17];
|
||||
extern const unsigned char * const ff_mpa_alloc_tables[5];
|
||||
|
||||
#endif /* AVCODEC_MPEGAUDIODATA_H */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* Float MPEG Audio decoder
|
||||
* Copyright (c) 2010 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
|
||||
*/
|
||||
|
||||
#define CONFIG_FLOAT 1
|
||||
#include "mpegaudiodec.c"
|
||||
|
||||
#if CONFIG_MP1FLOAT_DECODER
|
||||
AVCodec ff_mp1float_decoder = {
|
||||
.name = "mp1float",
|
||||
.long_name = NULL_IF_CONFIG_SMALL("MP1 (MPEG audio layer 1)"),
|
||||
.type = AVMEDIA_TYPE_AUDIO,
|
||||
.id = AV_CODEC_ID_MP1,
|
||||
.priv_data_size = sizeof(MPADecodeContext),
|
||||
.init = decode_init,
|
||||
.decode = decode_frame,
|
||||
.capabilities = CODEC_CAP_DR1,
|
||||
.flush = flush,
|
||||
.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
|
||||
AV_SAMPLE_FMT_FLT,
|
||||
AV_SAMPLE_FMT_NONE },
|
||||
};
|
||||
#endif
|
||||
#if CONFIG_MP2FLOAT_DECODER
|
||||
AVCodec ff_mp2float_decoder = {
|
||||
.name = "mp2float",
|
||||
.long_name = NULL_IF_CONFIG_SMALL("MP2 (MPEG audio layer 2)"),
|
||||
.type = AVMEDIA_TYPE_AUDIO,
|
||||
.id = AV_CODEC_ID_MP2,
|
||||
.priv_data_size = sizeof(MPADecodeContext),
|
||||
.init = decode_init,
|
||||
.decode = decode_frame,
|
||||
.capabilities = CODEC_CAP_DR1,
|
||||
.flush = flush,
|
||||
.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
|
||||
AV_SAMPLE_FMT_FLT,
|
||||
AV_SAMPLE_FMT_NONE },
|
||||
};
|
||||
#endif
|
||||
#if CONFIG_MP3FLOAT_DECODER
|
||||
AVCodec ff_mp3float_decoder = {
|
||||
.name = "mp3float",
|
||||
.long_name = NULL_IF_CONFIG_SMALL("MP3 (MPEG audio layer 3)"),
|
||||
.type = AVMEDIA_TYPE_AUDIO,
|
||||
.id = AV_CODEC_ID_MP3,
|
||||
.priv_data_size = sizeof(MPADecodeContext),
|
||||
.init = decode_init,
|
||||
.decode = decode_frame,
|
||||
.capabilities = CODEC_CAP_DR1,
|
||||
.flush = flush,
|
||||
.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
|
||||
AV_SAMPLE_FMT_FLT,
|
||||
AV_SAMPLE_FMT_NONE },
|
||||
};
|
||||
#endif
|
||||
#if CONFIG_MP3ADUFLOAT_DECODER
|
||||
AVCodec ff_mp3adufloat_decoder = {
|
||||
.name = "mp3adufloat",
|
||||
.long_name = NULL_IF_CONFIG_SMALL("ADU (Application Data Unit) MP3 (MPEG audio layer 3)"),
|
||||
.type = AVMEDIA_TYPE_AUDIO,
|
||||
.id = AV_CODEC_ID_MP3ADU,
|
||||
.priv_data_size = sizeof(MPADecodeContext),
|
||||
.init = decode_init,
|
||||
.decode = decode_frame_adu,
|
||||
.capabilities = CODEC_CAP_DR1,
|
||||
.flush = flush,
|
||||
.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
|
||||
AV_SAMPLE_FMT_FLT,
|
||||
AV_SAMPLE_FMT_NONE },
|
||||
};
|
||||
#endif
|
||||
#if CONFIG_MP3ON4FLOAT_DECODER
|
||||
AVCodec ff_mp3on4float_decoder = {
|
||||
.name = "mp3on4float",
|
||||
.long_name = NULL_IF_CONFIG_SMALL("MP3onMP4"),
|
||||
.type = AVMEDIA_TYPE_AUDIO,
|
||||
.id = AV_CODEC_ID_MP3ON4,
|
||||
.priv_data_size = sizeof(MP3On4DecodeContext),
|
||||
.init = decode_init_mp3on4,
|
||||
.close = decode_close_mp3on4,
|
||||
.decode = decode_frame_mp3on4,
|
||||
.capabilities = CODEC_CAP_DR1,
|
||||
.flush = flush_mp3on4,
|
||||
.sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP,
|
||||
AV_SAMPLE_FMT_NONE },
|
||||
};
|
||||
#endif
|
|
@ -0,0 +1,145 @@
|
|||
/*
|
||||
* MPEG Audio header decoder
|
||||
* Copyright (c) 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
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* MPEG Audio header decoder.
|
||||
*/
|
||||
|
||||
#include "avcodec.h"
|
||||
#include "mpegaudio.h"
|
||||
#include "mpegaudiodata.h"
|
||||
#include "mpegaudiodecheader.h"
|
||||
|
||||
|
||||
int avpriv_mpegaudio_decode_header(MPADecodeHeader *s, uint32_t header)
|
||||
{
|
||||
int sample_rate, frame_size, mpeg25, padding;
|
||||
int sample_rate_index, bitrate_index;
|
||||
if (header & (1<<20)) {
|
||||
s->lsf = (header & (1<<19)) ? 0 : 1;
|
||||
mpeg25 = 0;
|
||||
} else {
|
||||
s->lsf = 1;
|
||||
mpeg25 = 1;
|
||||
}
|
||||
|
||||
s->layer = 4 - ((header >> 17) & 3);
|
||||
/* extract frequency */
|
||||
sample_rate_index = (header >> 10) & 3;
|
||||
sample_rate = avpriv_mpa_freq_tab[sample_rate_index] >> (s->lsf + mpeg25);
|
||||
sample_rate_index += 3 * (s->lsf + mpeg25);
|
||||
s->sample_rate_index = sample_rate_index;
|
||||
s->error_protection = ((header >> 16) & 1) ^ 1;
|
||||
s->sample_rate = sample_rate;
|
||||
|
||||
bitrate_index = (header >> 12) & 0xf;
|
||||
padding = (header >> 9) & 1;
|
||||
//extension = (header >> 8) & 1;
|
||||
s->mode = (header >> 6) & 3;
|
||||
s->mode_ext = (header >> 4) & 3;
|
||||
//copyright = (header >> 3) & 1;
|
||||
//original = (header >> 2) & 1;
|
||||
//emphasis = header & 3;
|
||||
|
||||
if (s->mode == MPA_MONO)
|
||||
s->nb_channels = 1;
|
||||
else
|
||||
s->nb_channels = 2;
|
||||
|
||||
if (bitrate_index != 0) {
|
||||
frame_size = avpriv_mpa_bitrate_tab[s->lsf][s->layer - 1][bitrate_index];
|
||||
s->bit_rate = frame_size * 1000;
|
||||
switch(s->layer) {
|
||||
case 1:
|
||||
frame_size = (frame_size * 12000) / sample_rate;
|
||||
frame_size = (frame_size + padding) * 4;
|
||||
break;
|
||||
case 2:
|
||||
frame_size = (frame_size * 144000) / sample_rate;
|
||||
frame_size += padding;
|
||||
break;
|
||||
default:
|
||||
case 3:
|
||||
frame_size = (frame_size * 144000) / (sample_rate << s->lsf);
|
||||
frame_size += padding;
|
||||
break;
|
||||
}
|
||||
s->frame_size = frame_size;
|
||||
} else {
|
||||
/* if no frame size computed, signal it */
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if defined(DEBUG)
|
||||
av_dlog(NULL, "layer%d, %d Hz, %d kbits/s, ",
|
||||
s->layer, s->sample_rate, s->bit_rate);
|
||||
if (s->nb_channels == 2) {
|
||||
if (s->layer == 3) {
|
||||
if (s->mode_ext & MODE_EXT_MS_STEREO)
|
||||
av_dlog(NULL, "ms-");
|
||||
if (s->mode_ext & MODE_EXT_I_STEREO)
|
||||
av_dlog(NULL, "i-");
|
||||
}
|
||||
av_dlog(NULL, "stereo");
|
||||
} else {
|
||||
av_dlog(NULL, "mono");
|
||||
}
|
||||
av_dlog(NULL, "\n");
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int avpriv_mpa_decode_header(AVCodecContext *avctx, uint32_t head, int *sample_rate, int *channels, int *frame_size, int *bit_rate)
|
||||
{
|
||||
MPADecodeHeader s1, *s = &s1;
|
||||
|
||||
if (ff_mpa_check_header(head) != 0)
|
||||
return -1;
|
||||
|
||||
if (avpriv_mpegaudio_decode_header(s, head) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch(s->layer) {
|
||||
case 1:
|
||||
avctx->codec_id = AV_CODEC_ID_MP1;
|
||||
*frame_size = 384;
|
||||
break;
|
||||
case 2:
|
||||
avctx->codec_id = AV_CODEC_ID_MP2;
|
||||
*frame_size = 1152;
|
||||
break;
|
||||
default:
|
||||
case 3:
|
||||
avctx->codec_id = AV_CODEC_ID_MP3;
|
||||
if (s->lsf)
|
||||
*frame_size = 576;
|
||||
else
|
||||
*frame_size = 1152;
|
||||
break;
|
||||
}
|
||||
|
||||
*sample_rate = s->sample_rate;
|
||||
*channels = s->nb_channels;
|
||||
*bit_rate = s->bit_rate;
|
||||
return s->frame_size;
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* MPEG Audio header decoder
|
||||
* Copyright (c) 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
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* MPEG Audio header decoder.
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_MPEGAUDIODECHEADER_H
|
||||
#define AVCODEC_MPEGAUDIODECHEADER_H
|
||||
|
||||
#include "avcodec.h"
|
||||
|
||||
#define MP3_MASK 0xFFFE0CCF
|
||||
|
||||
#define MPA_DECODE_HEADER \
|
||||
int frame_size; \
|
||||
int error_protection; \
|
||||
int layer; \
|
||||
int sample_rate; \
|
||||
int sample_rate_index; /* between 0 and 8 */ \
|
||||
int bit_rate; \
|
||||
int nb_channels; \
|
||||
int mode; \
|
||||
int mode_ext; \
|
||||
int lsf;
|
||||
|
||||
typedef struct MPADecodeHeader {
|
||||
MPA_DECODE_HEADER
|
||||
} MPADecodeHeader;
|
||||
|
||||
/* header decoding. MUST check the header before because no
|
||||
consistency check is done there. Return 1 if free format found and
|
||||
that the frame size must be computed externally */
|
||||
int avpriv_mpegaudio_decode_header(MPADecodeHeader *s, uint32_t header);
|
||||
|
||||
/* useful helper to get mpeg audio stream infos. Return -1 if error in
|
||||
header, otherwise the coded frame size in bytes */
|
||||
int avpriv_mpa_decode_header(AVCodecContext *avctx, uint32_t head, int *sample_rate, int *channels, int *frame_size, int *bitrate);
|
||||
|
||||
/* fast header check for resync */
|
||||
static inline int ff_mpa_check_header(uint32_t header){
|
||||
/* header */
|
||||
if ((header & 0xffe00000) != 0xffe00000)
|
||||
return -1;
|
||||
/* layer check */
|
||||
if ((header & (3<<17)) == 0)
|
||||
return -1;
|
||||
/* bit rate */
|
||||
if ((header & (0xf<<12)) == 0xf<<12)
|
||||
return -1;
|
||||
/* frequency */
|
||||
if ((header & (3<<10)) == 3<<10)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* AVCODEC_MPEGAUDIODECHEADER_H */
|
|
@ -0,0 +1,615 @@
|
|||
/*
|
||||
* MPEG Audio decoder
|
||||
* 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
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* mpeg audio layer decoder tables.
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_MPEGAUDIODECTAB_H
|
||||
#define AVCODEC_MPEGAUDIODECTAB_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "mpegaudio.h"
|
||||
|
||||
/*******************************************************/
|
||||
/* layer 3 tables */
|
||||
|
||||
/* layer 3 huffman tables */
|
||||
typedef struct HuffTable {
|
||||
int xsize;
|
||||
const uint8_t *bits;
|
||||
const uint16_t *codes;
|
||||
} HuffTable;
|
||||
|
||||
/* layer3 scale factor size */
|
||||
static const uint8_t slen_table[2][16] = {
|
||||
{ 0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4 },
|
||||
{ 0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3 },
|
||||
};
|
||||
|
||||
/* number of lsf scale factors for a given size */
|
||||
static const uint8_t lsf_nsf_table[6][3][4] = {
|
||||
{ { 6, 5, 5, 5 }, { 9, 9, 9, 9 }, { 6, 9, 9, 9 } },
|
||||
{ { 6, 5, 7, 3 }, { 9, 9, 12, 6 }, { 6, 9, 12, 6 } },
|
||||
{ { 11, 10, 0, 0 }, { 18, 18, 0, 0 }, { 15, 18, 0, 0 } },
|
||||
{ { 7, 7, 7, 0 }, { 12, 12, 12, 0 }, { 6, 15, 12, 0 } },
|
||||
{ { 6, 6, 6, 3 }, { 12, 9, 9, 6 }, { 6, 12, 9, 6 } },
|
||||
{ { 8, 8, 5, 0 }, { 15, 12, 9, 0 }, { 6, 18, 9, 0 } },
|
||||
};
|
||||
|
||||
/* mpegaudio layer 3 huffman tables */
|
||||
|
||||
static const uint16_t mpa_huffcodes_1[4] = {
|
||||
0x0001, 0x0001, 0x0001, 0x0000,
|
||||
};
|
||||
|
||||
static const uint8_t mpa_huffbits_1[4] = {
|
||||
1, 3, 2, 3,
|
||||
};
|
||||
|
||||
static const uint16_t mpa_huffcodes_2[9] = {
|
||||
0x0001, 0x0002, 0x0001, 0x0003, 0x0001, 0x0001, 0x0003, 0x0002,
|
||||
0x0000,
|
||||
};
|
||||
|
||||
static const uint8_t mpa_huffbits_2[9] = {
|
||||
1, 3, 6, 3, 3, 5, 5, 5,
|
||||
6,
|
||||
};
|
||||
|
||||
static const uint16_t mpa_huffcodes_3[9] = {
|
||||
0x0003, 0x0002, 0x0001, 0x0001, 0x0001, 0x0001, 0x0003, 0x0002,
|
||||
0x0000,
|
||||
};
|
||||
|
||||
static const uint8_t mpa_huffbits_3[9] = {
|
||||
2, 2, 6, 3, 2, 5, 5, 5,
|
||||
6,
|
||||
};
|
||||
|
||||
static const uint16_t mpa_huffcodes_5[16] = {
|
||||
0x0001, 0x0002, 0x0006, 0x0005, 0x0003, 0x0001, 0x0004, 0x0004,
|
||||
0x0007, 0x0005, 0x0007, 0x0001, 0x0006, 0x0001, 0x0001, 0x0000,
|
||||
};
|
||||
|
||||
static const uint8_t mpa_huffbits_5[16] = {
|
||||
1, 3, 6, 7, 3, 3, 6, 7,
|
||||
6, 6, 7, 8, 7, 6, 7, 8,
|
||||
};
|
||||
|
||||
static const uint16_t mpa_huffcodes_6[16] = {
|
||||
0x0007, 0x0003, 0x0005, 0x0001, 0x0006, 0x0002, 0x0003, 0x0002,
|
||||
0x0005, 0x0004, 0x0004, 0x0001, 0x0003, 0x0003, 0x0002, 0x0000,
|
||||
};
|
||||
|
||||
static const uint8_t mpa_huffbits_6[16] = {
|
||||
3, 3, 5, 7, 3, 2, 4, 5,
|
||||
4, 4, 5, 6, 6, 5, 6, 7,
|
||||
};
|
||||
|
||||
static const uint16_t mpa_huffcodes_7[36] = {
|
||||
0x0001, 0x0002, 0x000a, 0x0013, 0x0010, 0x000a, 0x0003, 0x0003,
|
||||
0x0007, 0x000a, 0x0005, 0x0003, 0x000b, 0x0004, 0x000d, 0x0011,
|
||||
0x0008, 0x0004, 0x000c, 0x000b, 0x0012, 0x000f, 0x000b, 0x0002,
|
||||
0x0007, 0x0006, 0x0009, 0x000e, 0x0003, 0x0001, 0x0006, 0x0004,
|
||||
0x0005, 0x0003, 0x0002, 0x0000,
|
||||
};
|
||||
|
||||
static const uint8_t mpa_huffbits_7[36] = {
|
||||
1, 3, 6, 8, 8, 9, 3, 4,
|
||||
6, 7, 7, 8, 6, 5, 7, 8,
|
||||
8, 9, 7, 7, 8, 9, 9, 9,
|
||||
7, 7, 8, 9, 9, 10, 8, 8,
|
||||
9, 10, 10, 10,
|
||||
};
|
||||
|
||||
static const uint16_t mpa_huffcodes_8[36] = {
|
||||
0x0003, 0x0004, 0x0006, 0x0012, 0x000c, 0x0005, 0x0005, 0x0001,
|
||||
0x0002, 0x0010, 0x0009, 0x0003, 0x0007, 0x0003, 0x0005, 0x000e,
|
||||
0x0007, 0x0003, 0x0013, 0x0011, 0x000f, 0x000d, 0x000a, 0x0004,
|
||||
0x000d, 0x0005, 0x0008, 0x000b, 0x0005, 0x0001, 0x000c, 0x0004,
|
||||
0x0004, 0x0001, 0x0001, 0x0000,
|
||||
};
|
||||
|
||||
static const uint8_t mpa_huffbits_8[36] = {
|
||||
2, 3, 6, 8, 8, 9, 3, 2,
|
||||
4, 8, 8, 8, 6, 4, 6, 8,
|
||||
8, 9, 8, 8, 8, 9, 9, 10,
|
||||
8, 7, 8, 9, 10, 10, 9, 8,
|
||||
9, 9, 11, 11,
|
||||
};
|
||||
|
||||
static const uint16_t mpa_huffcodes_9[36] = {
|
||||
0x0007, 0x0005, 0x0009, 0x000e, 0x000f, 0x0007, 0x0006, 0x0004,
|
||||
0x0005, 0x0005, 0x0006, 0x0007, 0x0007, 0x0006, 0x0008, 0x0008,
|
||||
0x0008, 0x0005, 0x000f, 0x0006, 0x0009, 0x000a, 0x0005, 0x0001,
|
||||
0x000b, 0x0007, 0x0009, 0x0006, 0x0004, 0x0001, 0x000e, 0x0004,
|
||||
0x0006, 0x0002, 0x0006, 0x0000,
|
||||
};
|
||||
|
||||
static const uint8_t mpa_huffbits_9[36] = {
|
||||
3, 3, 5, 6, 8, 9, 3, 3,
|
||||
4, 5, 6, 8, 4, 4, 5, 6,
|
||||
7, 8, 6, 5, 6, 7, 7, 8,
|
||||
7, 6, 7, 7, 8, 9, 8, 7,
|
||||
8, 8, 9, 9,
|
||||
};
|
||||
|
||||
static const uint16_t mpa_huffcodes_10[64] = {
|
||||
0x0001, 0x0002, 0x000a, 0x0017, 0x0023, 0x001e, 0x000c, 0x0011,
|
||||
0x0003, 0x0003, 0x0008, 0x000c, 0x0012, 0x0015, 0x000c, 0x0007,
|
||||
0x000b, 0x0009, 0x000f, 0x0015, 0x0020, 0x0028, 0x0013, 0x0006,
|
||||
0x000e, 0x000d, 0x0016, 0x0022, 0x002e, 0x0017, 0x0012, 0x0007,
|
||||
0x0014, 0x0013, 0x0021, 0x002f, 0x001b, 0x0016, 0x0009, 0x0003,
|
||||
0x001f, 0x0016, 0x0029, 0x001a, 0x0015, 0x0014, 0x0005, 0x0003,
|
||||
0x000e, 0x000d, 0x000a, 0x000b, 0x0010, 0x0006, 0x0005, 0x0001,
|
||||
0x0009, 0x0008, 0x0007, 0x0008, 0x0004, 0x0004, 0x0002, 0x0000,
|
||||
};
|
||||
|
||||
static const uint8_t mpa_huffbits_10[64] = {
|
||||
1, 3, 6, 8, 9, 9, 9, 10,
|
||||
3, 4, 6, 7, 8, 9, 8, 8,
|
||||
6, 6, 7, 8, 9, 10, 9, 9,
|
||||
7, 7, 8, 9, 10, 10, 9, 10,
|
||||
8, 8, 9, 10, 10, 10, 10, 10,
|
||||
9, 9, 10, 10, 11, 11, 10, 11,
|
||||
8, 8, 9, 10, 10, 10, 11, 11,
|
||||
9, 8, 9, 10, 10, 11, 11, 11,
|
||||
};
|
||||
|
||||
static const uint16_t mpa_huffcodes_11[64] = {
|
||||
0x0003, 0x0004, 0x000a, 0x0018, 0x0022, 0x0021, 0x0015, 0x000f,
|
||||
0x0005, 0x0003, 0x0004, 0x000a, 0x0020, 0x0011, 0x000b, 0x000a,
|
||||
0x000b, 0x0007, 0x000d, 0x0012, 0x001e, 0x001f, 0x0014, 0x0005,
|
||||
0x0019, 0x000b, 0x0013, 0x003b, 0x001b, 0x0012, 0x000c, 0x0005,
|
||||
0x0023, 0x0021, 0x001f, 0x003a, 0x001e, 0x0010, 0x0007, 0x0005,
|
||||
0x001c, 0x001a, 0x0020, 0x0013, 0x0011, 0x000f, 0x0008, 0x000e,
|
||||
0x000e, 0x000c, 0x0009, 0x000d, 0x000e, 0x0009, 0x0004, 0x0001,
|
||||
0x000b, 0x0004, 0x0006, 0x0006, 0x0006, 0x0003, 0x0002, 0x0000,
|
||||
};
|
||||
|
||||
static const uint8_t mpa_huffbits_11[64] = {
|
||||
2, 3, 5, 7, 8, 9, 8, 9,
|
||||
3, 3, 4, 6, 8, 8, 7, 8,
|
||||
5, 5, 6, 7, 8, 9, 8, 8,
|
||||
7, 6, 7, 9, 8, 10, 8, 9,
|
||||
8, 8, 8, 9, 9, 10, 9, 10,
|
||||
8, 8, 9, 10, 10, 11, 10, 11,
|
||||
8, 7, 7, 8, 9, 10, 10, 10,
|
||||
8, 7, 8, 9, 10, 10, 10, 10,
|
||||
};
|
||||
|
||||
static const uint16_t mpa_huffcodes_12[64] = {
|
||||
0x0009, 0x0006, 0x0010, 0x0021, 0x0029, 0x0027, 0x0026, 0x001a,
|
||||
0x0007, 0x0005, 0x0006, 0x0009, 0x0017, 0x0010, 0x001a, 0x000b,
|
||||
0x0011, 0x0007, 0x000b, 0x000e, 0x0015, 0x001e, 0x000a, 0x0007,
|
||||
0x0011, 0x000a, 0x000f, 0x000c, 0x0012, 0x001c, 0x000e, 0x0005,
|
||||
0x0020, 0x000d, 0x0016, 0x0013, 0x0012, 0x0010, 0x0009, 0x0005,
|
||||
0x0028, 0x0011, 0x001f, 0x001d, 0x0011, 0x000d, 0x0004, 0x0002,
|
||||
0x001b, 0x000c, 0x000b, 0x000f, 0x000a, 0x0007, 0x0004, 0x0001,
|
||||
0x001b, 0x000c, 0x0008, 0x000c, 0x0006, 0x0003, 0x0001, 0x0000,
|
||||
};
|
||||
|
||||
static const uint8_t mpa_huffbits_12[64] = {
|
||||
4, 3, 5, 7, 8, 9, 9, 9,
|
||||
3, 3, 4, 5, 7, 7, 8, 8,
|
||||
5, 4, 5, 6, 7, 8, 7, 8,
|
||||
6, 5, 6, 6, 7, 8, 8, 8,
|
||||
7, 6, 7, 7, 8, 8, 8, 9,
|
||||
8, 7, 8, 8, 8, 9, 8, 9,
|
||||
8, 7, 7, 8, 8, 9, 9, 10,
|
||||
9, 8, 8, 9, 9, 9, 9, 10,
|
||||
};
|
||||
|
||||
static const uint16_t mpa_huffcodes_13[256] = {
|
||||
0x0001, 0x0005, 0x000e, 0x0015, 0x0022, 0x0033, 0x002e, 0x0047,
|
||||
0x002a, 0x0034, 0x0044, 0x0034, 0x0043, 0x002c, 0x002b, 0x0013,
|
||||
0x0003, 0x0004, 0x000c, 0x0013, 0x001f, 0x001a, 0x002c, 0x0021,
|
||||
0x001f, 0x0018, 0x0020, 0x0018, 0x001f, 0x0023, 0x0016, 0x000e,
|
||||
0x000f, 0x000d, 0x0017, 0x0024, 0x003b, 0x0031, 0x004d, 0x0041,
|
||||
0x001d, 0x0028, 0x001e, 0x0028, 0x001b, 0x0021, 0x002a, 0x0010,
|
||||
0x0016, 0x0014, 0x0025, 0x003d, 0x0038, 0x004f, 0x0049, 0x0040,
|
||||
0x002b, 0x004c, 0x0038, 0x0025, 0x001a, 0x001f, 0x0019, 0x000e,
|
||||
0x0023, 0x0010, 0x003c, 0x0039, 0x0061, 0x004b, 0x0072, 0x005b,
|
||||
0x0036, 0x0049, 0x0037, 0x0029, 0x0030, 0x0035, 0x0017, 0x0018,
|
||||
0x003a, 0x001b, 0x0032, 0x0060, 0x004c, 0x0046, 0x005d, 0x0054,
|
||||
0x004d, 0x003a, 0x004f, 0x001d, 0x004a, 0x0031, 0x0029, 0x0011,
|
||||
0x002f, 0x002d, 0x004e, 0x004a, 0x0073, 0x005e, 0x005a, 0x004f,
|
||||
0x0045, 0x0053, 0x0047, 0x0032, 0x003b, 0x0026, 0x0024, 0x000f,
|
||||
0x0048, 0x0022, 0x0038, 0x005f, 0x005c, 0x0055, 0x005b, 0x005a,
|
||||
0x0056, 0x0049, 0x004d, 0x0041, 0x0033, 0x002c, 0x002b, 0x002a,
|
||||
0x002b, 0x0014, 0x001e, 0x002c, 0x0037, 0x004e, 0x0048, 0x0057,
|
||||
0x004e, 0x003d, 0x002e, 0x0036, 0x0025, 0x001e, 0x0014, 0x0010,
|
||||
0x0035, 0x0019, 0x0029, 0x0025, 0x002c, 0x003b, 0x0036, 0x0051,
|
||||
0x0042, 0x004c, 0x0039, 0x0036, 0x0025, 0x0012, 0x0027, 0x000b,
|
||||
0x0023, 0x0021, 0x001f, 0x0039, 0x002a, 0x0052, 0x0048, 0x0050,
|
||||
0x002f, 0x003a, 0x0037, 0x0015, 0x0016, 0x001a, 0x0026, 0x0016,
|
||||
0x0035, 0x0019, 0x0017, 0x0026, 0x0046, 0x003c, 0x0033, 0x0024,
|
||||
0x0037, 0x001a, 0x0022, 0x0017, 0x001b, 0x000e, 0x0009, 0x0007,
|
||||
0x0022, 0x0020, 0x001c, 0x0027, 0x0031, 0x004b, 0x001e, 0x0034,
|
||||
0x0030, 0x0028, 0x0034, 0x001c, 0x0012, 0x0011, 0x0009, 0x0005,
|
||||
0x002d, 0x0015, 0x0022, 0x0040, 0x0038, 0x0032, 0x0031, 0x002d,
|
||||
0x001f, 0x0013, 0x000c, 0x000f, 0x000a, 0x0007, 0x0006, 0x0003,
|
||||
0x0030, 0x0017, 0x0014, 0x0027, 0x0024, 0x0023, 0x0035, 0x0015,
|
||||
0x0010, 0x0017, 0x000d, 0x000a, 0x0006, 0x0001, 0x0004, 0x0002,
|
||||
0x0010, 0x000f, 0x0011, 0x001b, 0x0019, 0x0014, 0x001d, 0x000b,
|
||||
0x0011, 0x000c, 0x0010, 0x0008, 0x0001, 0x0001, 0x0000, 0x0001,
|
||||
};
|
||||
|
||||
static const uint8_t mpa_huffbits_13[256] = {
|
||||
1, 4, 6, 7, 8, 9, 9, 10,
|
||||
9, 10, 11, 11, 12, 12, 13, 13,
|
||||
3, 4, 6, 7, 8, 8, 9, 9,
|
||||
9, 9, 10, 10, 11, 12, 12, 12,
|
||||
6, 6, 7, 8, 9, 9, 10, 10,
|
||||
9, 10, 10, 11, 11, 12, 13, 13,
|
||||
7, 7, 8, 9, 9, 10, 10, 10,
|
||||
10, 11, 11, 11, 11, 12, 13, 13,
|
||||
8, 7, 9, 9, 10, 10, 11, 11,
|
||||
10, 11, 11, 12, 12, 13, 13, 14,
|
||||
9, 8, 9, 10, 10, 10, 11, 11,
|
||||
11, 11, 12, 11, 13, 13, 14, 14,
|
||||
9, 9, 10, 10, 11, 11, 11, 11,
|
||||
11, 12, 12, 12, 13, 13, 14, 14,
|
||||
10, 9, 10, 11, 11, 11, 12, 12,
|
||||
12, 12, 13, 13, 13, 14, 16, 16,
|
||||
9, 8, 9, 10, 10, 11, 11, 12,
|
||||
12, 12, 12, 13, 13, 14, 15, 15,
|
||||
10, 9, 10, 10, 11, 11, 11, 13,
|
||||
12, 13, 13, 14, 14, 14, 16, 15,
|
||||
10, 10, 10, 11, 11, 12, 12, 13,
|
||||
12, 13, 14, 13, 14, 15, 16, 17,
|
||||
11, 10, 10, 11, 12, 12, 12, 12,
|
||||
13, 13, 13, 14, 15, 15, 15, 16,
|
||||
11, 11, 11, 12, 12, 13, 12, 13,
|
||||
14, 14, 15, 15, 15, 16, 16, 16,
|
||||
12, 11, 12, 13, 13, 13, 14, 14,
|
||||
14, 14, 14, 15, 16, 15, 16, 16,
|
||||
13, 12, 12, 13, 13, 13, 15, 14,
|
||||
14, 17, 15, 15, 15, 17, 16, 16,
|
||||
12, 12, 13, 14, 14, 14, 15, 14,
|
||||
15, 15, 16, 16, 19, 18, 19, 16,
|
||||
};
|
||||
|
||||
static const uint16_t mpa_huffcodes_15[256] = {
|
||||
0x0007, 0x000c, 0x0012, 0x0035, 0x002f, 0x004c, 0x007c, 0x006c,
|
||||
0x0059, 0x007b, 0x006c, 0x0077, 0x006b, 0x0051, 0x007a, 0x003f,
|
||||
0x000d, 0x0005, 0x0010, 0x001b, 0x002e, 0x0024, 0x003d, 0x0033,
|
||||
0x002a, 0x0046, 0x0034, 0x0053, 0x0041, 0x0029, 0x003b, 0x0024,
|
||||
0x0013, 0x0011, 0x000f, 0x0018, 0x0029, 0x0022, 0x003b, 0x0030,
|
||||
0x0028, 0x0040, 0x0032, 0x004e, 0x003e, 0x0050, 0x0038, 0x0021,
|
||||
0x001d, 0x001c, 0x0019, 0x002b, 0x0027, 0x003f, 0x0037, 0x005d,
|
||||
0x004c, 0x003b, 0x005d, 0x0048, 0x0036, 0x004b, 0x0032, 0x001d,
|
||||
0x0034, 0x0016, 0x002a, 0x0028, 0x0043, 0x0039, 0x005f, 0x004f,
|
||||
0x0048, 0x0039, 0x0059, 0x0045, 0x0031, 0x0042, 0x002e, 0x001b,
|
||||
0x004d, 0x0025, 0x0023, 0x0042, 0x003a, 0x0034, 0x005b, 0x004a,
|
||||
0x003e, 0x0030, 0x004f, 0x003f, 0x005a, 0x003e, 0x0028, 0x0026,
|
||||
0x007d, 0x0020, 0x003c, 0x0038, 0x0032, 0x005c, 0x004e, 0x0041,
|
||||
0x0037, 0x0057, 0x0047, 0x0033, 0x0049, 0x0033, 0x0046, 0x001e,
|
||||
0x006d, 0x0035, 0x0031, 0x005e, 0x0058, 0x004b, 0x0042, 0x007a,
|
||||
0x005b, 0x0049, 0x0038, 0x002a, 0x0040, 0x002c, 0x0015, 0x0019,
|
||||
0x005a, 0x002b, 0x0029, 0x004d, 0x0049, 0x003f, 0x0038, 0x005c,
|
||||
0x004d, 0x0042, 0x002f, 0x0043, 0x0030, 0x0035, 0x0024, 0x0014,
|
||||
0x0047, 0x0022, 0x0043, 0x003c, 0x003a, 0x0031, 0x0058, 0x004c,
|
||||
0x0043, 0x006a, 0x0047, 0x0036, 0x0026, 0x0027, 0x0017, 0x000f,
|
||||
0x006d, 0x0035, 0x0033, 0x002f, 0x005a, 0x0052, 0x003a, 0x0039,
|
||||
0x0030, 0x0048, 0x0039, 0x0029, 0x0017, 0x001b, 0x003e, 0x0009,
|
||||
0x0056, 0x002a, 0x0028, 0x0025, 0x0046, 0x0040, 0x0034, 0x002b,
|
||||
0x0046, 0x0037, 0x002a, 0x0019, 0x001d, 0x0012, 0x000b, 0x000b,
|
||||
0x0076, 0x0044, 0x001e, 0x0037, 0x0032, 0x002e, 0x004a, 0x0041,
|
||||
0x0031, 0x0027, 0x0018, 0x0010, 0x0016, 0x000d, 0x000e, 0x0007,
|
||||
0x005b, 0x002c, 0x0027, 0x0026, 0x0022, 0x003f, 0x0034, 0x002d,
|
||||
0x001f, 0x0034, 0x001c, 0x0013, 0x000e, 0x0008, 0x0009, 0x0003,
|
||||
0x007b, 0x003c, 0x003a, 0x0035, 0x002f, 0x002b, 0x0020, 0x0016,
|
||||
0x0025, 0x0018, 0x0011, 0x000c, 0x000f, 0x000a, 0x0002, 0x0001,
|
||||
0x0047, 0x0025, 0x0022, 0x001e, 0x001c, 0x0014, 0x0011, 0x001a,
|
||||
0x0015, 0x0010, 0x000a, 0x0006, 0x0008, 0x0006, 0x0002, 0x0000,
|
||||
};
|
||||
|
||||
static const uint8_t mpa_huffbits_15[256] = {
|
||||
3, 4, 5, 7, 7, 8, 9, 9,
|
||||
9, 10, 10, 11, 11, 11, 12, 13,
|
||||
4, 3, 5, 6, 7, 7, 8, 8,
|
||||
8, 9, 9, 10, 10, 10, 11, 11,
|
||||
5, 5, 5, 6, 7, 7, 8, 8,
|
||||
8, 9, 9, 10, 10, 11, 11, 11,
|
||||
6, 6, 6, 7, 7, 8, 8, 9,
|
||||
9, 9, 10, 10, 10, 11, 11, 11,
|
||||
7, 6, 7, 7, 8, 8, 9, 9,
|
||||
9, 9, 10, 10, 10, 11, 11, 11,
|
||||
8, 7, 7, 8, 8, 8, 9, 9,
|
||||
9, 9, 10, 10, 11, 11, 11, 12,
|
||||
9, 7, 8, 8, 8, 9, 9, 9,
|
||||
9, 10, 10, 10, 11, 11, 12, 12,
|
||||
9, 8, 8, 9, 9, 9, 9, 10,
|
||||
10, 10, 10, 10, 11, 11, 11, 12,
|
||||
9, 8, 8, 9, 9, 9, 9, 10,
|
||||
10, 10, 10, 11, 11, 12, 12, 12,
|
||||
9, 8, 9, 9, 9, 9, 10, 10,
|
||||
10, 11, 11, 11, 11, 12, 12, 12,
|
||||
10, 9, 9, 9, 10, 10, 10, 10,
|
||||
10, 11, 11, 11, 11, 12, 13, 12,
|
||||
10, 9, 9, 9, 10, 10, 10, 10,
|
||||
11, 11, 11, 11, 12, 12, 12, 13,
|
||||
11, 10, 9, 10, 10, 10, 11, 11,
|
||||
11, 11, 11, 11, 12, 12, 13, 13,
|
||||
11, 10, 10, 10, 10, 11, 11, 11,
|
||||
11, 12, 12, 12, 12, 12, 13, 13,
|
||||
12, 11, 11, 11, 11, 11, 11, 11,
|
||||
12, 12, 12, 12, 13, 13, 12, 13,
|
||||
12, 11, 11, 11, 11, 11, 11, 12,
|
||||
12, 12, 12, 12, 13, 13, 13, 13,
|
||||
};
|
||||
|
||||
static const uint16_t mpa_huffcodes_16[256] = {
|
||||
0x0001, 0x0005, 0x000e, 0x002c, 0x004a, 0x003f, 0x006e, 0x005d,
|
||||
0x00ac, 0x0095, 0x008a, 0x00f2, 0x00e1, 0x00c3, 0x0178, 0x0011,
|
||||
0x0003, 0x0004, 0x000c, 0x0014, 0x0023, 0x003e, 0x0035, 0x002f,
|
||||
0x0053, 0x004b, 0x0044, 0x0077, 0x00c9, 0x006b, 0x00cf, 0x0009,
|
||||
0x000f, 0x000d, 0x0017, 0x0026, 0x0043, 0x003a, 0x0067, 0x005a,
|
||||
0x00a1, 0x0048, 0x007f, 0x0075, 0x006e, 0x00d1, 0x00ce, 0x0010,
|
||||
0x002d, 0x0015, 0x0027, 0x0045, 0x0040, 0x0072, 0x0063, 0x0057,
|
||||
0x009e, 0x008c, 0x00fc, 0x00d4, 0x00c7, 0x0183, 0x016d, 0x001a,
|
||||
0x004b, 0x0024, 0x0044, 0x0041, 0x0073, 0x0065, 0x00b3, 0x00a4,
|
||||
0x009b, 0x0108, 0x00f6, 0x00e2, 0x018b, 0x017e, 0x016a, 0x0009,
|
||||
0x0042, 0x001e, 0x003b, 0x0038, 0x0066, 0x00b9, 0x00ad, 0x0109,
|
||||
0x008e, 0x00fd, 0x00e8, 0x0190, 0x0184, 0x017a, 0x01bd, 0x0010,
|
||||
0x006f, 0x0036, 0x0034, 0x0064, 0x00b8, 0x00b2, 0x00a0, 0x0085,
|
||||
0x0101, 0x00f4, 0x00e4, 0x00d9, 0x0181, 0x016e, 0x02cb, 0x000a,
|
||||
0x0062, 0x0030, 0x005b, 0x0058, 0x00a5, 0x009d, 0x0094, 0x0105,
|
||||
0x00f8, 0x0197, 0x018d, 0x0174, 0x017c, 0x0379, 0x0374, 0x0008,
|
||||
0x0055, 0x0054, 0x0051, 0x009f, 0x009c, 0x008f, 0x0104, 0x00f9,
|
||||
0x01ab, 0x0191, 0x0188, 0x017f, 0x02d7, 0x02c9, 0x02c4, 0x0007,
|
||||
0x009a, 0x004c, 0x0049, 0x008d, 0x0083, 0x0100, 0x00f5, 0x01aa,
|
||||
0x0196, 0x018a, 0x0180, 0x02df, 0x0167, 0x02c6, 0x0160, 0x000b,
|
||||
0x008b, 0x0081, 0x0043, 0x007d, 0x00f7, 0x00e9, 0x00e5, 0x00db,
|
||||
0x0189, 0x02e7, 0x02e1, 0x02d0, 0x0375, 0x0372, 0x01b7, 0x0004,
|
||||
0x00f3, 0x0078, 0x0076, 0x0073, 0x00e3, 0x00df, 0x018c, 0x02ea,
|
||||
0x02e6, 0x02e0, 0x02d1, 0x02c8, 0x02c2, 0x00df, 0x01b4, 0x0006,
|
||||
0x00ca, 0x00e0, 0x00de, 0x00da, 0x00d8, 0x0185, 0x0182, 0x017d,
|
||||
0x016c, 0x0378, 0x01bb, 0x02c3, 0x01b8, 0x01b5, 0x06c0, 0x0004,
|
||||
0x02eb, 0x00d3, 0x00d2, 0x00d0, 0x0172, 0x017b, 0x02de, 0x02d3,
|
||||
0x02ca, 0x06c7, 0x0373, 0x036d, 0x036c, 0x0d83, 0x0361, 0x0002,
|
||||
0x0179, 0x0171, 0x0066, 0x00bb, 0x02d6, 0x02d2, 0x0166, 0x02c7,
|
||||
0x02c5, 0x0362, 0x06c6, 0x0367, 0x0d82, 0x0366, 0x01b2, 0x0000,
|
||||
0x000c, 0x000a, 0x0007, 0x000b, 0x000a, 0x0011, 0x000b, 0x0009,
|
||||
0x000d, 0x000c, 0x000a, 0x0007, 0x0005, 0x0003, 0x0001, 0x0003,
|
||||
};
|
||||
|
||||
static const uint8_t mpa_huffbits_16[256] = {
|
||||
1, 4, 6, 8, 9, 9, 10, 10,
|
||||
11, 11, 11, 12, 12, 12, 13, 9,
|
||||
3, 4, 6, 7, 8, 9, 9, 9,
|
||||
10, 10, 10, 11, 12, 11, 12, 8,
|
||||
6, 6, 7, 8, 9, 9, 10, 10,
|
||||
11, 10, 11, 11, 11, 12, 12, 9,
|
||||
8, 7, 8, 9, 9, 10, 10, 10,
|
||||
11, 11, 12, 12, 12, 13, 13, 10,
|
||||
9, 8, 9, 9, 10, 10, 11, 11,
|
||||
11, 12, 12, 12, 13, 13, 13, 9,
|
||||
9, 8, 9, 9, 10, 11, 11, 12,
|
||||
11, 12, 12, 13, 13, 13, 14, 10,
|
||||
10, 9, 9, 10, 11, 11, 11, 11,
|
||||
12, 12, 12, 12, 13, 13, 14, 10,
|
||||
10, 9, 10, 10, 11, 11, 11, 12,
|
||||
12, 13, 13, 13, 13, 15, 15, 10,
|
||||
10, 10, 10, 11, 11, 11, 12, 12,
|
||||
13, 13, 13, 13, 14, 14, 14, 10,
|
||||
11, 10, 10, 11, 11, 12, 12, 13,
|
||||
13, 13, 13, 14, 13, 14, 13, 11,
|
||||
11, 11, 10, 11, 12, 12, 12, 12,
|
||||
13, 14, 14, 14, 15, 15, 14, 10,
|
||||
12, 11, 11, 11, 12, 12, 13, 14,
|
||||
14, 14, 14, 14, 14, 13, 14, 11,
|
||||
12, 12, 12, 12, 12, 13, 13, 13,
|
||||
13, 15, 14, 14, 14, 14, 16, 11,
|
||||
14, 12, 12, 12, 13, 13, 14, 14,
|
||||
14, 16, 15, 15, 15, 17, 15, 11,
|
||||
13, 13, 11, 12, 14, 14, 13, 14,
|
||||
14, 15, 16, 15, 17, 15, 14, 11,
|
||||
9, 8, 8, 9, 9, 10, 10, 10,
|
||||
11, 11, 11, 11, 11, 11, 11, 8,
|
||||
};
|
||||
|
||||
static const uint16_t mpa_huffcodes_24[256] = {
|
||||
0x000f, 0x000d, 0x002e, 0x0050, 0x0092, 0x0106, 0x00f8, 0x01b2,
|
||||
0x01aa, 0x029d, 0x028d, 0x0289, 0x026d, 0x0205, 0x0408, 0x0058,
|
||||
0x000e, 0x000c, 0x0015, 0x0026, 0x0047, 0x0082, 0x007a, 0x00d8,
|
||||
0x00d1, 0x00c6, 0x0147, 0x0159, 0x013f, 0x0129, 0x0117, 0x002a,
|
||||
0x002f, 0x0016, 0x0029, 0x004a, 0x0044, 0x0080, 0x0078, 0x00dd,
|
||||
0x00cf, 0x00c2, 0x00b6, 0x0154, 0x013b, 0x0127, 0x021d, 0x0012,
|
||||
0x0051, 0x0027, 0x004b, 0x0046, 0x0086, 0x007d, 0x0074, 0x00dc,
|
||||
0x00cc, 0x00be, 0x00b2, 0x0145, 0x0137, 0x0125, 0x010f, 0x0010,
|
||||
0x0093, 0x0048, 0x0045, 0x0087, 0x007f, 0x0076, 0x0070, 0x00d2,
|
||||
0x00c8, 0x00bc, 0x0160, 0x0143, 0x0132, 0x011d, 0x021c, 0x000e,
|
||||
0x0107, 0x0042, 0x0081, 0x007e, 0x0077, 0x0072, 0x00d6, 0x00ca,
|
||||
0x00c0, 0x00b4, 0x0155, 0x013d, 0x012d, 0x0119, 0x0106, 0x000c,
|
||||
0x00f9, 0x007b, 0x0079, 0x0075, 0x0071, 0x00d7, 0x00ce, 0x00c3,
|
||||
0x00b9, 0x015b, 0x014a, 0x0134, 0x0123, 0x0110, 0x0208, 0x000a,
|
||||
0x01b3, 0x0073, 0x006f, 0x006d, 0x00d3, 0x00cb, 0x00c4, 0x00bb,
|
||||
0x0161, 0x014c, 0x0139, 0x012a, 0x011b, 0x0213, 0x017d, 0x0011,
|
||||
0x01ab, 0x00d4, 0x00d0, 0x00cd, 0x00c9, 0x00c1, 0x00ba, 0x00b1,
|
||||
0x00a9, 0x0140, 0x012f, 0x011e, 0x010c, 0x0202, 0x0179, 0x0010,
|
||||
0x014f, 0x00c7, 0x00c5, 0x00bf, 0x00bd, 0x00b5, 0x00ae, 0x014d,
|
||||
0x0141, 0x0131, 0x0121, 0x0113, 0x0209, 0x017b, 0x0173, 0x000b,
|
||||
0x029c, 0x00b8, 0x00b7, 0x00b3, 0x00af, 0x0158, 0x014b, 0x013a,
|
||||
0x0130, 0x0122, 0x0115, 0x0212, 0x017f, 0x0175, 0x016e, 0x000a,
|
||||
0x028c, 0x015a, 0x00ab, 0x00a8, 0x00a4, 0x013e, 0x0135, 0x012b,
|
||||
0x011f, 0x0114, 0x0107, 0x0201, 0x0177, 0x0170, 0x016a, 0x0006,
|
||||
0x0288, 0x0142, 0x013c, 0x0138, 0x0133, 0x012e, 0x0124, 0x011c,
|
||||
0x010d, 0x0105, 0x0200, 0x0178, 0x0172, 0x016c, 0x0167, 0x0004,
|
||||
0x026c, 0x012c, 0x0128, 0x0126, 0x0120, 0x011a, 0x0111, 0x010a,
|
||||
0x0203, 0x017c, 0x0176, 0x0171, 0x016d, 0x0169, 0x0165, 0x0002,
|
||||
0x0409, 0x0118, 0x0116, 0x0112, 0x010b, 0x0108, 0x0103, 0x017e,
|
||||
0x017a, 0x0174, 0x016f, 0x016b, 0x0168, 0x0166, 0x0164, 0x0000,
|
||||
0x002b, 0x0014, 0x0013, 0x0011, 0x000f, 0x000d, 0x000b, 0x0009,
|
||||
0x0007, 0x0006, 0x0004, 0x0007, 0x0005, 0x0003, 0x0001, 0x0003,
|
||||
};
|
||||
|
||||
static const uint8_t mpa_huffbits_24[256] = {
|
||||
4, 4, 6, 7, 8, 9, 9, 10,
|
||||
10, 11, 11, 11, 11, 11, 12, 9,
|
||||
4, 4, 5, 6, 7, 8, 8, 9,
|
||||
9, 9, 10, 10, 10, 10, 10, 8,
|
||||
6, 5, 6, 7, 7, 8, 8, 9,
|
||||
9, 9, 9, 10, 10, 10, 11, 7,
|
||||
7, 6, 7, 7, 8, 8, 8, 9,
|
||||
9, 9, 9, 10, 10, 10, 10, 7,
|
||||
8, 7, 7, 8, 8, 8, 8, 9,
|
||||
9, 9, 10, 10, 10, 10, 11, 7,
|
||||
9, 7, 8, 8, 8, 8, 9, 9,
|
||||
9, 9, 10, 10, 10, 10, 10, 7,
|
||||
9, 8, 8, 8, 8, 9, 9, 9,
|
||||
9, 10, 10, 10, 10, 10, 11, 7,
|
||||
10, 8, 8, 8, 9, 9, 9, 9,
|
||||
10, 10, 10, 10, 10, 11, 11, 8,
|
||||
10, 9, 9, 9, 9, 9, 9, 9,
|
||||
9, 10, 10, 10, 10, 11, 11, 8,
|
||||
10, 9, 9, 9, 9, 9, 9, 10,
|
||||
10, 10, 10, 10, 11, 11, 11, 8,
|
||||
11, 9, 9, 9, 9, 10, 10, 10,
|
||||
10, 10, 10, 11, 11, 11, 11, 8,
|
||||
11, 10, 9, 9, 9, 10, 10, 10,
|
||||
10, 10, 10, 11, 11, 11, 11, 8,
|
||||
11, 10, 10, 10, 10, 10, 10, 10,
|
||||
10, 10, 11, 11, 11, 11, 11, 8,
|
||||
11, 10, 10, 10, 10, 10, 10, 10,
|
||||
11, 11, 11, 11, 11, 11, 11, 8,
|
||||
12, 10, 10, 10, 10, 10, 10, 11,
|
||||
11, 11, 11, 11, 11, 11, 11, 8,
|
||||
8, 7, 7, 7, 7, 7, 7, 7,
|
||||
7, 7, 7, 8, 8, 8, 8, 4,
|
||||
};
|
||||
|
||||
static const HuffTable mpa_huff_tables[16] = {
|
||||
{ 1, NULL, NULL },
|
||||
{ 2, mpa_huffbits_1, mpa_huffcodes_1 },
|
||||
{ 3, mpa_huffbits_2, mpa_huffcodes_2 },
|
||||
{ 3, mpa_huffbits_3, mpa_huffcodes_3 },
|
||||
{ 4, mpa_huffbits_5, mpa_huffcodes_5 },
|
||||
{ 4, mpa_huffbits_6, mpa_huffcodes_6 },
|
||||
{ 6, mpa_huffbits_7, mpa_huffcodes_7 },
|
||||
{ 6, mpa_huffbits_8, mpa_huffcodes_8 },
|
||||
{ 6, mpa_huffbits_9, mpa_huffcodes_9 },
|
||||
{ 8, mpa_huffbits_10, mpa_huffcodes_10 },
|
||||
{ 8, mpa_huffbits_11, mpa_huffcodes_11 },
|
||||
{ 8, mpa_huffbits_12, mpa_huffcodes_12 },
|
||||
{ 16, mpa_huffbits_13, mpa_huffcodes_13 },
|
||||
{ 16, mpa_huffbits_15, mpa_huffcodes_15 },
|
||||
{ 16, mpa_huffbits_16, mpa_huffcodes_16 },
|
||||
{ 16, mpa_huffbits_24, mpa_huffcodes_24 },
|
||||
};
|
||||
|
||||
static const uint8_t mpa_huff_data[32][2] = {
|
||||
{ 0, 0 },
|
||||
{ 1, 0 },
|
||||
{ 2, 0 },
|
||||
{ 3, 0 },
|
||||
{ 0, 0 },
|
||||
{ 4, 0 },
|
||||
{ 5, 0 },
|
||||
{ 6, 0 },
|
||||
{ 7, 0 },
|
||||
{ 8, 0 },
|
||||
{ 9, 0 },
|
||||
{ 10, 0 },
|
||||
{ 11, 0 },
|
||||
{ 12, 0 },
|
||||
{ 0, 0 },
|
||||
{ 13, 0 },
|
||||
{ 14, 1 },
|
||||
{ 14, 2 },
|
||||
{ 14, 3 },
|
||||
{ 14, 4 },
|
||||
{ 14, 6 },
|
||||
{ 14, 8 },
|
||||
{ 14, 10 },
|
||||
{ 14, 13 },
|
||||
{ 15, 4 },
|
||||
{ 15, 5 },
|
||||
{ 15, 6 },
|
||||
{ 15, 7 },
|
||||
{ 15, 8 },
|
||||
{ 15, 9 },
|
||||
{ 15, 11 },
|
||||
{ 15, 13 },
|
||||
};
|
||||
|
||||
|
||||
/* huffman tables for quadrules */
|
||||
static const uint8_t mpa_quad_codes[2][16] = {
|
||||
{ 1, 5, 4, 5, 6, 5, 4, 4, 7, 3, 6, 0, 7, 2, 3, 1, },
|
||||
{ 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, },
|
||||
};
|
||||
|
||||
static const uint8_t mpa_quad_bits[2][16] = {
|
||||
{ 1, 4, 4, 5, 4, 6, 5, 6, 4, 5, 5, 6, 5, 6, 6, 6, },
|
||||
{ 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, },
|
||||
};
|
||||
|
||||
/* band size tables */
|
||||
static const uint8_t band_size_long[9][22] = {
|
||||
{ 4, 4, 4, 4, 4, 4, 6, 6, 8, 8, 10,
|
||||
12, 16, 20, 24, 28, 34, 42, 50, 54, 76, 158, }, /* 44100 */
|
||||
{ 4, 4, 4, 4, 4, 4, 6, 6, 6, 8, 10,
|
||||
12, 16, 18, 22, 28, 34, 40, 46, 54, 54, 192, }, /* 48000 */
|
||||
{ 4, 4, 4, 4, 4, 4, 6, 6, 8, 10, 12,
|
||||
16, 20, 24, 30, 38, 46, 56, 68, 84, 102, 26, }, /* 32000 */
|
||||
{ 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16,
|
||||
20, 24, 28, 32, 38, 46, 52, 60, 68, 58, 54, }, /* 22050 */
|
||||
{ 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16,
|
||||
18, 22, 26, 32, 38, 46, 52, 64, 70, 76, 36, }, /* 24000 */
|
||||
{ 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16,
|
||||
20, 24, 28, 32, 38, 46, 52, 60, 68, 58, 54, }, /* 16000 */
|
||||
{ 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16,
|
||||
20, 24, 28, 32, 38, 46, 52, 60, 68, 58, 54, }, /* 11025 */
|
||||
{ 6, 6, 6, 6, 6, 6, 8, 10, 12, 14, 16,
|
||||
20, 24, 28, 32, 38, 46, 52, 60, 68, 58, 54, }, /* 12000 */
|
||||
{ 12, 12, 12, 12, 12, 12, 16, 20, 24, 28, 32,
|
||||
40, 48, 56, 64, 76, 90, 2, 2, 2, 2, 2, }, /* 8000 */
|
||||
};
|
||||
|
||||
static const uint8_t band_size_short[9][13] = {
|
||||
{ 4, 4, 4, 4, 6, 8, 10, 12, 14, 18, 22, 30, 56, }, /* 44100 */
|
||||
{ 4, 4, 4, 4, 6, 6, 10, 12, 14, 16, 20, 26, 66, }, /* 48000 */
|
||||
{ 4, 4, 4, 4, 6, 8, 12, 16, 20, 26, 34, 42, 12, }, /* 32000 */
|
||||
{ 4, 4, 4, 6, 6, 8, 10, 14, 18, 26, 32, 42, 18, }, /* 22050 */
|
||||
{ 4, 4, 4, 6, 8, 10, 12, 14, 18, 24, 32, 44, 12, }, /* 24000 */
|
||||
{ 4, 4, 4, 6, 8, 10, 12, 14, 18, 24, 30, 40, 18, }, /* 16000 */
|
||||
{ 4, 4, 4, 6, 8, 10, 12, 14, 18, 24, 30, 40, 18, }, /* 11025 */
|
||||
{ 4, 4, 4, 6, 8, 10, 12, 14, 18, 24, 30, 40, 18, }, /* 12000 */
|
||||
{ 8, 8, 8, 12, 16, 20, 24, 28, 36, 2, 2, 2, 26, }, /* 8000 */
|
||||
};
|
||||
|
||||
static const uint8_t mpa_pretab[2][22] = {
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 3, 3, 2, 0 },
|
||||
};
|
||||
|
||||
/* table for alias reduction (XXX: store it as integer !) */
|
||||
static const float ci_table[8] = {
|
||||
-0.6, -0.535, -0.33, -0.185, -0.095, -0.041, -0.0142, -0.0037,
|
||||
};
|
||||
|
||||
#endif /* AVCODEC_MPEGAUDIODECTAB_H */
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (c) 2011 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 "config.h"
|
||||
#include "libavutil/attributes.h"
|
||||
#include "mpegaudiodsp.h"
|
||||
#include "dct.h"
|
||||
#include "dct32.h"
|
||||
|
||||
av_cold void ff_mpadsp_init(MPADSPContext *s)
|
||||
{
|
||||
DCTContext dct;
|
||||
|
||||
ff_dct_init(&dct, 5, DCT_II);
|
||||
ff_init_mpadsp_tabs_float();
|
||||
ff_init_mpadsp_tabs_fixed();
|
||||
|
||||
s->apply_window_float = ff_mpadsp_apply_window_float;
|
||||
s->apply_window_fixed = ff_mpadsp_apply_window_fixed;
|
||||
|
||||
s->dct32_float = dct.dct32;
|
||||
s->dct32_fixed = ff_dct32_fixed;
|
||||
|
||||
s->imdct36_blocks_float = ff_imdct36_blocks_float;
|
||||
s->imdct36_blocks_fixed = ff_imdct36_blocks_fixed;
|
||||
|
||||
if (ARCH_ARM) ff_mpadsp_init_arm(s);
|
||||
if (ARCH_PPC) ff_mpadsp_init_ppc(s);
|
||||
if (ARCH_X86) ff_mpadsp_init_x86(s);
|
||||
if (HAVE_MIPSFPU) ff_mpadsp_init_mipsfpu(s);
|
||||
if (HAVE_MIPSDSPR1) ff_mpadsp_init_mipsdspr1(s);
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* 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 AVCODEC_MPEGAUDIODSP_H
|
||||
#define AVCODEC_MPEGAUDIODSP_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "libavutil/common.h"
|
||||
|
||||
typedef struct MPADSPContext {
|
||||
void (*apply_window_float)(float *synth_buf, float *window,
|
||||
int *dither_state, float *samples, int incr);
|
||||
void (*apply_window_fixed)(int32_t *synth_buf, int32_t *window,
|
||||
int *dither_state, int16_t *samples, int incr);
|
||||
void (*dct32_float)(float *dst, const float *src);
|
||||
void (*dct32_fixed)(int *dst, const int *src);
|
||||
|
||||
void (*imdct36_blocks_float)(float *out, float *buf, float *in,
|
||||
int count, int switch_point, int block_type);
|
||||
void (*imdct36_blocks_fixed)(int *out, int *buf, int *in,
|
||||
int count, int switch_point, int block_type);
|
||||
} MPADSPContext;
|
||||
|
||||
void ff_mpadsp_init(MPADSPContext *s);
|
||||
|
||||
extern int32_t ff_mpa_synth_window_fixed[];
|
||||
extern float ff_mpa_synth_window_float[];
|
||||
|
||||
extern const int32_t ff_mpa_enwindow[257];
|
||||
|
||||
void ff_mpa_synth_filter_fixed(MPADSPContext *s,
|
||||
int32_t *synth_buf_ptr, int *synth_buf_offset,
|
||||
int32_t *window, int *dither_state,
|
||||
int16_t *samples, int incr,
|
||||
int32_t *sb_samples);
|
||||
|
||||
void ff_mpa_synth_filter_float(MPADSPContext *s,
|
||||
float *synth_buf_ptr, int *synth_buf_offset,
|
||||
float *window, int *dither_state,
|
||||
float *samples, int incr,
|
||||
float *sb_samples);
|
||||
|
||||
void ff_mpadsp_init_arm(MPADSPContext *s);
|
||||
void ff_mpadsp_init_ppc(MPADSPContext *s);
|
||||
void ff_mpadsp_init_x86(MPADSPContext *s);
|
||||
void ff_mpadsp_init_mipsfpu(MPADSPContext *s);
|
||||
void ff_mpadsp_init_mipsdspr1(MPADSPContext *s);
|
||||
|
||||
void ff_mpa_synth_init_float(float *window);
|
||||
void ff_mpa_synth_init_fixed(int32_t *window);
|
||||
|
||||
void ff_mpadsp_apply_window_float(float *synth_buf, float *window,
|
||||
int *dither_state, float *samples,
|
||||
int incr);
|
||||
void ff_mpadsp_apply_window_fixed(int32_t *synth_buf, int32_t *window,
|
||||
int *dither_state, int16_t *samples,
|
||||
int incr);
|
||||
|
||||
void ff_imdct36_blocks_float(float *out, float *buf, float *in,
|
||||
int count, int switch_point, int block_type);
|
||||
|
||||
void ff_imdct36_blocks_fixed(int *out, int *buf, int *in,
|
||||
int count, int switch_point, int block_type);
|
||||
|
||||
void ff_init_mpadsp_tabs_float(void);
|
||||
void ff_init_mpadsp_tabs_fixed(void);
|
||||
|
||||
/** For SSE implementation, MDCT_BUF_SIZE/2 should be 128-bit aligned */
|
||||
#define MDCT_BUF_SIZE FFALIGN(36, 2*4)
|
||||
|
||||
extern int ff_mdct_win_fixed[8][MDCT_BUF_SIZE];
|
||||
extern float ff_mdct_win_float[8][MDCT_BUF_SIZE];
|
||||
|
||||
#endif /* AVCODEC_MPEGAUDIODSP_H */
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* 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 "mpegaudiodsp.h"
|
||||
|
||||
/* half mpeg encoding window (full precision) */
|
||||
const int32_t ff_mpa_enwindow[257] = {
|
||||
0, -1, -1, -1, -1, -1, -1, -2,
|
||||
-2, -2, -2, -3, -3, -4, -4, -5,
|
||||
-5, -6, -7, -7, -8, -9, -10, -11,
|
||||
-13, -14, -16, -17, -19, -21, -24, -26,
|
||||
-29, -31, -35, -38, -41, -45, -49, -53,
|
||||
-58, -63, -68, -73, -79, -85, -91, -97,
|
||||
-104, -111, -117, -125, -132, -139, -147, -154,
|
||||
-161, -169, -176, -183, -190, -196, -202, -208,
|
||||
213, 218, 222, 225, 227, 228, 228, 227,
|
||||
224, 221, 215, 208, 200, 189, 177, 163,
|
||||
146, 127, 106, 83, 57, 29, -2, -36,
|
||||
-72, -111, -153, -197, -244, -294, -347, -401,
|
||||
-459, -519, -581, -645, -711, -779, -848, -919,
|
||||
-991, -1064, -1137, -1210, -1283, -1356, -1428, -1498,
|
||||
-1567, -1634, -1698, -1759, -1817, -1870, -1919, -1962,
|
||||
-2001, -2032, -2057, -2075, -2085, -2087, -2080, -2063,
|
||||
2037, 2000, 1952, 1893, 1822, 1739, 1644, 1535,
|
||||
1414, 1280, 1131, 970, 794, 605, 402, 185,
|
||||
-45, -288, -545, -814, -1095, -1388, -1692, -2006,
|
||||
-2330, -2663, -3004, -3351, -3705, -4063, -4425, -4788,
|
||||
-5153, -5517, -5879, -6237, -6589, -6935, -7271, -7597,
|
||||
-7910, -8209, -8491, -8755, -8998, -9219, -9416, -9585,
|
||||
-9727, -9838, -9916, -9959, -9966, -9935, -9863, -9750,
|
||||
-9592, -9389, -9139, -8840, -8492, -8092, -7640, -7134,
|
||||
6574, 5959, 5288, 4561, 3776, 2935, 2037, 1082,
|
||||
70, -998, -2122, -3300, -4533, -5818, -7154, -8540,
|
||||
-9975,-11455,-12980,-14548,-16155,-17799,-19478,-21189,
|
||||
-22929,-24694,-26482,-28289,-30112,-31947,-33791,-35640,
|
||||
-37489,-39336,-41176,-43006,-44821,-46617,-48390,-50137,
|
||||
-51853,-53534,-55178,-56778,-58333,-59838,-61289,-62684,
|
||||
-64019,-65290,-66494,-67629,-68692,-69679,-70590,-71420,
|
||||
-72169,-72835,-73415,-73908,-74313,-74630,-74856,-74992,
|
||||
75038,
|
||||
};
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* 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 CONFIG_FLOAT 0
|
||||
#include "mpegaudiodsp_template.c"
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* 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 CONFIG_FLOAT 1
|
||||
#include "mpegaudiodsp_template.c"
|
|
@ -0,0 +1,401 @@
|
|||
/*
|
||||
* Copyright (c) 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 <stdint.h>
|
||||
|
||||
#include "libavutil/attributes.h"
|
||||
#include "libavutil/mem.h"
|
||||
#include "dct32.h"
|
||||
#include "mathops.h"
|
||||
#include "mpegaudiodsp.h"
|
||||
#include "mpegaudio.h"
|
||||
|
||||
#if CONFIG_FLOAT
|
||||
#define RENAME(n) n##_float
|
||||
|
||||
static inline float round_sample(float *sum)
|
||||
{
|
||||
float sum1=*sum;
|
||||
*sum = 0;
|
||||
return sum1;
|
||||
}
|
||||
|
||||
#define MACS(rt, ra, rb) rt+=(ra)*(rb)
|
||||
#define MULS(ra, rb) ((ra)*(rb))
|
||||
#define MULH3(x, y, s) ((s)*(y)*(x))
|
||||
#define MLSS(rt, ra, rb) rt-=(ra)*(rb)
|
||||
#define MULLx(x, y, s) ((y)*(x))
|
||||
#define FIXHR(x) ((float)(x))
|
||||
#define FIXR(x) ((float)(x))
|
||||
#define SHR(a,b) ((a)*(1.0f/(1<<(b))))
|
||||
|
||||
#else
|
||||
|
||||
#define RENAME(n) n##_fixed
|
||||
#define OUT_SHIFT (WFRAC_BITS + FRAC_BITS - 15)
|
||||
|
||||
static inline int round_sample(int64_t *sum)
|
||||
{
|
||||
int sum1;
|
||||
sum1 = (int)((*sum) >> OUT_SHIFT);
|
||||
*sum &= (1<<OUT_SHIFT)-1;
|
||||
return av_clip_int16(sum1);
|
||||
}
|
||||
|
||||
# define MULS(ra, rb) MUL64(ra, rb)
|
||||
# define MACS(rt, ra, rb) MAC64(rt, ra, rb)
|
||||
# define MLSS(rt, ra, rb) MLS64(rt, ra, rb)
|
||||
# define MULH3(x, y, s) MULH((s)*(x), y)
|
||||
# define MULLx(x, y, s) MULL(x,y,s)
|
||||
# define SHR(a,b) ((a)>>(b))
|
||||
# define FIXR(a) ((int)((a) * FRAC_ONE + 0.5))
|
||||
# define FIXHR(a) ((int)((a) * (1LL<<32) + 0.5))
|
||||
#endif
|
||||
|
||||
/** Window for MDCT. Actually only the elements in [0,17] and
|
||||
[MDCT_BUF_SIZE/2, MDCT_BUF_SIZE/2 + 17] are actually used. The rest
|
||||
is just to preserve alignment for SIMD implementations.
|
||||
*/
|
||||
DECLARE_ALIGNED(16, INTFLOAT, RENAME(ff_mdct_win))[8][MDCT_BUF_SIZE];
|
||||
|
||||
DECLARE_ALIGNED(16, MPA_INT, RENAME(ff_mpa_synth_window))[512+256];
|
||||
|
||||
#define SUM8(op, sum, w, p) \
|
||||
{ \
|
||||
op(sum, (w)[0 * 64], (p)[0 * 64]); \
|
||||
op(sum, (w)[1 * 64], (p)[1 * 64]); \
|
||||
op(sum, (w)[2 * 64], (p)[2 * 64]); \
|
||||
op(sum, (w)[3 * 64], (p)[3 * 64]); \
|
||||
op(sum, (w)[4 * 64], (p)[4 * 64]); \
|
||||
op(sum, (w)[5 * 64], (p)[5 * 64]); \
|
||||
op(sum, (w)[6 * 64], (p)[6 * 64]); \
|
||||
op(sum, (w)[7 * 64], (p)[7 * 64]); \
|
||||
}
|
||||
|
||||
#define SUM8P2(sum1, op1, sum2, op2, w1, w2, p) \
|
||||
{ \
|
||||
INTFLOAT tmp;\
|
||||
tmp = p[0 * 64];\
|
||||
op1(sum1, (w1)[0 * 64], tmp);\
|
||||
op2(sum2, (w2)[0 * 64], tmp);\
|
||||
tmp = p[1 * 64];\
|
||||
op1(sum1, (w1)[1 * 64], tmp);\
|
||||
op2(sum2, (w2)[1 * 64], tmp);\
|
||||
tmp = p[2 * 64];\
|
||||
op1(sum1, (w1)[2 * 64], tmp);\
|
||||
op2(sum2, (w2)[2 * 64], tmp);\
|
||||
tmp = p[3 * 64];\
|
||||
op1(sum1, (w1)[3 * 64], tmp);\
|
||||
op2(sum2, (w2)[3 * 64], tmp);\
|
||||
tmp = p[4 * 64];\
|
||||
op1(sum1, (w1)[4 * 64], tmp);\
|
||||
op2(sum2, (w2)[4 * 64], tmp);\
|
||||
tmp = p[5 * 64];\
|
||||
op1(sum1, (w1)[5 * 64], tmp);\
|
||||
op2(sum2, (w2)[5 * 64], tmp);\
|
||||
tmp = p[6 * 64];\
|
||||
op1(sum1, (w1)[6 * 64], tmp);\
|
||||
op2(sum2, (w2)[6 * 64], tmp);\
|
||||
tmp = p[7 * 64];\
|
||||
op1(sum1, (w1)[7 * 64], tmp);\
|
||||
op2(sum2, (w2)[7 * 64], tmp);\
|
||||
}
|
||||
|
||||
void RENAME(ff_mpadsp_apply_window)(MPA_INT *synth_buf, MPA_INT *window,
|
||||
int *dither_state, OUT_INT *samples,
|
||||
int incr)
|
||||
{
|
||||
register const MPA_INT *w, *w2, *p;
|
||||
int j;
|
||||
OUT_INT *samples2;
|
||||
#if CONFIG_FLOAT
|
||||
float sum, sum2;
|
||||
#else
|
||||
int64_t sum, sum2;
|
||||
#endif
|
||||
|
||||
/* copy to avoid wrap */
|
||||
memcpy(synth_buf + 512, synth_buf, 32 * sizeof(*synth_buf));
|
||||
|
||||
samples2 = samples + 31 * incr;
|
||||
w = window;
|
||||
w2 = window + 31;
|
||||
|
||||
sum = *dither_state;
|
||||
p = synth_buf + 16;
|
||||
SUM8(MACS, sum, w, p);
|
||||
p = synth_buf + 48;
|
||||
SUM8(MLSS, sum, w + 32, p);
|
||||
*samples = round_sample(&sum);
|
||||
samples += incr;
|
||||
w++;
|
||||
|
||||
/* we calculate two samples at the same time to avoid one memory
|
||||
access per two sample */
|
||||
for(j=1;j<16;j++) {
|
||||
sum2 = 0;
|
||||
p = synth_buf + 16 + j;
|
||||
SUM8P2(sum, MACS, sum2, MLSS, w, w2, p);
|
||||
p = synth_buf + 48 - j;
|
||||
SUM8P2(sum, MLSS, sum2, MLSS, w + 32, w2 + 32, p);
|
||||
|
||||
*samples = round_sample(&sum);
|
||||
samples += incr;
|
||||
sum += sum2;
|
||||
*samples2 = round_sample(&sum);
|
||||
samples2 -= incr;
|
||||
w++;
|
||||
w2--;
|
||||
}
|
||||
|
||||
p = synth_buf + 32;
|
||||
SUM8(MLSS, sum, w + 32, p);
|
||||
*samples = round_sample(&sum);
|
||||
*dither_state= sum;
|
||||
}
|
||||
|
||||
/* 32 sub band synthesis filter. Input: 32 sub band samples, Output:
|
||||
32 samples. */
|
||||
void RENAME(ff_mpa_synth_filter)(MPADSPContext *s, MPA_INT *synth_buf_ptr,
|
||||
int *synth_buf_offset,
|
||||
MPA_INT *window, int *dither_state,
|
||||
OUT_INT *samples, int incr,
|
||||
MPA_INT *sb_samples)
|
||||
{
|
||||
MPA_INT *synth_buf;
|
||||
int offset;
|
||||
|
||||
offset = *synth_buf_offset;
|
||||
synth_buf = synth_buf_ptr + offset;
|
||||
|
||||
s->RENAME(dct32)(synth_buf, sb_samples);
|
||||
s->RENAME(apply_window)(synth_buf, window, dither_state, samples, incr);
|
||||
|
||||
offset = (offset - 32) & 511;
|
||||
*synth_buf_offset = offset;
|
||||
}
|
||||
|
||||
av_cold void RENAME(ff_mpa_synth_init)(MPA_INT *window)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
/* max = 18760, max sum over all 16 coefs : 44736 */
|
||||
for(i=0;i<257;i++) {
|
||||
INTFLOAT v;
|
||||
v = ff_mpa_enwindow[i];
|
||||
#if CONFIG_FLOAT
|
||||
v *= 1.0 / (1LL<<(16 + FRAC_BITS));
|
||||
#endif
|
||||
window[i] = v;
|
||||
if ((i & 63) != 0)
|
||||
v = -v;
|
||||
if (i != 0)
|
||||
window[512 - i] = v;
|
||||
}
|
||||
|
||||
|
||||
// Needed for avoiding shuffles in ASM implementations
|
||||
for(i=0; i < 8; i++)
|
||||
for(j=0; j < 16; j++)
|
||||
window[512+16*i+j] = window[64*i+32-j];
|
||||
|
||||
for(i=0; i < 8; i++)
|
||||
for(j=0; j < 16; j++)
|
||||
window[512+128+16*i+j] = window[64*i+48-j];
|
||||
}
|
||||
|
||||
av_cold void RENAME(ff_init_mpadsp_tabs)(void)
|
||||
{
|
||||
int i, j;
|
||||
/* compute mdct windows */
|
||||
for (i = 0; i < 36; i++) {
|
||||
for (j = 0; j < 4; j++) {
|
||||
double d;
|
||||
|
||||
if (j == 2 && i % 3 != 1)
|
||||
continue;
|
||||
|
||||
d = sin(M_PI * (i + 0.5) / 36.0);
|
||||
if (j == 1) {
|
||||
if (i >= 30) d = 0;
|
||||
else if (i >= 24) d = sin(M_PI * (i - 18 + 0.5) / 12.0);
|
||||
else if (i >= 18) d = 1;
|
||||
} else if (j == 3) {
|
||||
if (i < 6) d = 0;
|
||||
else if (i < 12) d = sin(M_PI * (i - 6 + 0.5) / 12.0);
|
||||
else if (i < 18) d = 1;
|
||||
}
|
||||
//merge last stage of imdct into the window coefficients
|
||||
d *= 0.5 * IMDCT_SCALAR / cos(M_PI * (2 * i + 19) / 72);
|
||||
|
||||
if (j == 2)
|
||||
RENAME(ff_mdct_win)[j][i/3] = FIXHR((d / (1<<5)));
|
||||
else {
|
||||
int idx = i < 18 ? i : i + (MDCT_BUF_SIZE/2 - 18);
|
||||
RENAME(ff_mdct_win)[j][idx] = FIXHR((d / (1<<5)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* NOTE: we do frequency inversion adter the MDCT by changing
|
||||
the sign of the right window coefs */
|
||||
for (j = 0; j < 4; j++) {
|
||||
for (i = 0; i < MDCT_BUF_SIZE; i += 2) {
|
||||
RENAME(ff_mdct_win)[j + 4][i ] = RENAME(ff_mdct_win)[j][i ];
|
||||
RENAME(ff_mdct_win)[j + 4][i + 1] = -RENAME(ff_mdct_win)[j][i + 1];
|
||||
}
|
||||
}
|
||||
}
|
||||
/* cos(pi*i/18) */
|
||||
#define C1 FIXHR(0.98480775301220805936/2)
|
||||
#define C2 FIXHR(0.93969262078590838405/2)
|
||||
#define C3 FIXHR(0.86602540378443864676/2)
|
||||
#define C4 FIXHR(0.76604444311897803520/2)
|
||||
#define C5 FIXHR(0.64278760968653932632/2)
|
||||
#define C6 FIXHR(0.5/2)
|
||||
#define C7 FIXHR(0.34202014332566873304/2)
|
||||
#define C8 FIXHR(0.17364817766693034885/2)
|
||||
|
||||
/* 0.5 / cos(pi*(2*i+1)/36) */
|
||||
static const INTFLOAT icos36[9] = {
|
||||
FIXR(0.50190991877167369479),
|
||||
FIXR(0.51763809020504152469), //0
|
||||
FIXR(0.55168895948124587824),
|
||||
FIXR(0.61038729438072803416),
|
||||
FIXR(0.70710678118654752439), //1
|
||||
FIXR(0.87172339781054900991),
|
||||
FIXR(1.18310079157624925896),
|
||||
FIXR(1.93185165257813657349), //2
|
||||
FIXR(5.73685662283492756461),
|
||||
};
|
||||
|
||||
/* 0.5 / cos(pi*(2*i+1)/36) */
|
||||
static const INTFLOAT icos36h[9] = {
|
||||
FIXHR(0.50190991877167369479/2),
|
||||
FIXHR(0.51763809020504152469/2), //0
|
||||
FIXHR(0.55168895948124587824/2),
|
||||
FIXHR(0.61038729438072803416/2),
|
||||
FIXHR(0.70710678118654752439/2), //1
|
||||
FIXHR(0.87172339781054900991/2),
|
||||
FIXHR(1.18310079157624925896/4),
|
||||
FIXHR(1.93185165257813657349/4), //2
|
||||
// FIXHR(5.73685662283492756461),
|
||||
};
|
||||
|
||||
/* using Lee like decomposition followed by hand coded 9 points DCT */
|
||||
static void imdct36(INTFLOAT *out, INTFLOAT *buf, INTFLOAT *in, INTFLOAT *win)
|
||||
{
|
||||
int i, j;
|
||||
INTFLOAT t0, t1, t2, t3, s0, s1, s2, s3;
|
||||
INTFLOAT tmp[18], *tmp1, *in1;
|
||||
|
||||
for (i = 17; i >= 1; i--)
|
||||
in[i] += in[i-1];
|
||||
for (i = 17; i >= 3; i -= 2)
|
||||
in[i] += in[i-2];
|
||||
|
||||
for (j = 0; j < 2; j++) {
|
||||
tmp1 = tmp + j;
|
||||
in1 = in + j;
|
||||
|
||||
t2 = in1[2*4] + in1[2*8] - in1[2*2];
|
||||
|
||||
t3 = in1[2*0] + SHR(in1[2*6],1);
|
||||
t1 = in1[2*0] - in1[2*6];
|
||||
tmp1[ 6] = t1 - SHR(t2,1);
|
||||
tmp1[16] = t1 + t2;
|
||||
|
||||
t0 = MULH3(in1[2*2] + in1[2*4] , C2, 2);
|
||||
t1 = MULH3(in1[2*4] - in1[2*8] , -2*C8, 1);
|
||||
t2 = MULH3(in1[2*2] + in1[2*8] , -C4, 2);
|
||||
|
||||
tmp1[10] = t3 - t0 - t2;
|
||||
tmp1[ 2] = t3 + t0 + t1;
|
||||
tmp1[14] = t3 + t2 - t1;
|
||||
|
||||
tmp1[ 4] = MULH3(in1[2*5] + in1[2*7] - in1[2*1], -C3, 2);
|
||||
t2 = MULH3(in1[2*1] + in1[2*5], C1, 2);
|
||||
t3 = MULH3(in1[2*5] - in1[2*7], -2*C7, 1);
|
||||
t0 = MULH3(in1[2*3], C3, 2);
|
||||
|
||||
t1 = MULH3(in1[2*1] + in1[2*7], -C5, 2);
|
||||
|
||||
tmp1[ 0] = t2 + t3 + t0;
|
||||
tmp1[12] = t2 + t1 - t0;
|
||||
tmp1[ 8] = t3 - t1 - t0;
|
||||
}
|
||||
|
||||
i = 0;
|
||||
for (j = 0; j < 4; j++) {
|
||||
t0 = tmp[i];
|
||||
t1 = tmp[i + 2];
|
||||
s0 = t1 + t0;
|
||||
s2 = t1 - t0;
|
||||
|
||||
t2 = tmp[i + 1];
|
||||
t3 = tmp[i + 3];
|
||||
s1 = MULH3(t3 + t2, icos36h[ j], 2);
|
||||
s3 = MULLx(t3 - t2, icos36 [8 - j], FRAC_BITS);
|
||||
|
||||
t0 = s0 + s1;
|
||||
t1 = s0 - s1;
|
||||
out[(9 + j) * SBLIMIT] = MULH3(t1, win[ 9 + j], 1) + buf[4*(9 + j)];
|
||||
out[(8 - j) * SBLIMIT] = MULH3(t1, win[ 8 - j], 1) + buf[4*(8 - j)];
|
||||
buf[4 * ( 9 + j )] = MULH3(t0, win[MDCT_BUF_SIZE/2 + 9 + j], 1);
|
||||
buf[4 * ( 8 - j )] = MULH3(t0, win[MDCT_BUF_SIZE/2 + 8 - j], 1);
|
||||
|
||||
t0 = s2 + s3;
|
||||
t1 = s2 - s3;
|
||||
out[(9 + 8 - j) * SBLIMIT] = MULH3(t1, win[ 9 + 8 - j], 1) + buf[4*(9 + 8 - j)];
|
||||
out[ j * SBLIMIT] = MULH3(t1, win[ j], 1) + buf[4*( j)];
|
||||
buf[4 * ( 9 + 8 - j )] = MULH3(t0, win[MDCT_BUF_SIZE/2 + 9 + 8 - j], 1);
|
||||
buf[4 * ( j )] = MULH3(t0, win[MDCT_BUF_SIZE/2 + j], 1);
|
||||
i += 4;
|
||||
}
|
||||
|
||||
s0 = tmp[16];
|
||||
s1 = MULH3(tmp[17], icos36h[4], 2);
|
||||
t0 = s0 + s1;
|
||||
t1 = s0 - s1;
|
||||
out[(9 + 4) * SBLIMIT] = MULH3(t1, win[ 9 + 4], 1) + buf[4*(9 + 4)];
|
||||
out[(8 - 4) * SBLIMIT] = MULH3(t1, win[ 8 - 4], 1) + buf[4*(8 - 4)];
|
||||
buf[4 * ( 9 + 4 )] = MULH3(t0, win[MDCT_BUF_SIZE/2 + 9 + 4], 1);
|
||||
buf[4 * ( 8 - 4 )] = MULH3(t0, win[MDCT_BUF_SIZE/2 + 8 - 4], 1);
|
||||
}
|
||||
|
||||
void RENAME(ff_imdct36_blocks)(INTFLOAT *out, INTFLOAT *buf, INTFLOAT *in,
|
||||
int count, int switch_point, int block_type)
|
||||
{
|
||||
int j;
|
||||
for (j=0 ; j < count; j++) {
|
||||
/* apply window & overlap with previous buffer */
|
||||
|
||||
/* select window */
|
||||
int win_idx = (switch_point && j < 2) ? 0 : block_type;
|
||||
INTFLOAT *win = RENAME(ff_mdct_win)[win_idx + (4 & -(j & 1))];
|
||||
|
||||
imdct36(out, buf, in, win);
|
||||
|
||||
in += 18;
|
||||
buf += ((j&3) != 3 ? 1 : (72-3));
|
||||
out++;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,788 @@
|
|||
/*
|
||||
* The simplest mpeg audio layer 2 encoder
|
||||
* 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
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* The simplest mpeg audio layer 2 encoder.
|
||||
*/
|
||||
|
||||
#include "libavutil/channel_layout.h"
|
||||
|
||||
#include "avcodec.h"
|
||||
#include "internal.h"
|
||||
#include "put_bits.h"
|
||||
|
||||
#define FRAC_BITS 15 /* fractional bits for sb_samples and dct */
|
||||
#define WFRAC_BITS 14 /* fractional bits for window */
|
||||
|
||||
#include "mpegaudio.h"
|
||||
#include "mpegaudiodsp.h"
|
||||
|
||||
/* currently, cannot change these constants (need to modify
|
||||
quantization stage) */
|
||||
#define MUL(a,b) (((int64_t)(a) * (int64_t)(b)) >> FRAC_BITS)
|
||||
|
||||
#define SAMPLES_BUF_SIZE 4096
|
||||
|
||||
typedef struct MpegAudioContext {
|
||||
PutBitContext pb;
|
||||
int nb_channels;
|
||||
int lsf; /* 1 if mpeg2 low bitrate selected */
|
||||
int bitrate_index; /* bit rate */
|
||||
int freq_index;
|
||||
int frame_size; /* frame size, in bits, without padding */
|
||||
/* padding computation */
|
||||
int frame_frac, frame_frac_incr, do_padding;
|
||||
short samples_buf[MPA_MAX_CHANNELS][SAMPLES_BUF_SIZE]; /* buffer for filter */
|
||||
int samples_offset[MPA_MAX_CHANNELS]; /* offset in samples_buf */
|
||||
int sb_samples[MPA_MAX_CHANNELS][3][12][SBLIMIT];
|
||||
unsigned char scale_factors[MPA_MAX_CHANNELS][SBLIMIT][3]; /* scale factors */
|
||||
/* code to group 3 scale factors */
|
||||
unsigned char scale_code[MPA_MAX_CHANNELS][SBLIMIT];
|
||||
int sblimit; /* number of used subbands */
|
||||
const unsigned char *alloc_table;
|
||||
} MpegAudioContext;
|
||||
|
||||
/* define it to use floats in quantization (I don't like floats !) */
|
||||
#define USE_FLOATS
|
||||
|
||||
#include "mpegaudiodata.h"
|
||||
#include "mpegaudiotab.h"
|
||||
|
||||
static av_cold int MPA_encode_init(AVCodecContext *avctx)
|
||||
{
|
||||
MpegAudioContext *s = avctx->priv_data;
|
||||
int freq = avctx->sample_rate;
|
||||
int bitrate = avctx->bit_rate;
|
||||
int channels = avctx->channels;
|
||||
int i, v, table;
|
||||
float a;
|
||||
|
||||
if (channels <= 0 || channels > 2){
|
||||
av_log(avctx, AV_LOG_ERROR, "encoding %d channel(s) is not allowed in mp2\n", channels);
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
bitrate = bitrate / 1000;
|
||||
s->nb_channels = channels;
|
||||
avctx->frame_size = MPA_FRAME_SIZE;
|
||||
avctx->delay = 512 - 32 + 1;
|
||||
|
||||
/* encoding freq */
|
||||
s->lsf = 0;
|
||||
for(i=0;i<3;i++) {
|
||||
if (avpriv_mpa_freq_tab[i] == freq)
|
||||
break;
|
||||
if ((avpriv_mpa_freq_tab[i] / 2) == freq) {
|
||||
s->lsf = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == 3){
|
||||
av_log(avctx, AV_LOG_ERROR, "Sampling rate %d is not allowed in mp2\n", freq);
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
s->freq_index = i;
|
||||
|
||||
/* encoding bitrate & frequency */
|
||||
for(i=0;i<15;i++) {
|
||||
if (avpriv_mpa_bitrate_tab[s->lsf][1][i] == bitrate)
|
||||
break;
|
||||
}
|
||||
if (i == 15){
|
||||
av_log(avctx, AV_LOG_ERROR, "bitrate %d is not allowed in mp2\n", bitrate);
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
s->bitrate_index = i;
|
||||
|
||||
/* compute total header size & pad bit */
|
||||
|
||||
a = (float)(bitrate * 1000 * MPA_FRAME_SIZE) / (freq * 8.0);
|
||||
s->frame_size = ((int)a) * 8;
|
||||
|
||||
/* frame fractional size to compute padding */
|
||||
s->frame_frac = 0;
|
||||
s->frame_frac_incr = (int)((a - floor(a)) * 65536.0);
|
||||
|
||||
/* select the right allocation table */
|
||||
table = ff_mpa_l2_select_table(bitrate, s->nb_channels, freq, s->lsf);
|
||||
|
||||
/* number of used subbands */
|
||||
s->sblimit = ff_mpa_sblimit_table[table];
|
||||
s->alloc_table = ff_mpa_alloc_tables[table];
|
||||
|
||||
av_dlog(avctx, "%d kb/s, %d Hz, frame_size=%d bits, table=%d, padincr=%x\n",
|
||||
bitrate, freq, s->frame_size, table, s->frame_frac_incr);
|
||||
|
||||
for(i=0;i<s->nb_channels;i++)
|
||||
s->samples_offset[i] = 0;
|
||||
|
||||
for(i=0;i<257;i++) {
|
||||
int v;
|
||||
v = ff_mpa_enwindow[i];
|
||||
#if WFRAC_BITS != 16
|
||||
v = (v + (1 << (16 - WFRAC_BITS - 1))) >> (16 - WFRAC_BITS);
|
||||
#endif
|
||||
filter_bank[i] = v;
|
||||
if ((i & 63) != 0)
|
||||
v = -v;
|
||||
if (i != 0)
|
||||
filter_bank[512 - i] = v;
|
||||
}
|
||||
|
||||
for(i=0;i<64;i++) {
|
||||
v = (int)(exp2((3 - i) / 3.0) * (1 << 20));
|
||||
if (v <= 0)
|
||||
v = 1;
|
||||
scale_factor_table[i] = v;
|
||||
#ifdef USE_FLOATS
|
||||
scale_factor_inv_table[i] = exp2(-(3 - i) / 3.0) / (float)(1 << 20);
|
||||
#else
|
||||
#define P 15
|
||||
scale_factor_shift[i] = 21 - P - (i / 3);
|
||||
scale_factor_mult[i] = (1 << P) * exp2((i % 3) / 3.0);
|
||||
#endif
|
||||
}
|
||||
for(i=0;i<128;i++) {
|
||||
v = i - 64;
|
||||
if (v <= -3)
|
||||
v = 0;
|
||||
else if (v < 0)
|
||||
v = 1;
|
||||
else if (v == 0)
|
||||
v = 2;
|
||||
else if (v < 3)
|
||||
v = 3;
|
||||
else
|
||||
v = 4;
|
||||
scale_diff_table[i] = v;
|
||||
}
|
||||
|
||||
for(i=0;i<17;i++) {
|
||||
v = ff_mpa_quant_bits[i];
|
||||
if (v < 0)
|
||||
v = -v;
|
||||
else
|
||||
v = v * 3;
|
||||
total_quant_bits[i] = 12 * v;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 32 point floating point IDCT without 1/sqrt(2) coef zero scaling */
|
||||
static void idct32(int *out, int *tab)
|
||||
{
|
||||
int i, j;
|
||||
int *t, *t1, xr;
|
||||
const int *xp = costab32;
|
||||
|
||||
for(j=31;j>=3;j-=2) tab[j] += tab[j - 2];
|
||||
|
||||
t = tab + 30;
|
||||
t1 = tab + 2;
|
||||
do {
|
||||
t[0] += t[-4];
|
||||
t[1] += t[1 - 4];
|
||||
t -= 4;
|
||||
} while (t != t1);
|
||||
|
||||
t = tab + 28;
|
||||
t1 = tab + 4;
|
||||
do {
|
||||
t[0] += t[-8];
|
||||
t[1] += t[1-8];
|
||||
t[2] += t[2-8];
|
||||
t[3] += t[3-8];
|
||||
t -= 8;
|
||||
} while (t != t1);
|
||||
|
||||
t = tab;
|
||||
t1 = tab + 32;
|
||||
do {
|
||||
t[ 3] = -t[ 3];
|
||||
t[ 6] = -t[ 6];
|
||||
|
||||
t[11] = -t[11];
|
||||
t[12] = -t[12];
|
||||
t[13] = -t[13];
|
||||
t[15] = -t[15];
|
||||
t += 16;
|
||||
} while (t != t1);
|
||||
|
||||
|
||||
t = tab;
|
||||
t1 = tab + 8;
|
||||
do {
|
||||
int x1, x2, x3, x4;
|
||||
|
||||
x3 = MUL(t[16], FIX(SQRT2*0.5));
|
||||
x4 = t[0] - x3;
|
||||
x3 = t[0] + x3;
|
||||
|
||||
x2 = MUL(-(t[24] + t[8]), FIX(SQRT2*0.5));
|
||||
x1 = MUL((t[8] - x2), xp[0]);
|
||||
x2 = MUL((t[8] + x2), xp[1]);
|
||||
|
||||
t[ 0] = x3 + x1;
|
||||
t[ 8] = x4 - x2;
|
||||
t[16] = x4 + x2;
|
||||
t[24] = x3 - x1;
|
||||
t++;
|
||||
} while (t != t1);
|
||||
|
||||
xp += 2;
|
||||
t = tab;
|
||||
t1 = tab + 4;
|
||||
do {
|
||||
xr = MUL(t[28],xp[0]);
|
||||
t[28] = (t[0] - xr);
|
||||
t[0] = (t[0] + xr);
|
||||
|
||||
xr = MUL(t[4],xp[1]);
|
||||
t[ 4] = (t[24] - xr);
|
||||
t[24] = (t[24] + xr);
|
||||
|
||||
xr = MUL(t[20],xp[2]);
|
||||
t[20] = (t[8] - xr);
|
||||
t[ 8] = (t[8] + xr);
|
||||
|
||||
xr = MUL(t[12],xp[3]);
|
||||
t[12] = (t[16] - xr);
|
||||
t[16] = (t[16] + xr);
|
||||
t++;
|
||||
} while (t != t1);
|
||||
xp += 4;
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
xr = MUL(tab[30-i*4],xp[0]);
|
||||
tab[30-i*4] = (tab[i*4] - xr);
|
||||
tab[ i*4] = (tab[i*4] + xr);
|
||||
|
||||
xr = MUL(tab[ 2+i*4],xp[1]);
|
||||
tab[ 2+i*4] = (tab[28-i*4] - xr);
|
||||
tab[28-i*4] = (tab[28-i*4] + xr);
|
||||
|
||||
xr = MUL(tab[31-i*4],xp[0]);
|
||||
tab[31-i*4] = (tab[1+i*4] - xr);
|
||||
tab[ 1+i*4] = (tab[1+i*4] + xr);
|
||||
|
||||
xr = MUL(tab[ 3+i*4],xp[1]);
|
||||
tab[ 3+i*4] = (tab[29-i*4] - xr);
|
||||
tab[29-i*4] = (tab[29-i*4] + xr);
|
||||
|
||||
xp += 2;
|
||||
}
|
||||
|
||||
t = tab + 30;
|
||||
t1 = tab + 1;
|
||||
do {
|
||||
xr = MUL(t1[0], *xp);
|
||||
t1[0] = (t[0] - xr);
|
||||
t[0] = (t[0] + xr);
|
||||
t -= 2;
|
||||
t1 += 2;
|
||||
xp++;
|
||||
} while (t >= tab);
|
||||
|
||||
for(i=0;i<32;i++) {
|
||||
out[i] = tab[bitinv32[i]];
|
||||
}
|
||||
}
|
||||
|
||||
#define WSHIFT (WFRAC_BITS + 15 - FRAC_BITS)
|
||||
|
||||
static void filter(MpegAudioContext *s, int ch, const short *samples, int incr)
|
||||
{
|
||||
short *p, *q;
|
||||
int sum, offset, i, j;
|
||||
int tmp[64];
|
||||
int tmp1[32];
|
||||
int *out;
|
||||
|
||||
offset = s->samples_offset[ch];
|
||||
out = &s->sb_samples[ch][0][0][0];
|
||||
for(j=0;j<36;j++) {
|
||||
/* 32 samples at once */
|
||||
for(i=0;i<32;i++) {
|
||||
s->samples_buf[ch][offset + (31 - i)] = samples[0];
|
||||
samples += incr;
|
||||
}
|
||||
|
||||
/* filter */
|
||||
p = s->samples_buf[ch] + offset;
|
||||
q = filter_bank;
|
||||
/* maxsum = 23169 */
|
||||
for(i=0;i<64;i++) {
|
||||
sum = p[0*64] * q[0*64];
|
||||
sum += p[1*64] * q[1*64];
|
||||
sum += p[2*64] * q[2*64];
|
||||
sum += p[3*64] * q[3*64];
|
||||
sum += p[4*64] * q[4*64];
|
||||
sum += p[5*64] * q[5*64];
|
||||
sum += p[6*64] * q[6*64];
|
||||
sum += p[7*64] * q[7*64];
|
||||
tmp[i] = sum;
|
||||
p++;
|
||||
q++;
|
||||
}
|
||||
tmp1[0] = tmp[16] >> WSHIFT;
|
||||
for( i=1; i<=16; i++ ) tmp1[i] = (tmp[i+16]+tmp[16-i]) >> WSHIFT;
|
||||
for( i=17; i<=31; i++ ) tmp1[i] = (tmp[i+16]-tmp[80-i]) >> WSHIFT;
|
||||
|
||||
idct32(out, tmp1);
|
||||
|
||||
/* advance of 32 samples */
|
||||
offset -= 32;
|
||||
out += 32;
|
||||
/* handle the wrap around */
|
||||
if (offset < 0) {
|
||||
memmove(s->samples_buf[ch] + SAMPLES_BUF_SIZE - (512 - 32),
|
||||
s->samples_buf[ch], (512 - 32) * 2);
|
||||
offset = SAMPLES_BUF_SIZE - 512;
|
||||
}
|
||||
}
|
||||
s->samples_offset[ch] = offset;
|
||||
}
|
||||
|
||||
static void compute_scale_factors(unsigned char scale_code[SBLIMIT],
|
||||
unsigned char scale_factors[SBLIMIT][3],
|
||||
int sb_samples[3][12][SBLIMIT],
|
||||
int sblimit)
|
||||
{
|
||||
int *p, vmax, v, n, i, j, k, code;
|
||||
int index, d1, d2;
|
||||
unsigned char *sf = &scale_factors[0][0];
|
||||
|
||||
for(j=0;j<sblimit;j++) {
|
||||
for(i=0;i<3;i++) {
|
||||
/* find the max absolute value */
|
||||
p = &sb_samples[i][0][j];
|
||||
vmax = abs(*p);
|
||||
for(k=1;k<12;k++) {
|
||||
p += SBLIMIT;
|
||||
v = abs(*p);
|
||||
if (v > vmax)
|
||||
vmax = v;
|
||||
}
|
||||
/* compute the scale factor index using log 2 computations */
|
||||
if (vmax > 1) {
|
||||
n = av_log2(vmax);
|
||||
/* n is the position of the MSB of vmax. now
|
||||
use at most 2 compares to find the index */
|
||||
index = (21 - n) * 3 - 3;
|
||||
if (index >= 0) {
|
||||
while (vmax <= scale_factor_table[index+1])
|
||||
index++;
|
||||
} else {
|
||||
index = 0; /* very unlikely case of overflow */
|
||||
}
|
||||
} else {
|
||||
index = 62; /* value 63 is not allowed */
|
||||
}
|
||||
|
||||
av_dlog(NULL, "%2d:%d in=%x %x %d\n",
|
||||
j, i, vmax, scale_factor_table[index], index);
|
||||
/* store the scale factor */
|
||||
av_assert2(index >=0 && index <= 63);
|
||||
sf[i] = index;
|
||||
}
|
||||
|
||||
/* compute the transmission factor : look if the scale factors
|
||||
are close enough to each other */
|
||||
d1 = scale_diff_table[sf[0] - sf[1] + 64];
|
||||
d2 = scale_diff_table[sf[1] - sf[2] + 64];
|
||||
|
||||
/* handle the 25 cases */
|
||||
switch(d1 * 5 + d2) {
|
||||
case 0*5+0:
|
||||
case 0*5+4:
|
||||
case 3*5+4:
|
||||
case 4*5+0:
|
||||
case 4*5+4:
|
||||
code = 0;
|
||||
break;
|
||||
case 0*5+1:
|
||||
case 0*5+2:
|
||||
case 4*5+1:
|
||||
case 4*5+2:
|
||||
code = 3;
|
||||
sf[2] = sf[1];
|
||||
break;
|
||||
case 0*5+3:
|
||||
case 4*5+3:
|
||||
code = 3;
|
||||
sf[1] = sf[2];
|
||||
break;
|
||||
case 1*5+0:
|
||||
case 1*5+4:
|
||||
case 2*5+4:
|
||||
code = 1;
|
||||
sf[1] = sf[0];
|
||||
break;
|
||||
case 1*5+1:
|
||||
case 1*5+2:
|
||||
case 2*5+0:
|
||||
case 2*5+1:
|
||||
case 2*5+2:
|
||||
code = 2;
|
||||
sf[1] = sf[2] = sf[0];
|
||||
break;
|
||||
case 2*5+3:
|
||||
case 3*5+3:
|
||||
code = 2;
|
||||
sf[0] = sf[1] = sf[2];
|
||||
break;
|
||||
case 3*5+0:
|
||||
case 3*5+1:
|
||||
case 3*5+2:
|
||||
code = 2;
|
||||
sf[0] = sf[2] = sf[1];
|
||||
break;
|
||||
case 1*5+3:
|
||||
code = 2;
|
||||
if (sf[0] > sf[2])
|
||||
sf[0] = sf[2];
|
||||
sf[1] = sf[2] = sf[0];
|
||||
break;
|
||||
default:
|
||||
av_assert2(0); //cannot happen
|
||||
code = 0; /* kill warning */
|
||||
}
|
||||
|
||||
av_dlog(NULL, "%d: %2d %2d %2d %d %d -> %d\n", j,
|
||||
sf[0], sf[1], sf[2], d1, d2, code);
|
||||
scale_code[j] = code;
|
||||
sf += 3;
|
||||
}
|
||||
}
|
||||
|
||||
/* The most important function : psycho acoustic module. In this
|
||||
encoder there is basically none, so this is the worst you can do,
|
||||
but also this is the simpler. */
|
||||
static void psycho_acoustic_model(MpegAudioContext *s, short smr[SBLIMIT])
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0;i<s->sblimit;i++) {
|
||||
smr[i] = (int)(fixed_smr[i] * 10);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#define SB_NOTALLOCATED 0
|
||||
#define SB_ALLOCATED 1
|
||||
#define SB_NOMORE 2
|
||||
|
||||
/* Try to maximize the smr while using a number of bits inferior to
|
||||
the frame size. I tried to make the code simpler, faster and
|
||||
smaller than other encoders :-) */
|
||||
static void compute_bit_allocation(MpegAudioContext *s,
|
||||
short smr1[MPA_MAX_CHANNELS][SBLIMIT],
|
||||
unsigned char bit_alloc[MPA_MAX_CHANNELS][SBLIMIT],
|
||||
int *padding)
|
||||
{
|
||||
int i, ch, b, max_smr, max_ch, max_sb, current_frame_size, max_frame_size;
|
||||
int incr;
|
||||
short smr[MPA_MAX_CHANNELS][SBLIMIT];
|
||||
unsigned char subband_status[MPA_MAX_CHANNELS][SBLIMIT];
|
||||
const unsigned char *alloc;
|
||||
|
||||
memcpy(smr, smr1, s->nb_channels * sizeof(short) * SBLIMIT);
|
||||
memset(subband_status, SB_NOTALLOCATED, s->nb_channels * SBLIMIT);
|
||||
memset(bit_alloc, 0, s->nb_channels * SBLIMIT);
|
||||
|
||||
/* compute frame size and padding */
|
||||
max_frame_size = s->frame_size;
|
||||
s->frame_frac += s->frame_frac_incr;
|
||||
if (s->frame_frac >= 65536) {
|
||||
s->frame_frac -= 65536;
|
||||
s->do_padding = 1;
|
||||
max_frame_size += 8;
|
||||
} else {
|
||||
s->do_padding = 0;
|
||||
}
|
||||
|
||||
/* compute the header + bit alloc size */
|
||||
current_frame_size = 32;
|
||||
alloc = s->alloc_table;
|
||||
for(i=0;i<s->sblimit;i++) {
|
||||
incr = alloc[0];
|
||||
current_frame_size += incr * s->nb_channels;
|
||||
alloc += 1 << incr;
|
||||
}
|
||||
for(;;) {
|
||||
/* look for the subband with the largest signal to mask ratio */
|
||||
max_sb = -1;
|
||||
max_ch = -1;
|
||||
max_smr = INT_MIN;
|
||||
for(ch=0;ch<s->nb_channels;ch++) {
|
||||
for(i=0;i<s->sblimit;i++) {
|
||||
if (smr[ch][i] > max_smr && subband_status[ch][i] != SB_NOMORE) {
|
||||
max_smr = smr[ch][i];
|
||||
max_sb = i;
|
||||
max_ch = ch;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (max_sb < 0)
|
||||
break;
|
||||
av_dlog(NULL, "current=%d max=%d max_sb=%d max_ch=%d alloc=%d\n",
|
||||
current_frame_size, max_frame_size, max_sb, max_ch,
|
||||
bit_alloc[max_ch][max_sb]);
|
||||
|
||||
/* find alloc table entry (XXX: not optimal, should use
|
||||
pointer table) */
|
||||
alloc = s->alloc_table;
|
||||
for(i=0;i<max_sb;i++) {
|
||||
alloc += 1 << alloc[0];
|
||||
}
|
||||
|
||||
if (subband_status[max_ch][max_sb] == SB_NOTALLOCATED) {
|
||||
/* nothing was coded for this band: add the necessary bits */
|
||||
incr = 2 + nb_scale_factors[s->scale_code[max_ch][max_sb]] * 6;
|
||||
incr += total_quant_bits[alloc[1]];
|
||||
} else {
|
||||
/* increments bit allocation */
|
||||
b = bit_alloc[max_ch][max_sb];
|
||||
incr = total_quant_bits[alloc[b + 1]] -
|
||||
total_quant_bits[alloc[b]];
|
||||
}
|
||||
|
||||
if (current_frame_size + incr <= max_frame_size) {
|
||||
/* can increase size */
|
||||
b = ++bit_alloc[max_ch][max_sb];
|
||||
current_frame_size += incr;
|
||||
/* decrease smr by the resolution we added */
|
||||
smr[max_ch][max_sb] = smr1[max_ch][max_sb] - quant_snr[alloc[b]];
|
||||
/* max allocation size reached ? */
|
||||
if (b == ((1 << alloc[0]) - 1))
|
||||
subband_status[max_ch][max_sb] = SB_NOMORE;
|
||||
else
|
||||
subband_status[max_ch][max_sb] = SB_ALLOCATED;
|
||||
} else {
|
||||
/* cannot increase the size of this subband */
|
||||
subband_status[max_ch][max_sb] = SB_NOMORE;
|
||||
}
|
||||
}
|
||||
*padding = max_frame_size - current_frame_size;
|
||||
av_assert0(*padding >= 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Output the mpeg audio layer 2 frame. Note how the code is small
|
||||
* compared to other encoders :-)
|
||||
*/
|
||||
static void encode_frame(MpegAudioContext *s,
|
||||
unsigned char bit_alloc[MPA_MAX_CHANNELS][SBLIMIT],
|
||||
int padding)
|
||||
{
|
||||
int i, j, k, l, bit_alloc_bits, b, ch;
|
||||
unsigned char *sf;
|
||||
int q[3];
|
||||
PutBitContext *p = &s->pb;
|
||||
|
||||
/* header */
|
||||
|
||||
put_bits(p, 12, 0xfff);
|
||||
put_bits(p, 1, 1 - s->lsf); /* 1 = mpeg1 ID, 0 = mpeg2 lsf ID */
|
||||
put_bits(p, 2, 4-2); /* layer 2 */
|
||||
put_bits(p, 1, 1); /* no error protection */
|
||||
put_bits(p, 4, s->bitrate_index);
|
||||
put_bits(p, 2, s->freq_index);
|
||||
put_bits(p, 1, s->do_padding); /* use padding */
|
||||
put_bits(p, 1, 0); /* private_bit */
|
||||
put_bits(p, 2, s->nb_channels == 2 ? MPA_STEREO : MPA_MONO);
|
||||
put_bits(p, 2, 0); /* mode_ext */
|
||||
put_bits(p, 1, 0); /* no copyright */
|
||||
put_bits(p, 1, 1); /* original */
|
||||
put_bits(p, 2, 0); /* no emphasis */
|
||||
|
||||
/* bit allocation */
|
||||
j = 0;
|
||||
for(i=0;i<s->sblimit;i++) {
|
||||
bit_alloc_bits = s->alloc_table[j];
|
||||
for(ch=0;ch<s->nb_channels;ch++) {
|
||||
put_bits(p, bit_alloc_bits, bit_alloc[ch][i]);
|
||||
}
|
||||
j += 1 << bit_alloc_bits;
|
||||
}
|
||||
|
||||
/* scale codes */
|
||||
for(i=0;i<s->sblimit;i++) {
|
||||
for(ch=0;ch<s->nb_channels;ch++) {
|
||||
if (bit_alloc[ch][i])
|
||||
put_bits(p, 2, s->scale_code[ch][i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* scale factors */
|
||||
for(i=0;i<s->sblimit;i++) {
|
||||
for(ch=0;ch<s->nb_channels;ch++) {
|
||||
if (bit_alloc[ch][i]) {
|
||||
sf = &s->scale_factors[ch][i][0];
|
||||
switch(s->scale_code[ch][i]) {
|
||||
case 0:
|
||||
put_bits(p, 6, sf[0]);
|
||||
put_bits(p, 6, sf[1]);
|
||||
put_bits(p, 6, sf[2]);
|
||||
break;
|
||||
case 3:
|
||||
case 1:
|
||||
put_bits(p, 6, sf[0]);
|
||||
put_bits(p, 6, sf[2]);
|
||||
break;
|
||||
case 2:
|
||||
put_bits(p, 6, sf[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* quantization & write sub band samples */
|
||||
|
||||
for(k=0;k<3;k++) {
|
||||
for(l=0;l<12;l+=3) {
|
||||
j = 0;
|
||||
for(i=0;i<s->sblimit;i++) {
|
||||
bit_alloc_bits = s->alloc_table[j];
|
||||
for(ch=0;ch<s->nb_channels;ch++) {
|
||||
b = bit_alloc[ch][i];
|
||||
if (b) {
|
||||
int qindex, steps, m, sample, bits;
|
||||
/* we encode 3 sub band samples of the same sub band at a time */
|
||||
qindex = s->alloc_table[j+b];
|
||||
steps = ff_mpa_quant_steps[qindex];
|
||||
for(m=0;m<3;m++) {
|
||||
sample = s->sb_samples[ch][k][l + m][i];
|
||||
/* divide by scale factor */
|
||||
#ifdef USE_FLOATS
|
||||
{
|
||||
float a;
|
||||
a = (float)sample * scale_factor_inv_table[s->scale_factors[ch][i][k]];
|
||||
q[m] = (int)((a + 1.0) * steps * 0.5);
|
||||
}
|
||||
#else
|
||||
{
|
||||
int q1, e, shift, mult;
|
||||
e = s->scale_factors[ch][i][k];
|
||||
shift = scale_factor_shift[e];
|
||||
mult = scale_factor_mult[e];
|
||||
|
||||
/* normalize to P bits */
|
||||
if (shift < 0)
|
||||
q1 = sample << (-shift);
|
||||
else
|
||||
q1 = sample >> shift;
|
||||
q1 = (q1 * mult) >> P;
|
||||
q[m] = ((q1 + (1 << P)) * steps) >> (P + 1);
|
||||
}
|
||||
#endif
|
||||
if (q[m] >= steps)
|
||||
q[m] = steps - 1;
|
||||
av_assert2(q[m] >= 0 && q[m] < steps);
|
||||
}
|
||||
bits = ff_mpa_quant_bits[qindex];
|
||||
if (bits < 0) {
|
||||
/* group the 3 values to save bits */
|
||||
put_bits(p, -bits,
|
||||
q[0] + steps * (q[1] + steps * q[2]));
|
||||
} else {
|
||||
put_bits(p, bits, q[0]);
|
||||
put_bits(p, bits, q[1]);
|
||||
put_bits(p, bits, q[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* next subband in alloc table */
|
||||
j += 1 << bit_alloc_bits;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* padding */
|
||||
for(i=0;i<padding;i++)
|
||||
put_bits(p, 1, 0);
|
||||
|
||||
/* flush */
|
||||
flush_put_bits(p);
|
||||
}
|
||||
|
||||
static int MPA_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
|
||||
const AVFrame *frame, int *got_packet_ptr)
|
||||
{
|
||||
MpegAudioContext *s = avctx->priv_data;
|
||||
const int16_t *samples = (const int16_t *)frame->data[0];
|
||||
short smr[MPA_MAX_CHANNELS][SBLIMIT];
|
||||
unsigned char bit_alloc[MPA_MAX_CHANNELS][SBLIMIT];
|
||||
int padding, i, ret;
|
||||
|
||||
for(i=0;i<s->nb_channels;i++) {
|
||||
filter(s, i, samples + i, s->nb_channels);
|
||||
}
|
||||
|
||||
for(i=0;i<s->nb_channels;i++) {
|
||||
compute_scale_factors(s->scale_code[i], s->scale_factors[i],
|
||||
s->sb_samples[i], s->sblimit);
|
||||
}
|
||||
for(i=0;i<s->nb_channels;i++) {
|
||||
psycho_acoustic_model(s, smr[i]);
|
||||
}
|
||||
compute_bit_allocation(s, smr, bit_alloc, &padding);
|
||||
|
||||
if ((ret = ff_alloc_packet2(avctx, avpkt, MPA_MAX_CODED_FRAME_SIZE)) < 0)
|
||||
return ret;
|
||||
|
||||
init_put_bits(&s->pb, avpkt->data, avpkt->size);
|
||||
|
||||
encode_frame(s, bit_alloc, padding);
|
||||
|
||||
if (frame->pts != AV_NOPTS_VALUE)
|
||||
avpkt->pts = frame->pts - ff_samples_to_time_base(avctx, avctx->delay);
|
||||
|
||||
avpkt->size = put_bits_count(&s->pb) / 8;
|
||||
*got_packet_ptr = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const AVCodecDefault mp2_defaults[] = {
|
||||
{ "b", "128k" },
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
AVCodec ff_mp2_encoder = {
|
||||
.name = "mp2",
|
||||
.long_name = NULL_IF_CONFIG_SMALL("MP2 (MPEG audio layer 2)"),
|
||||
.type = AVMEDIA_TYPE_AUDIO,
|
||||
.id = AV_CODEC_ID_MP2,
|
||||
.priv_data_size = sizeof(MpegAudioContext),
|
||||
.init = MPA_encode_init,
|
||||
.encode2 = MPA_encode_frame,
|
||||
.sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16,
|
||||
AV_SAMPLE_FMT_NONE },
|
||||
.supported_samplerates = (const int[]){
|
||||
44100, 48000, 32000, 22050, 24000, 16000, 0
|
||||
},
|
||||
.channel_layouts = (const uint64_t[]){ AV_CH_LAYOUT_MONO,
|
||||
AV_CH_LAYOUT_STEREO,
|
||||
0 },
|
||||
.defaults = mp2_defaults,
|
||||
};
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* mpeg audio layer 2 tables. Most of them come from the mpeg audio
|
||||
* specification.
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file
|
||||
* mpeg audio layer 2 tables.
|
||||
* Most of them come from the mpeg audio specification.
|
||||
*/
|
||||
|
||||
#ifndef AVCODEC_MPEGAUDIOTAB_H
|
||||
#define AVCODEC_MPEGAUDIOTAB_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "mpegaudio.h"
|
||||
|
||||
#define SQRT2 1.41421356237309514547
|
||||
|
||||
static const int costab32[30] = {
|
||||
FIX(0.54119610014619701222),
|
||||
FIX(1.3065629648763763537),
|
||||
|
||||
FIX(0.50979557910415917998),
|
||||
FIX(2.5629154477415054814),
|
||||
FIX(0.89997622313641556513),
|
||||
FIX(0.60134488693504528634),
|
||||
|
||||
FIX(0.5024192861881556782),
|
||||
FIX(5.1011486186891552563),
|
||||
FIX(0.78815462345125020249),
|
||||
FIX(0.64682178335999007679),
|
||||
FIX(0.56694403481635768927),
|
||||
FIX(1.0606776859903470633),
|
||||
FIX(1.7224470982383341955),
|
||||
FIX(0.52249861493968885462),
|
||||
|
||||
FIX(10.19000812354803287),
|
||||
FIX(0.674808341455005678),
|
||||
FIX(1.1694399334328846596),
|
||||
FIX(0.53104259108978413284),
|
||||
FIX(2.0577810099534108446),
|
||||
FIX(0.58293496820613388554),
|
||||
FIX(0.83934964541552681272),
|
||||
FIX(0.50547095989754364798),
|
||||
FIX(3.4076084184687189804),
|
||||
FIX(0.62250412303566482475),
|
||||
FIX(0.97256823786196078263),
|
||||
FIX(0.51544730992262455249),
|
||||
FIX(1.4841646163141661852),
|
||||
FIX(0.5531038960344445421),
|
||||
FIX(0.74453627100229857749),
|
||||
FIX(0.5006029982351962726),
|
||||
};
|
||||
|
||||
static const int bitinv32[32] = {
|
||||
0, 16, 8, 24, 4, 20, 12, 28,
|
||||
2, 18, 10, 26, 6, 22, 14, 30,
|
||||
1, 17, 9, 25, 5, 21, 13, 29,
|
||||
3, 19, 11, 27, 7, 23, 15, 31
|
||||
};
|
||||
|
||||
|
||||
static int16_t filter_bank[512];
|
||||
|
||||
static int scale_factor_table[64];
|
||||
#ifdef USE_FLOATS
|
||||
static float scale_factor_inv_table[64];
|
||||
#else
|
||||
static int8_t scale_factor_shift[64];
|
||||
static unsigned short scale_factor_mult[64];
|
||||
#endif
|
||||
static unsigned char scale_diff_table[128];
|
||||
|
||||
/* total number of bits per allocation group */
|
||||
static unsigned short total_quant_bits[17];
|
||||
|
||||
/* signal to noise ratio of each quantification step (could be
|
||||
computed from quant_steps[]). The values are dB multiplied by 10
|
||||
*/
|
||||
static const unsigned short quant_snr[17] = {
|
||||
70, 110, 160, 208,
|
||||
253, 316, 378, 439,
|
||||
499, 559, 620, 680,
|
||||
740, 800, 861, 920,
|
||||
980
|
||||
};
|
||||
|
||||
/* fixed psycho acoustic model. Values of SNR taken from the 'toolame'
|
||||
project */
|
||||
static const float fixed_smr[SBLIMIT] = {
|
||||
30, 17, 16, 10, 3, 12, 8, 2.5,
|
||||
5, 5, 6, 6, 5, 6, 10, 6,
|
||||
-4, -10, -21, -30, -42, -55, -68, -75,
|
||||
-75, -75, -75, -75, -91, -107, -110, -108
|
||||
};
|
||||
|
||||
static const unsigned char nb_scale_factors[4] = { 3, 2, 1, 2 };
|
||||
|
||||
#endif /* AVCODEC_MPEGAUDIOTAB_H */
|
|
@ -0,0 +1,277 @@
|
|||
/*
|
||||
* MMX optimized MP3 decoding functions
|
||||
* Copyright (c) 2010 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 "libavutil/attributes.h"
|
||||
#include "libavutil/cpu.h"
|
||||
#include "libavutil/internal.h"
|
||||
#include "libavutil/x86/asm.h"
|
||||
#include "libavutil/x86/cpu.h"
|
||||
#include "libavcodec/mpegaudiodsp.h"
|
||||
|
||||
#define DECL(CPU)\
|
||||
static void imdct36_blocks_ ## CPU(float *out, float *buf, float *in, int count, int switch_point, int block_type);\
|
||||
void ff_imdct36_float_ ## CPU(float *out, float *buf, float *in, float *win);
|
||||
|
||||
DECL(sse)
|
||||
DECL(sse2)
|
||||
DECL(sse3)
|
||||
DECL(ssse3)
|
||||
DECL(avx)
|
||||
|
||||
void ff_four_imdct36_float_sse(float *out, float *buf, float *in, float *win,
|
||||
float *tmpbuf);
|
||||
void ff_four_imdct36_float_avx(float *out, float *buf, float *in, float *win,
|
||||
float *tmpbuf);
|
||||
|
||||
DECLARE_ALIGNED(16, static float, mdct_win_sse)[2][4][4*40];
|
||||
|
||||
#if HAVE_SSE2_INLINE
|
||||
|
||||
#define MACS(rt, ra, rb) rt+=(ra)*(rb)
|
||||
#define MLSS(rt, ra, rb) rt-=(ra)*(rb)
|
||||
|
||||
#define SUM8(op, sum, w, p) \
|
||||
{ \
|
||||
op(sum, (w)[0 * 64], (p)[0 * 64]); \
|
||||
op(sum, (w)[1 * 64], (p)[1 * 64]); \
|
||||
op(sum, (w)[2 * 64], (p)[2 * 64]); \
|
||||
op(sum, (w)[3 * 64], (p)[3 * 64]); \
|
||||
op(sum, (w)[4 * 64], (p)[4 * 64]); \
|
||||
op(sum, (w)[5 * 64], (p)[5 * 64]); \
|
||||
op(sum, (w)[6 * 64], (p)[6 * 64]); \
|
||||
op(sum, (w)[7 * 64], (p)[7 * 64]); \
|
||||
}
|
||||
|
||||
static void apply_window(const float *buf, const float *win1,
|
||||
const float *win2, float *sum1, float *sum2, int len)
|
||||
{
|
||||
x86_reg count = - 4*len;
|
||||
const float *win1a = win1+len;
|
||||
const float *win2a = win2+len;
|
||||
const float *bufa = buf+len;
|
||||
float *sum1a = sum1+len;
|
||||
float *sum2a = sum2+len;
|
||||
|
||||
|
||||
#define MULT(a, b) \
|
||||
"movaps " #a "(%1,%0), %%xmm1 \n\t" \
|
||||
"movaps " #a "(%3,%0), %%xmm2 \n\t" \
|
||||
"mulps %%xmm2, %%xmm1 \n\t" \
|
||||
"subps %%xmm1, %%xmm0 \n\t" \
|
||||
"mulps " #b "(%2,%0), %%xmm2 \n\t" \
|
||||
"subps %%xmm2, %%xmm4 \n\t" \
|
||||
|
||||
__asm__ volatile(
|
||||
"1: \n\t"
|
||||
"xorps %%xmm0, %%xmm0 \n\t"
|
||||
"xorps %%xmm4, %%xmm4 \n\t"
|
||||
|
||||
MULT( 0, 0)
|
||||
MULT( 256, 64)
|
||||
MULT( 512, 128)
|
||||
MULT( 768, 192)
|
||||
MULT(1024, 256)
|
||||
MULT(1280, 320)
|
||||
MULT(1536, 384)
|
||||
MULT(1792, 448)
|
||||
|
||||
"movaps %%xmm0, (%4,%0) \n\t"
|
||||
"movaps %%xmm4, (%5,%0) \n\t"
|
||||
"add $16, %0 \n\t"
|
||||
"jl 1b \n\t"
|
||||
:"+&r"(count)
|
||||
:"r"(win1a), "r"(win2a), "r"(bufa), "r"(sum1a), "r"(sum2a)
|
||||
);
|
||||
|
||||
#undef MULT
|
||||
}
|
||||
|
||||
static void apply_window_mp3(float *in, float *win, int *unused, float *out,
|
||||
int incr)
|
||||
{
|
||||
LOCAL_ALIGNED_16(float, suma, [17]);
|
||||
LOCAL_ALIGNED_16(float, sumb, [17]);
|
||||
LOCAL_ALIGNED_16(float, sumc, [17]);
|
||||
LOCAL_ALIGNED_16(float, sumd, [17]);
|
||||
|
||||
float sum;
|
||||
|
||||
/* copy to avoid wrap */
|
||||
__asm__ volatile(
|
||||
"movaps 0(%0), %%xmm0 \n\t" \
|
||||
"movaps 16(%0), %%xmm1 \n\t" \
|
||||
"movaps 32(%0), %%xmm2 \n\t" \
|
||||
"movaps 48(%0), %%xmm3 \n\t" \
|
||||
"movaps %%xmm0, 0(%1) \n\t" \
|
||||
"movaps %%xmm1, 16(%1) \n\t" \
|
||||
"movaps %%xmm2, 32(%1) \n\t" \
|
||||
"movaps %%xmm3, 48(%1) \n\t" \
|
||||
"movaps 64(%0), %%xmm0 \n\t" \
|
||||
"movaps 80(%0), %%xmm1 \n\t" \
|
||||
"movaps 96(%0), %%xmm2 \n\t" \
|
||||
"movaps 112(%0), %%xmm3 \n\t" \
|
||||
"movaps %%xmm0, 64(%1) \n\t" \
|
||||
"movaps %%xmm1, 80(%1) \n\t" \
|
||||
"movaps %%xmm2, 96(%1) \n\t" \
|
||||
"movaps %%xmm3, 112(%1) \n\t"
|
||||
::"r"(in), "r"(in+512)
|
||||
:"memory"
|
||||
);
|
||||
|
||||
apply_window(in + 16, win , win + 512, suma, sumc, 16);
|
||||
apply_window(in + 32, win + 48, win + 640, sumb, sumd, 16);
|
||||
|
||||
SUM8(MACS, suma[0], win + 32, in + 48);
|
||||
|
||||
sumc[ 0] = 0;
|
||||
sumb[16] = 0;
|
||||
sumd[16] = 0;
|
||||
|
||||
#define SUMS(suma, sumb, sumc, sumd, out1, out2) \
|
||||
"movups " #sumd "(%4), %%xmm0 \n\t" \
|
||||
"shufps $0x1b, %%xmm0, %%xmm0 \n\t" \
|
||||
"subps " #suma "(%1), %%xmm0 \n\t" \
|
||||
"movaps %%xmm0," #out1 "(%0) \n\t" \
|
||||
\
|
||||
"movups " #sumc "(%3), %%xmm0 \n\t" \
|
||||
"shufps $0x1b, %%xmm0, %%xmm0 \n\t" \
|
||||
"addps " #sumb "(%2), %%xmm0 \n\t" \
|
||||
"movaps %%xmm0," #out2 "(%0) \n\t"
|
||||
|
||||
if (incr == 1) {
|
||||
__asm__ volatile(
|
||||
SUMS( 0, 48, 4, 52, 0, 112)
|
||||
SUMS(16, 32, 20, 36, 16, 96)
|
||||
SUMS(32, 16, 36, 20, 32, 80)
|
||||
SUMS(48, 0, 52, 4, 48, 64)
|
||||
|
||||
:"+&r"(out)
|
||||
:"r"(&suma[0]), "r"(&sumb[0]), "r"(&sumc[0]), "r"(&sumd[0])
|
||||
:"memory"
|
||||
);
|
||||
out += 16*incr;
|
||||
} else {
|
||||
int j;
|
||||
float *out2 = out + 32 * incr;
|
||||
out[0 ] = -suma[ 0];
|
||||
out += incr;
|
||||
out2 -= incr;
|
||||
for(j=1;j<16;j++) {
|
||||
*out = -suma[ j] + sumd[16-j];
|
||||
*out2 = sumb[16-j] + sumc[ j];
|
||||
out += incr;
|
||||
out2 -= incr;
|
||||
}
|
||||
}
|
||||
|
||||
sum = 0;
|
||||
SUM8(MLSS, sum, win + 16 + 32, in + 32);
|
||||
*out = sum;
|
||||
}
|
||||
|
||||
#endif /* HAVE_SSE2_INLINE */
|
||||
|
||||
#if HAVE_YASM
|
||||
#define DECL_IMDCT_BLOCKS(CPU1, CPU2) \
|
||||
static void imdct36_blocks_ ## CPU1(float *out, float *buf, float *in, \
|
||||
int count, int switch_point, int block_type) \
|
||||
{ \
|
||||
int align_end = count - (count & 3); \
|
||||
int j; \
|
||||
for (j = 0; j < align_end; j+= 4) { \
|
||||
LOCAL_ALIGNED_16(float, tmpbuf, [1024]); \
|
||||
float *win = mdct_win_sse[switch_point && j < 4][block_type]; \
|
||||
/* apply window & overlap with previous buffer */ \
|
||||
\
|
||||
/* select window */ \
|
||||
ff_four_imdct36_float_ ## CPU2(out, buf, in, win, tmpbuf); \
|
||||
in += 4*18; \
|
||||
buf += 4*18; \
|
||||
out += 4; \
|
||||
} \
|
||||
for (; j < count; j++) { \
|
||||
/* apply window & overlap with previous buffer */ \
|
||||
\
|
||||
/* select window */ \
|
||||
int win_idx = (switch_point && j < 2) ? 0 : block_type; \
|
||||
float *win = ff_mdct_win_float[win_idx + (4 & -(j & 1))]; \
|
||||
\
|
||||
ff_imdct36_float_ ## CPU1(out, buf, in, win); \
|
||||
\
|
||||
in += 18; \
|
||||
buf++; \
|
||||
out++; \
|
||||
} \
|
||||
}
|
||||
|
||||
#if HAVE_SSE
|
||||
DECL_IMDCT_BLOCKS(sse,sse)
|
||||
DECL_IMDCT_BLOCKS(sse2,sse)
|
||||
DECL_IMDCT_BLOCKS(sse3,sse)
|
||||
DECL_IMDCT_BLOCKS(ssse3,sse)
|
||||
#endif
|
||||
#if HAVE_AVX_EXTERNAL
|
||||
DECL_IMDCT_BLOCKS(avx,avx)
|
||||
#endif
|
||||
#endif /* HAVE_YASM */
|
||||
|
||||
av_cold void ff_mpadsp_init_x86(MPADSPContext *s)
|
||||
{
|
||||
int cpu_flags = av_get_cpu_flags();
|
||||
|
||||
int i, j;
|
||||
for (j = 0; j < 4; j++) {
|
||||
for (i = 0; i < 40; i ++) {
|
||||
mdct_win_sse[0][j][4*i ] = ff_mdct_win_float[j ][i];
|
||||
mdct_win_sse[0][j][4*i + 1] = ff_mdct_win_float[j + 4][i];
|
||||
mdct_win_sse[0][j][4*i + 2] = ff_mdct_win_float[j ][i];
|
||||
mdct_win_sse[0][j][4*i + 3] = ff_mdct_win_float[j + 4][i];
|
||||
mdct_win_sse[1][j][4*i ] = ff_mdct_win_float[0 ][i];
|
||||
mdct_win_sse[1][j][4*i + 1] = ff_mdct_win_float[4 ][i];
|
||||
mdct_win_sse[1][j][4*i + 2] = ff_mdct_win_float[j ][i];
|
||||
mdct_win_sse[1][j][4*i + 3] = ff_mdct_win_float[j + 4][i];
|
||||
}
|
||||
}
|
||||
|
||||
#if HAVE_SSE2_INLINE
|
||||
if (cpu_flags & AV_CPU_FLAG_SSE2) {
|
||||
s->apply_window_float = apply_window_mp3;
|
||||
}
|
||||
#endif /* HAVE_SSE2_INLINE */
|
||||
|
||||
#if HAVE_YASM
|
||||
if (EXTERNAL_SSE(cpu_flags)) {
|
||||
s->imdct36_blocks_float = imdct36_blocks_sse;
|
||||
}
|
||||
if (EXTERNAL_SSE2(cpu_flags)) {
|
||||
s->imdct36_blocks_float = imdct36_blocks_sse2;
|
||||
}
|
||||
if (EXTERNAL_SSE3(cpu_flags)) {
|
||||
s->imdct36_blocks_float = imdct36_blocks_sse3;
|
||||
}
|
||||
if (EXTERNAL_SSSE3(cpu_flags)) {
|
||||
s->imdct36_blocks_float = imdct36_blocks_ssse3;
|
||||
}
|
||||
if (EXTERNAL_AVX(cpu_flags)) {
|
||||
s->imdct36_blocks_float = imdct36_blocks_avx;
|
||||
}
|
||||
#endif /* HAVE_YASM */
|
||||
}
|
|
@ -0,0 +1,366 @@
|
|||
/*
|
||||
* 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 "config.h"
|
||||
#include "libavutil/opt.h"
|
||||
#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 {
|
||||
AVClass *class;
|
||||
int64_t filesize;
|
||||
int64_t header_filesize;
|
||||
int xing_toc;
|
||||
int start_pad;
|
||||
int end_pad;
|
||||
int usetoc;
|
||||
int is_cbr;
|
||||
} MP3DecContext;
|
||||
|
||||
/* 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_EXTENSION + 1;
|
||||
else if(max_frames>200)return AVPROBE_SCORE_EXTENSION;
|
||||
else if(max_frames>=4) return AVPROBE_SCORE_EXTENSION / 2;
|
||||
else if(ff_id3v2_match(buf0, ID3v2_DEFAULT_MAGIC) && 2*ff_id3v2_tag_len(buf0) >= p->buf_size)
|
||||
return p->buf_size < PROBE_BUF_MAX ? AVPROBE_SCORE_EXTENSION / 4 : AVPROBE_SCORE_EXTENSION - 2;
|
||||
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;
|
||||
MP3DecContext *mp3 = s->priv_data;
|
||||
int fill_index = mp3->usetoc && duration > 0;
|
||||
|
||||
if (!filesize &&
|
||||
!(filesize = avio_size(s->pb))) {
|
||||
av_log(s, AV_LOG_WARNING, "Cannot determine file size, skipping TOC table.\n");
|
||||
fill_index = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < XING_TOC_COUNT; i++) {
|
||||
uint8_t b = avio_r8(s->pb);
|
||||
if (fill_index)
|
||||
av_add_index_entry(s->streams[0],
|
||||
av_rescale(b, filesize, 256),
|
||||
av_rescale(i, duration, XING_TOC_COUNT),
|
||||
0, 0, AVINDEX_KEYFRAME);
|
||||
}
|
||||
if (fill_index)
|
||||
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)
|
||||
{
|
||||
MP3DecContext *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 */
|
||||
static 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)
|
||||
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);
|
||||
|
||||
mp3->is_cbr = is_cbr;
|
||||
mp3->header_filesize = size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mp3_read_header(AVFormatContext *s)
|
||||
{
|
||||
MP3DecContext *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)
|
||||
{
|
||||
MP3DecContext *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)
|
||||
{
|
||||
MP3DecContext *mp3 = s->priv_data;
|
||||
AVIndexEntry *ie, ie1;
|
||||
AVStream *st = s->streams[0];
|
||||
int64_t ret = av_index_search_timestamp(st, timestamp, flags);
|
||||
int i, j;
|
||||
|
||||
if (mp3->is_cbr && st->duration > 0 && mp3->header_filesize > s->data_offset) {
|
||||
int64_t filesize = avio_size(s->pb);
|
||||
int64_t duration;
|
||||
if (filesize <= s->data_offset)
|
||||
filesize = mp3->header_filesize;
|
||||
filesize -= s->data_offset;
|
||||
duration = av_rescale(st->duration, filesize, mp3->header_filesize - s->data_offset);
|
||||
ie = &ie1;
|
||||
timestamp = av_clip64(timestamp, 0, duration);
|
||||
ie->timestamp = timestamp;
|
||||
ie->pos = av_rescale(timestamp, filesize, duration) + s->data_offset;
|
||||
} else if (mp3->xing_toc) {
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
ie = &st->index_entries[ret];
|
||||
} else {
|
||||
st->skip_samples = timestamp <= 0 ? mp3->start_pad + 528 + 1 : 0;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
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; j<MIN_VALID; j++) {
|
||||
ret = check(s, pos);
|
||||
if(ret < 0)
|
||||
break;
|
||||
pos += ret;
|
||||
}
|
||||
if(j==MIN_VALID)
|
||||
break;
|
||||
}
|
||||
if(j!=MIN_VALID)
|
||||
i=0;
|
||||
|
||||
ret = avio_seek(s->pb, 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;
|
||||
}
|
||||
|
||||
static const AVOption options[] = {
|
||||
{ "usetoc", "use table of contents", offsetof(MP3DecContext, usetoc), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, AV_OPT_FLAG_DECODING_PARAM},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
static const AVClass demuxer_class = {
|
||||
.class_name = "mp3",
|
||||
.item_name = av_default_item_name,
|
||||
.option = options,
|
||||
.version = LIBAVUTIL_VERSION_INT,
|
||||
.category = AV_CLASS_CATEGORY_DEMUXER,
|
||||
};
|
||||
|
||||
AVInputFormat ff_mp3_demuxer = {
|
||||
.name = "mp3",
|
||||
.long_name = NULL_IF_CONFIG_SMALL("MP2/3 (MPEG audio layer 2/3)"),
|
||||
.read_probe = mp3_read_probe,
|
||||
.read_header = mp3_read_header,
|
||||
.read_packet = mp3_read_packet,
|
||||
.read_seek = mp3_seek,
|
||||
.priv_data_size = sizeof(MP3DecContext),
|
||||
.flags = AVFMT_GENERIC_INDEX,
|
||||
.extensions = "mp2,mp3,m2a,mpa", /* XXX: use probe */
|
||||
.priv_class = &demuxer_class,
|
||||
};
|
|
@ -0,0 +1,948 @@
|
|||
/*
|
||||
* 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 "config.h"
|
||||
#include "avformat.h"
|
||||
#include "internal.h"
|
||||
#include "mpeg.h"
|
||||
|
||||
#if CONFIG_VOBSUB_DEMUXER
|
||||
# include "subtitles.h"
|
||||
# include "libavutil/bprint.h"
|
||||
#endif
|
||||
|
||||
#undef NDEBUG
|
||||
#include <assert.h>
|
||||
#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; p<end && *p == 0xFF; p++);
|
||||
if((*p&0xC0) == 0x40) p+=2;
|
||||
if((*p&0xF0) == 0x20){
|
||||
pes1= p[0]&p[2]&p[4]&1;
|
||||
}else if((*p&0xF0) == 0x30){
|
||||
pes1= p[0]&p[2]&p[4]&p[5]&p[7]&p[9]&1;
|
||||
}else
|
||||
pes1 = *p == 0x0F;
|
||||
|
||||
return pes1||pes2;
|
||||
}
|
||||
|
||||
static int check_pack_header(const uint8_t *buf) {
|
||||
return (buf[1] & 0xC0) == 0x40 || (buf[1] & 0xF0) == 0x20;
|
||||
}
|
||||
|
||||
static int mpegps_probe(AVProbeData *p)
|
||||
{
|
||||
uint32_t code= -1;
|
||||
int sys=0, pspack=0, priv1=0, vid=0, audio=0, invalid=0;
|
||||
int i;
|
||||
int score=0;
|
||||
|
||||
for(i=0; i<p->buf_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_EXTENSION / 2;
|
||||
|
||||
if(sys>invalid && sys*9 <= pspack*10)
|
||||
return (audio > 12 || vid > 3 || pspack > 2) ? AVPROBE_SCORE_EXTENSION + 2 : AVPROBE_SCORE_EXTENSION / 2; // 1 more than .mpg
|
||||
if(pspack > invalid && (priv1+vid+audio)*10 >= pspack*9)
|
||||
return pspack > 2 ? AVPROBE_SCORE_EXTENSION + 2 : AVPROBE_SCORE_EXTENSION / 2; // 1 more than .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_EXTENSION + 2 : AVPROBE_SCORE_EXTENSION / 2;
|
||||
|
||||
//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;
|
||||
int imkh_cctv;
|
||||
#if CONFIG_VOBSUB_DEMUXER
|
||||
AVFormatContext *sub_ctx;
|
||||
FFDemuxSubtitlesQueue q[32];
|
||||
#endif
|
||||
} MpegDemuxContext;
|
||||
|
||||
static int mpegps_read_header(AVFormatContext *s)
|
||||
{
|
||||
MpegDemuxContext *m = s->priv_data;
|
||||
char buffer[7];
|
||||
int64_t last_pos = avio_tell(s->pb);
|
||||
|
||||
m->header_state = 0xff;
|
||||
s->ctx_flags |= AVFMTCTX_NOHEADER;
|
||||
|
||||
avio_get_str(s->pb, 6, buffer, sizeof(buffer));
|
||||
if (!memcmp("IMKH", buffer, 4)) {
|
||||
m->imkh_cctv = 1;
|
||||
} else if (!memcmp("Sofdec", buffer, 6)) {
|
||||
m->sofdec = 1;
|
||||
} else
|
||||
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; i<s->nb_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;i<s->nb_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(m->imkh_cctv && es_type == 0x91){
|
||||
codec_id = AV_CODEC_ID_PCM_MULAW;
|
||||
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 {
|
||||
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;
|
||||
if (st->codec->codec_id == AV_CODEC_ID_PCM_MULAW) {
|
||||
st->codec->channels = 1;
|
||||
st->codec->channel_layout = AV_CH_LAYOUT_MONO;
|
||||
st->codec->sample_rate = 8000;
|
||||
}
|
||||
st->request_probe = request_probe;
|
||||
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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
if (stream_id >= FF_ARRAY_ELEMS(vobsub->q)) {
|
||||
av_log(s, AV_LOG_ERROR, "Maximum number of subtitles streams reached\n");
|
||||
ret = AVERROR(EINVAL);
|
||||
goto end;
|
||||
}
|
||||
|
||||
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;
|
||||
avpriv_set_pts_info(st, 64, 1, 1000);
|
||||
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 (!s->nb_streams) {
|
||||
av_log(s, AV_LOG_ERROR, "Timestamp declared before any stream\n");
|
||||
ret = AVERROR_INVALIDDATA;
|
||||
goto end;
|
||||
}
|
||||
|
||||
if (sscanf(p, "%02d:%02d:%02d:%03d, filepos: %"SCNx64,
|
||||
&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[s->nb_streams - 1], "", 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;
|
||||
|
||||
for (i = 0; i < s->nb_streams; i++) {
|
||||
vobsub->q[i].sort = SUB_SORT_POS_TS;
|
||||
ff_subtitles_queue_finalize(&vobsub->q[i]);
|
||||
}
|
||||
|
||||
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;
|
||||
AVIOContext *pb = vobsub->sub_ctx->pb;
|
||||
int ret, psize, total_read = 0, i;
|
||||
AVPacket idx_pkt;
|
||||
|
||||
int64_t min_ts = INT64_MAX;
|
||||
int sid = 0;
|
||||
for (i = 0; i < s->nb_streams; i++) {
|
||||
FFDemuxSubtitlesQueue *tmpq = &vobsub->q[i];
|
||||
int64_t ts = tmpq->subs[tmpq->current_sub_idx].pts;
|
||||
if (ts < min_ts) {
|
||||
min_ts = ts;
|
||||
sid = i;
|
||||
}
|
||||
}
|
||||
q = &vobsub->q[sid];
|
||||
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;
|
||||
int64_t old_pos = avio_tell(pb), new_pos;
|
||||
int pkt_size;
|
||||
|
||||
ret = mpegps_read_pes_header(vobsub->sub_ctx, NULL, &startcode, &pts, &dts);
|
||||
if (ret < 0) {
|
||||
if (pkt->size) // raise packet even if incomplete
|
||||
break;
|
||||
FAIL(ret);
|
||||
}
|
||||
to_read = ret & 0xffff;
|
||||
new_pos = avio_tell(pb);
|
||||
pkt_size = ret + (new_pos - old_pos);
|
||||
|
||||
/* this prevents reads above the current packet */
|
||||
if (total_read + pkt_size > psize)
|
||||
break;
|
||||
total_read += pkt_size;
|
||||
|
||||
/* 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;
|
||||
} while (total_read < psize);
|
||||
|
||||
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(pkt);
|
||||
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;
|
||||
|
||||
/* Rescale requested timestamps based on the first stream (timebase is the
|
||||
* same for all subtitles stream within a .idx/.sub). Rescaling is done just
|
||||
* like in avformat_seek_file(). */
|
||||
if (stream_index == -1 && s->nb_streams != 1) {
|
||||
int i, ret = 0;
|
||||
AVRational time_base = s->streams[0]->time_base;
|
||||
ts = av_rescale_q(ts, AV_TIME_BASE_Q, time_base);
|
||||
min_ts = av_rescale_rnd(min_ts, time_base.den,
|
||||
time_base.num * (int64_t)AV_TIME_BASE,
|
||||
AV_ROUND_UP | AV_ROUND_PASS_MINMAX);
|
||||
max_ts = av_rescale_rnd(max_ts, time_base.den,
|
||||
time_base.num * (int64_t)AV_TIME_BASE,
|
||||
AV_ROUND_DOWN | AV_ROUND_PASS_MINMAX);
|
||||
for (i = 0; i < s->nb_streams; i++) {
|
||||
int r = ff_subtitles_queue_seek(&vobsub->q[i], s, stream_index,
|
||||
min_ts, ts, max_ts, flags);
|
||||
if (r < 0)
|
||||
ret = r;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ff_subtitles_queue_seek(&vobsub->q[stream_index], s, stream_index,
|
||||
min_ts, ts, max_ts, flags);
|
||||
}
|
||||
|
||||
static int vobsub_read_close(AVFormatContext *s)
|
||||
{
|
||||
int i;
|
||||
MpegDemuxContext *vobsub = s->priv_data;
|
||||
|
||||
for (i = 0; i < s->nb_streams; i++)
|
||||
ff_subtitles_queue_clean(&vobsub->q[i]);
|
||||
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
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* 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 <stdint.h>
|
||||
#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 0x88
|
||||
#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 */
|
|
@ -212,6 +212,12 @@ int lockmgr_callback(void ** mutex, enum AVLockOp op)
|
|||
break;
|
||||
}
|
||||
|
||||
if ( framePacket.stream_index != streamIndex )
|
||||
{
|
||||
av_free_packet( &framePacket );
|
||||
continue;
|
||||
}
|
||||
|
||||
AVFrame * frame = av_frame_alloc();
|
||||
int ret, got_frame = 0;
|
||||
|
||||
|
@ -294,12 +300,12 @@ int lockmgr_callback(void ** mutex, enum AVLockOp op)
|
|||
|
||||
+ (NSArray *)fileTypes
|
||||
{
|
||||
return [NSArray arrayWithObjects:@"wma", @"asf", @"xwma", @"tak", nil];
|
||||
return [NSArray arrayWithObjects:@"wma", @"asf", @"xwma", @"tak", @"mp3", @"mp2", @"m2a", @"mpa", nil];
|
||||
}
|
||||
|
||||
+ (NSArray *)mimeTypes
|
||||
{
|
||||
return [NSArray arrayWithObjects:@"application/wma", @"application/x-wma", @"audio/x-wma", @"audio/x-ms-wma", @"audio/x-tak", nil];
|
||||
return [NSArray arrayWithObjects:@"application/wma", @"application/x-wma", @"audio/x-wma", @"audio/x-ms-wma", @"audio/x-tak", @"audio/mpeg", @"audio/x-mp3", @"audio/x-mp2", nil];
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue