summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--camera/Android.mk1
-rw-r--r--camera/CameraBase.cpp4
-rw-r--r--camera/CameraParameters.cpp6
-rw-r--r--camera/CameraParameters2.cpp381
-rw-r--r--cmds/screenrecord/Overlay.cpp2
-rw-r--r--cmds/stagefright/codec.cpp7
-rw-r--r--cmds/stagefright/muxer.cpp3
-rw-r--r--cmds/stagefright/recordvideo.cpp3
-rw-r--r--cmds/stagefright/sf2.cpp5
-rw-r--r--cmds/stagefright/stagefright.cpp32
-rw-r--r--drm/common/DrmSupportInfo.cpp4
-rw-r--r--drm/drmserver/Android.mk5
-rw-r--r--drm/drmserver/DrmManager.cpp20
-rw-r--r--drm/drmserver/DrmManagerService.cpp93
-rw-r--r--drm/libdrmframework/include/DrmManagerService.h19
-rw-r--r--drm/libdrmframework/include/PlugInManager.h4
-rw-r--r--drm/libdrmframework/plugins/forward-lock/FwdLockEngine/Android.mk2
-rw-r--r--drm/mediadrm/plugins/mock/Android.mk3
-rw-r--r--drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp2
-rw-r--r--include/camera/CameraParameters2.h203
-rw-r--r--include/media/AudioSystem.h4
-rw-r--r--include/media/AudioTrack.h3
-rw-r--r--include/media/EffectsFactoryApi.h24
-rw-r--r--include/media/IAudioFlinger.h4
-rw-r--r--include/media/IOMX.h5
-rw-r--r--include/media/MediaMetadataRetrieverInterface.h1
-rw-r--r--include/media/MediaPlayerInterface.h1
-rw-r--r--include/media/mediascanner.h28
-rw-r--r--include/media/nbaio/NBLog.h6
-rw-r--r--include/media/stagefright/ACodec.h7
-rw-r--r--include/media/stagefright/AudioPlayer.h2
-rw-r--r--include/media/stagefright/ClockEstimator.h110
-rw-r--r--include/media/stagefright/FileSource.h2
-rw-r--r--include/media/stagefright/MediaCodec.h2
-rw-r--r--include/media/stagefright/MediaSource.h2
-rw-r--r--include/media/stagefright/MetaData.h3
-rw-r--r--include/media/stagefright/StagefrightMediaScanner.h2
-rw-r--r--include/private/media/AudioTrackShared.h14
-rw-r--r--include/private/media/StaticAudioTrackState.h10
-rw-r--r--include/private/media/VideoFrame.h58
-rwxr-xr-xlibvideoeditor/lvpp/Android.mk7
-rwxr-xr-xlibvideoeditor/lvpp/DummyVideoSource.cpp3
-rwxr-xr-xlibvideoeditor/lvpp/VideoEditorAudioPlayer.cpp15
-rwxr-xr-xlibvideoeditor/lvpp/VideoEditorBGAudioProcessing.cpp8
-rwxr-xr-xlibvideoeditor/lvpp/VideoEditorPlayer.cpp7
-rwxr-xr-xlibvideoeditor/lvpp/VideoEditorPlayer.h1
-rwxr-xr-xlibvideoeditor/lvpp/VideoEditorPreviewController.cpp4
-rwxr-xr-xlibvideoeditor/lvpp/VideoEditorSRC.cpp2
-rwxr-xr-xlibvideoeditor/osal/inc/M4OSA_Error.h2
-rwxr-xr-xlibvideoeditor/osal/inc/M4OSA_Types.h14
-rwxr-xr-xlibvideoeditor/osal/src/Android.mk4
-rwxr-xr-xlibvideoeditor/osal/src/M4OSA_Thread.c4
-rwxr-xr-xlibvideoeditor/osal/src/M4PSW_DebugTrace.c5
-rwxr-xr-xlibvideoeditor/vss/3gpwriter/src/Android.mk5
-rwxr-xr-xlibvideoeditor/vss/common/inc/marker.h78
-rwxr-xr-xlibvideoeditor/vss/mcs/src/Android.mk5
-rwxr-xr-xlibvideoeditor/vss/src/Android.mk7
-rwxr-xr-xlibvideoeditor/vss/src/M4DECODER_Null.c2
-rwxr-xr-xlibvideoeditor/vss/src/M4PCMR_CoreReader.c2
-rwxr-xr-xlibvideoeditor/vss/src/M4READER_Amr.c4
-rwxr-xr-xlibvideoeditor/vss/src/M4READER_Pcm.c2
-rwxr-xr-xlibvideoeditor/vss/src/M4VD_EXTERNAL_BitstreamParser.c15
-rwxr-xr-xlibvideoeditor/vss/src/M4xVSS_internal.c4
-rwxr-xr-xlibvideoeditor/vss/src/VideoEditorResampler.cpp2
-rwxr-xr-xlibvideoeditor/vss/stagefrightshells/src/VideoEditor3gpReader.cpp8
-rwxr-xr-xlibvideoeditor/vss/stagefrightshells/src/VideoEditorAudioDecoder.cpp2
-rwxr-xr-xlibvideoeditor/vss/stagefrightshells/src/VideoEditorBuffer.c8
-rwxr-xr-xlibvideoeditor/vss/stagefrightshells/src/VideoEditorMp3Reader.cpp4
-rwxr-xr-xlibvideoeditor/vss/stagefrightshells/src/VideoEditorUtils.cpp20
-rwxr-xr-xlibvideoeditor/vss/stagefrightshells/src/VideoEditorVideoEncoder.cpp2
-rwxr-xr-xlibvideoeditor/vss/video_filters/src/Android.mk5
-rw-r--r--media/common_time/utils.cpp2
-rw-r--r--media/libcpustats/Android.mk4
-rw-r--r--media/libcpustats/ThreadCpuUsage.cpp3
-rw-r--r--media/libeffects/downmix/Android.mk2
-rw-r--r--media/libeffects/downmix/EffectDownmix.c53
-rw-r--r--media/libeffects/downmix/EffectDownmix.h4
-rw-r--r--media/libeffects/factory/Android.mk1
-rw-r--r--media/libeffects/factory/EffectsFactory.c20
-rw-r--r--media/libeffects/factory/EffectsFactory.h28
-rw-r--r--media/libeffects/loudness/Android.mk2
-rw-r--r--media/libeffects/loudness/EffectLoudnessEnhancer.cpp14
-rw-r--r--media/libeffects/lvm/lib/Bass/src/LVDBE_Init.c2
-rw-r--r--media/libeffects/lvm/lib/Bundle/src/LVM_Process.c2
-rw-r--r--media/libeffects/lvm/lib/Common/lib/InstAlloc.h2
-rw-r--r--media/libeffects/lvm/lib/Common/lib/LVM_Types.h13
-rw-r--r--media/libeffects/lvm/lib/Common/src/InstAlloc.c22
-rw-r--r--media/libeffects/lvm/lib/Eq/src/LVEQNB_Init.c1
-rw-r--r--media/libeffects/lvm/lib/Eq/src/LVEQNB_Process.c2
-rw-r--r--media/libeffects/lvm/wrapper/Android.mk4
-rw-r--r--media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp44
-rw-r--r--media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp14
-rw-r--r--media/libeffects/preprocessing/Android.mk2
-rw-r--r--media/libeffects/preprocessing/PreProcessing.cpp26
-rw-r--r--media/libeffects/proxy/Android.mk5
-rw-r--r--media/libeffects/proxy/EffectProxy.cpp78
-rw-r--r--media/libeffects/proxy/EffectProxy.h4
-rw-r--r--media/libeffects/testlibs/Android.mk_4
-rw-r--r--media/libeffects/testlibs/EffectEqualizer.cpp10
-rw-r--r--media/libeffects/testlibs/EffectReverb.c8
-rw-r--r--media/libeffects/testlibs/EffectReverb.h4
-rw-r--r--media/libeffects/visualizer/Android.mk2
-rw-r--r--media/libeffects/visualizer/EffectVisualizer.cpp98
-rw-r--r--media/libmedia/Android.mk2
-rw-r--r--media/libmedia/AudioRecord.cpp2
-rw-r--r--media/libmedia/AudioSystem.cpp4
-rw-r--r--media/libmedia/AudioTrack.cpp98
-rw-r--r--media/libmedia/AudioTrackShared.cpp71
-rw-r--r--media/libmedia/IAudioFlinger.cpp28
-rw-r--r--media/libmedia/IAudioFlingerClient.cpp4
-rw-r--r--media/libmedia/IAudioTrack.cpp4
-rw-r--r--media/libmedia/ICrypto.cpp4
-rw-r--r--media/libmedia/IMediaLogService.cpp4
-rw-r--r--media/libmedia/IMediaMetadataRetriever.cpp6
-rw-r--r--media/libmedia/IOMX.cpp148
-rw-r--r--media/libmedia/IStreamSource.cpp16
-rw-r--r--media/libmedia/MediaScanner.cpp20
-rw-r--r--media/libmedia/MemoryLeakTrackUtil.cpp15
-rw-r--r--media/libmedia/mediaplayer.cpp2
-rw-r--r--media/libmediaplayerservice/Android.mk3
-rw-r--r--media/libmediaplayerservice/MediaPlayerFactory.cpp22
-rw-r--r--media/libmediaplayerservice/MediaPlayerFactory.h26
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.cpp16
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.h2
-rw-r--r--media/libmediaplayerservice/MetadataRetrieverClient.cpp12
-rw-r--r--media/libmediaplayerservice/MidiFile.h8
-rw-r--r--media/libmediaplayerservice/StagefrightPlayer.cpp2
-rw-r--r--media/libmediaplayerservice/StagefrightRecorder.cpp7
-rw-r--r--media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp2
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayer.cpp9
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp61
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h5
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp15
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp4
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerSource.h10
-rw-r--r--media/libmediaplayerservice/nuplayer/mp4/MP4Source.cpp2
-rw-r--r--media/libnbaio/MonoPipe.cpp2
-rw-r--r--media/libnbaio/NBLog.cpp80
-rw-r--r--media/libstagefright/AACExtractor.cpp4
-rw-r--r--media/libstagefright/AACWriter.cpp6
-rw-r--r--media/libstagefright/ACodec.cpp177
-rw-r--r--media/libstagefright/AMRExtractor.cpp8
-rw-r--r--media/libstagefright/AMRWriter.cpp6
-rw-r--r--media/libstagefright/Android.mk1
-rw-r--r--media/libstagefright/AudioPlayer.cpp17
-rw-r--r--media/libstagefright/AudioSource.cpp6
-rw-r--r--media/libstagefright/AwesomePlayer.cpp82
-rw-r--r--media/libstagefright/CameraSource.cpp2
-rw-r--r--media/libstagefright/CameraSourceTimeLapse.cpp4
-rw-r--r--media/libstagefright/ClockEstimator.cpp177
-rw-r--r--media/libstagefright/FLACExtractor.cpp70
-rw-r--r--media/libstagefright/MP3Extractor.cpp3
-rw-r--r--media/libstagefright/MPEG2TSWriter.cpp5
-rw-r--r--media/libstagefright/MPEG4Extractor.cpp127
-rw-r--r--media/libstagefright/MPEG4Writer.cpp29
-rw-r--r--media/libstagefright/MediaAdapter.cpp4
-rw-r--r--media/libstagefright/MediaBuffer.cpp5
-rw-r--r--media/libstagefright/MediaCodec.cpp8
-rw-r--r--media/libstagefright/MetaData.cpp17
-rw-r--r--media/libstagefright/NuCachedSource2.cpp4
-rw-r--r--media/libstagefright/OMXClient.cpp8
-rw-r--r--media/libstagefright/OMXCodec.cpp110
-rw-r--r--media/libstagefright/OggExtractor.cpp24
-rw-r--r--media/libstagefright/SampleTable.cpp191
-rw-r--r--media/libstagefright/StagefrightMediaScanner.cpp12
-rw-r--r--media/libstagefright/StagefrightMetadataRetriever.cpp19
-rw-r--r--media/libstagefright/SurfaceMediaSource.cpp12
-rw-r--r--media/libstagefright/TimedEventQueue.cpp29
-rw-r--r--media/libstagefright/Utils.cpp11
-rw-r--r--media/libstagefright/VBRISeeker.cpp4
-rw-r--r--media/libstagefright/WAVExtractor.cpp4
-rw-r--r--media/libstagefright/avc_utils.cpp9
-rw-r--r--media/libstagefright/chromium_http/Android.mk2
-rw-r--r--media/libstagefright/chromium_http/ChromiumHTTPDataSource.cpp5
-rw-r--r--media/libstagefright/chromium_http/support.cpp107
-rw-r--r--media/libstagefright/codecs/aacdec/SoftAAC2.cpp223
-rw-r--r--media/libstagefright/codecs/aacdec/SoftAAC2.h2
-rw-r--r--media/libstagefright/codecs/aacenc/SoftAACEncoder2.cpp6
-rw-r--r--media/libstagefright/codecs/aacenc/src/adj_thr.c2
-rw-r--r--media/libstagefright/codecs/aacenc/src/dyn_bits.c3
-rw-r--r--media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp4
-rw-r--r--media/libstagefright/codecs/amrnb/enc/SoftAMRNBEncoder.cpp2
-rw-r--r--media/libstagefright/codecs/amrwbenc/SoftAMRWBEncoder.cpp2
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Filt_6k_7k_opt.s1
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/pred_lt4_1_opt.s1
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Filt_6k_7k_neon.s1
-rw-r--r--media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/pred_lt4_1_neon.s1
-rw-r--r--media/libstagefright/codecs/avc/enc/SoftAVCEncoder.cpp26
-rw-r--r--media/libstagefright/codecs/avc/enc/src/bitstream_io.cpp15
-rw-r--r--media/libstagefright/codecs/common/Config.mk6
-rw-r--r--media/libstagefright/codecs/common/cmnMemory.c18
-rw-r--r--media/libstagefright/codecs/flac/enc/SoftFlacEncoder.cpp18
-rw-r--r--media/libstagefright/codecs/g711/dec/SoftG711.cpp4
-rw-r--r--media/libstagefright/codecs/gsm/dec/SoftGSM.cpp6
-rw-r--r--media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp2
-rw-r--r--media/libstagefright/codecs/m4v_h263/dec/src/get_pred_adv_b_add.cpp8
-rw-r--r--media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp12
-rw-r--r--media/libstagefright/codecs/m4v_h263/enc/include/mp4enc_api.h2
-rw-r--r--media/libstagefright/codecs/m4v_h263/enc/src/dct.cpp12
-rw-r--r--media/libstagefright/codecs/m4v_h263/enc/src/fastcodemb.cpp4
-rw-r--r--media/libstagefright/codecs/m4v_h263/enc/src/motion_comp.cpp10
-rw-r--r--media/libstagefright/codecs/m4v_h263/enc/src/mp4def.h2
-rw-r--r--media/libstagefright/codecs/m4v_h263/enc/src/sad_inline.h2
-rw-r--r--media/libstagefright/codecs/mp3dec/SoftMP3.cpp116
-rw-r--r--media/libstagefright/codecs/mp3dec/SoftMP3.h2
-rw-r--r--media/libstagefright/codecs/mp3dec/src/asm/pvmp3_dct_9_arm.s210
-rw-r--r--media/libstagefright/codecs/mp3dec/src/asm/pvmp3_mdct_18_arm.s369
-rw-r--r--media/libstagefright/codecs/mp3dec/src/asm/pvmp3_mdct_18_wm.asm366
-rw-r--r--media/libstagefright/codecs/mp3dec/src/asm/pvmp3_polyphase_filter_window_arm.s237
-rw-r--r--media/libstagefright/codecs/mp3dec/src/asm/pvmp3_polyphase_filter_window_gcc.s1
-rw-r--r--media/libstagefright/codecs/mp3dec/src/asm/pvmp3_polyphase_filter_window_wm.asm231
-rw-r--r--media/libstagefright/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_data.cpp2
-rw-r--r--media/libstagefright/codecs/on2/dec/SoftVPX.cpp2
-rw-r--r--media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp3
-rw-r--r--media/libstagefright/codecs/on2/h264dec/Android.mk5
-rw-r--r--media/libstagefright/codecs/on2/h264dec/SoftAVC.cpp2
-rw-r--r--media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/omxtypes.h60
-rwxr-xr-xmedia/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/omxtypes.h60
-rw-r--r--media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_DecodeCoeffsToPair_s.S16
-rw-r--r--media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_DequantTables_s.S8
-rw-r--r--media/libstagefright/codecs/on2/h264dec/omxdl/reference/api/omxtypes.h60
-rwxr-xr-xmedia/libstagefright/codecs/on2/h264dec/source/h264bsd_conceal.c2
-rwxr-xr-xmedia/libstagefright/codecs/on2/h264dec/source/h264bsd_intra_prediction.c10
-rwxr-xr-xmedia/libstagefright/codecs/on2/h264dec/source/h264bsd_util.c2
-rwxr-xr-xmedia/libstagefright/codecs/on2/h264dec/source/h264bsd_util.h3
-rw-r--r--media/libstagefright/codecs/raw/SoftRaw.cpp2
-rw-r--r--media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp84
-rw-r--r--media/libstagefright/codecs/vorbis/dec/SoftVorbis.h2
-rw-r--r--media/libstagefright/foundation/ANetworkSession.cpp6
-rw-r--r--media/libstagefright/foundation/AString.cpp42
-rw-r--r--media/libstagefright/foundation/Android.mk2
-rw-r--r--media/libstagefright/httplive/LiveSession.cpp605
-rw-r--r--media/libstagefright/httplive/LiveSession.h87
-rw-r--r--media/libstagefright/httplive/M3UParser.cpp232
-rw-r--r--media/libstagefright/httplive/M3UParser.h10
-rw-r--r--media/libstagefright/httplive/PlaylistFetcher.cpp781
-rw-r--r--media/libstagefright/httplive/PlaylistFetcher.h55
-rw-r--r--media/libstagefright/id3/ID3.cpp26
-rw-r--r--media/libstagefright/id3/testid3.cpp4
-rw-r--r--media/libstagefright/include/AwesomePlayer.h3
-rw-r--r--media/libstagefright/include/ChromiumHTTPDataSource.h1
-rw-r--r--media/libstagefright/include/ID3.h4
-rw-r--r--media/libstagefright/include/MPEG4Extractor.h1
-rw-r--r--media/libstagefright/include/OMX.h4
-rw-r--r--media/libstagefright/include/OMXNodeInstance.h13
-rw-r--r--media/libstagefright/include/SampleTable.h10
-rw-r--r--media/libstagefright/include/TimedEventQueue.h4
-rw-r--r--media/libstagefright/matroska/Android.mk2
-rw-r--r--media/libstagefright/matroska/MatroskaExtractor.cpp98
-rw-r--r--media/libstagefright/mpeg2ts/ATSParser.cpp24
-rw-r--r--media/libstagefright/mpeg2ts/ATSParser.h5
-rw-r--r--media/libstagefright/mpeg2ts/AnotherPacketSource.cpp74
-rw-r--r--media/libstagefright/mpeg2ts/AnotherPacketSource.h3
-rw-r--r--media/libstagefright/mpeg2ts/ESQueue.cpp17
-rw-r--r--media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp15
-rw-r--r--media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp2
-rw-r--r--media/libstagefright/omx/GraphicBufferSource.cpp112
-rw-r--r--media/libstagefright/omx/GraphicBufferSource.h25
-rw-r--r--media/libstagefright/omx/OMX.cpp18
-rw-r--r--media/libstagefright/omx/OMXNodeInstance.cpp150
-rw-r--r--media/libstagefright/omx/SoftOMXComponent.cpp40
-rw-r--r--media/libstagefright/omx/SoftOMXPlugin.cpp2
-rw-r--r--media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp11
-rw-r--r--media/libstagefright/omx/tests/Android.mk2
-rw-r--r--media/libstagefright/omx/tests/OMXHarness.cpp7
-rw-r--r--media/libstagefright/rtsp/AAVCAssembler.cpp10
-rw-r--r--media/libstagefright/rtsp/AMPEG2TSAssembler.cpp4
-rw-r--r--media/libstagefright/rtsp/AMPEG4ElementaryAssembler.cpp2
-rw-r--r--media/libstagefright/rtsp/ARTPConnection.cpp2
-rw-r--r--media/libstagefright/rtsp/ARTPWriter.cpp4
-rw-r--r--media/libstagefright/rtsp/ARTSPConnection.cpp2
-rw-r--r--media/libstagefright/rtsp/ARawAudioAssembler.cpp4
-rw-r--r--media/libstagefright/rtsp/Android.mk4
-rw-r--r--media/libstagefright/rtsp/MyHandler.h35
-rw-r--r--media/libstagefright/rtsp/SDPLoader.cpp4
-rw-r--r--media/libstagefright/tests/Android.mk2
-rw-r--r--media/libstagefright/tests/DummyRecorder.cpp2
-rw-r--r--media/libstagefright/timedtext/Android.mk3
-rw-r--r--media/libstagefright/timedtext/TimedTextPlayer.cpp3
-rw-r--r--media/libstagefright/timedtext/TimedTextSource.h2
-rw-r--r--media/libstagefright/wifi-display/rtp/RTPSender.cpp5
-rw-r--r--media/libstagefright/wifi-display/source/TSPacketizer.cpp4
-rw-r--r--media/libstagefright/wifi-display/source/WifiDisplaySource.cpp8
-rw-r--r--media/mediaserver/Android.mk1
-rw-r--r--media/mtp/Android.mk3
-rw-r--r--media/mtp/MtpDataPacket.cpp4
-rw-r--r--media/mtp/MtpDevice.cpp4
-rw-r--r--media/mtp/MtpProperty.cpp5
-rw-r--r--media/mtp/MtpServer.cpp7
-rw-r--r--media/mtp/MtpStringBuffer.cpp37
-rw-r--r--media/mtp/MtpStringBuffer.h5
-rw-r--r--media/mtp/MtpUtils.cpp3
-rw-r--r--services/audioflinger/Android.mk30
-rw-r--r--services/audioflinger/AudioFlinger.cpp20
-rw-r--r--services/audioflinger/AudioFlinger.h4
-rw-r--r--services/audioflinger/AudioMixer.cpp18
-rw-r--r--services/audioflinger/AudioPolicyService.cpp24
-rw-r--r--services/audioflinger/AudioPolicyService.h23
-rw-r--r--services/audioflinger/AudioResamplerSinc.cpp316
-rw-r--r--services/audioflinger/AudioWatchdog.cpp2
-rw-r--r--services/audioflinger/Configuration.h3
-rw-r--r--services/audioflinger/Effects.cpp24
-rw-r--r--services/audioflinger/FastMixer.cpp90
-rw-r--r--services/audioflinger/FastMixer.h5
-rw-r--r--services/audioflinger/FastMixerState.cpp2
-rw-r--r--services/audioflinger/FastMixerState.h1
-rw-r--r--services/audioflinger/StateQueue.cpp12
-rw-r--r--services/audioflinger/StateQueue.h4
-rw-r--r--services/audioflinger/Threads.cpp88
-rw-r--r--services/audioflinger/Threads.h2
-rw-r--r--services/audioflinger/Tracks.cpp19
-rw-r--r--services/camera/libcameraservice/CameraService.cpp17
-rw-r--r--services/camera/libcameraservice/api1/Camera2Client.cpp33
-rw-r--r--services/camera/libcameraservice/api1/CameraClient.cpp2
-rw-r--r--services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp6
-rw-r--r--services/camera/libcameraservice/api1/client2/FrameProcessor.cpp2
-rw-r--r--services/camera/libcameraservice/api1/client2/JpegCompressor.cpp4
-rw-r--r--services/camera/libcameraservice/api1/client2/JpegProcessor.cpp93
-rw-r--r--services/camera/libcameraservice/api1/client2/Parameters.cpp197
-rw-r--r--services/camera/libcameraservice/api1/client2/Parameters.h5
-rw-r--r--services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp16
-rw-r--r--services/camera/libcameraservice/api1/client2/ZslProcessor.cpp14
-rw-r--r--services/camera/libcameraservice/api1/client2/ZslProcessor3.cpp10
-rw-r--r--services/camera/libcameraservice/api2/CameraDeviceClient.cpp2
-rw-r--r--services/camera/libcameraservice/common/Camera2ClientBase.cpp4
-rw-r--r--services/camera/libcameraservice/common/FrameProcessorBase.cpp2
-rw-r--r--services/camera/libcameraservice/device2/Camera2Device.cpp13
-rw-r--r--services/camera/libcameraservice/device3/Camera3Device.cpp18
-rw-r--r--services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp15
-rw-r--r--services/camera/libcameraservice/device3/Camera3Stream.cpp2
-rw-r--r--services/camera/libcameraservice/device3/Camera3ZslStream.cpp6
-rw-r--r--services/camera/libcameraservice/device3/StatusTracker.cpp5
-rw-r--r--services/camera/libcameraservice/gui/RingBufferConsumer.cpp33
-rw-r--r--services/camera/libcameraservice/utils/CameraTraces.cpp4
-rw-r--r--services/medialog/Android.mk2
-rw-r--r--services/medialog/MediaLogService.cpp4
-rw-r--r--tools/resampler_tools/fir.cpp2
337 files changed, 5697 insertions, 4260 deletions
diff --git a/camera/Android.mk b/camera/Android.mk
index e633450..5cedab0 100644
--- a/camera/Android.mk
+++ b/camera/Android.mk
@@ -8,6 +8,7 @@ LOCAL_SRC_FILES:= \
Camera.cpp \
CameraMetadata.cpp \
CameraParameters.cpp \
+ CameraParameters2.cpp \
ICamera.cpp \
ICameraClient.cpp \
ICameraService.cpp \
diff --git a/camera/CameraBase.cpp b/camera/CameraBase.cpp
index 55376b0..04694cd 100644
--- a/camera/CameraBase.cpp
+++ b/camera/CameraBase.cpp
@@ -49,7 +49,7 @@ namespace {
DeathNotifier() {
}
- virtual void binderDied(const wp<IBinder>& who) {
+ virtual void binderDied(const wp<IBinder>& /*who*/) {
ALOGV("binderDied");
Mutex::Autolock _l(gLock);
gCameraService.clear();
@@ -153,7 +153,7 @@ status_t CameraBase<TCam, TCamTraits>::getStatus()
}
template <typename TCam, typename TCamTraits>
-void CameraBase<TCam, TCamTraits>::binderDied(const wp<IBinder>& who) {
+void CameraBase<TCam, TCamTraits>::binderDied(const wp<IBinder>& /*who*/) {
ALOGW("mediaserver's remote binder Camera object died");
notifyCallback(CAMERA_MSG_ERROR, CAMERA_ERROR_SERVER_DIED, /*ext2*/0);
}
diff --git a/camera/CameraParameters.cpp b/camera/CameraParameters.cpp
index c51f265..78eb4d6 100644
--- a/camera/CameraParameters.cpp
+++ b/camera/CameraParameters.cpp
@@ -456,7 +456,7 @@ const char *CameraParameters::getPictureFormat() const
void CameraParameters::dump() const
{
- ALOGD("dump: mMap.size = %d", mMap.size());
+ ALOGD("dump: mMap.size = %zu", mMap.size());
for (size_t i = 0; i < mMap.size(); i++) {
String8 k, v;
k = mMap.keyAt(i);
@@ -465,12 +465,12 @@ void CameraParameters::dump() const
}
}
-status_t CameraParameters::dump(int fd, const Vector<String16>& args) const
+status_t CameraParameters::dump(int fd, const Vector<String16>& /*args*/) const
{
const size_t SIZE = 256;
char buffer[SIZE];
String8 result;
- snprintf(buffer, 255, "CameraParameters::dump: mMap.size = %d\n", mMap.size());
+ snprintf(buffer, 255, "CameraParameters::dump: mMap.size = %zu\n", mMap.size());
result.append(buffer);
for (size_t i = 0; i < mMap.size(); i++) {
String8 k, v;
diff --git a/camera/CameraParameters2.cpp b/camera/CameraParameters2.cpp
new file mode 100644
index 0000000..eac79e1
--- /dev/null
+++ b/camera/CameraParameters2.cpp
@@ -0,0 +1,381 @@
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#define LOG_TAG "CameraParams2"
+// #define LOG_NDEBUG 0
+#include <utils/Log.h>
+
+#include <string.h>
+#include <stdlib.h>
+#include <camera/CameraParameters2.h>
+
+namespace android {
+
+CameraParameters2::CameraParameters2()
+ : mMap()
+{
+}
+
+CameraParameters2::~CameraParameters2()
+{
+}
+
+String8 CameraParameters2::flatten() const
+{
+ String8 flattened("");
+ size_t size = mMap.size();
+
+ for (size_t i = 0; i < size; i++) {
+ String8 k, v;
+ k = mMap.keyAt(i);
+ v = mMap.valueAt(i);
+
+ flattened += k;
+ flattened += "=";
+ flattened += v;
+ if (i != size-1)
+ flattened += ";";
+ }
+
+ ALOGV("%s: Flattened params = %s", __FUNCTION__, flattened.string());
+
+ return flattened;
+}
+
+void CameraParameters2::unflatten(const String8 &params)
+{
+ const char *a = params.string();
+ const char *b;
+
+ mMap.clear();
+
+ for (;;) {
+ // Find the bounds of the key name.
+ b = strchr(a, '=');
+ if (b == 0)
+ break;
+
+ // Create the key string.
+ String8 k(a, (size_t)(b-a));
+
+ // Find the value.
+ a = b+1;
+ b = strchr(a, ';');
+ if (b == 0) {
+ // If there's no semicolon, this is the last item.
+ String8 v(a);
+ mMap.add(k, v);
+ break;
+ }
+
+ String8 v(a, (size_t)(b-a));
+ mMap.add(k, v);
+ a = b+1;
+ }
+}
+
+
+void CameraParameters2::set(const char *key, const char *value)
+{
+ // XXX i think i can do this with strspn()
+ if (strchr(key, '=') || strchr(key, ';')) {
+ //XXX ALOGE("Key \"%s\"contains invalid character (= or ;)", key);
+ return;
+ }
+
+ if (strchr(value, '=') || strchr(value, ';')) {
+ //XXX ALOGE("Value \"%s\"contains invalid character (= or ;)", value);
+ return;
+ }
+
+ // Replacing a value updates the key's order to be the new largest order
+ ssize_t res = mMap.replaceValueFor(String8(key), String8(value));
+ LOG_ALWAYS_FATAL_IF(res < 0, "replaceValueFor(%s,%s) failed", key, value);
+}
+
+void CameraParameters2::set(const char *key, int value)
+{
+ char str[16];
+ sprintf(str, "%d", value);
+ set(key, str);
+}
+
+void CameraParameters2::setFloat(const char *key, float value)
+{
+ char str[16]; // 14 should be enough. We overestimate to be safe.
+ snprintf(str, sizeof(str), "%g", value);
+ set(key, str);
+}
+
+const char *CameraParameters2::get(const char *key) const
+{
+ ssize_t idx = mMap.indexOfKey(String8(key));
+ if (idx < 0) {
+ return NULL;
+ } else {
+ return mMap.valueAt(idx).string();
+ }
+}
+
+int CameraParameters2::getInt(const char *key) const
+{
+ const char *v = get(key);
+ if (v == 0)
+ return -1;
+ return strtol(v, 0, 0);
+}
+
+float CameraParameters2::getFloat(const char *key) const
+{
+ const char *v = get(key);
+ if (v == 0) return -1;
+ return strtof(v, 0);
+}
+
+status_t CameraParameters2::compareSetOrder(const char *key1, const char *key2,
+ int *order) const {
+ if (key1 == NULL) {
+ ALOGE("%s: key1 must not be NULL", __FUNCTION__);
+ return BAD_VALUE;
+ } else if (key2 == NULL) {
+ ALOGE("%s: key2 must not be NULL", __FUNCTION__);
+ return BAD_VALUE;
+ } else if (order == NULL) {
+ ALOGE("%s: order must not be NULL", __FUNCTION__);
+ return BAD_VALUE;
+ }
+
+ ssize_t index1 = mMap.indexOfKey(String8(key1));
+ ssize_t index2 = mMap.indexOfKey(String8(key2));
+ if (index1 < 0) {
+ ALOGW("%s: Key1 (%s) was not set", __FUNCTION__, key1);
+ return NAME_NOT_FOUND;
+ } else if (index2 < 0) {
+ ALOGW("%s: Key2 (%s) was not set", __FUNCTION__, key2);
+ return NAME_NOT_FOUND;
+ }
+
+ *order = (index1 == index2) ? 0 :
+ (index1 < index2) ? -1 :
+ 1;
+
+ return OK;
+}
+
+void CameraParameters2::remove(const char *key)
+{
+ mMap.removeItem(String8(key));
+}
+
+// Parse string like "640x480" or "10000,20000"
+static int parse_pair(const char *str, int *first, int *second, char delim,
+ char **endptr = NULL)
+{
+ // Find the first integer.
+ char *end;
+ int w = (int)strtol(str, &end, 10);
+ // If a delimeter does not immediately follow, give up.
+ if (*end != delim) {
+ ALOGE("Cannot find delimeter (%c) in str=%s", delim, str);
+ return -1;
+ }
+
+ // Find the second integer, immediately after the delimeter.
+ int h = (int)strtol(end+1, &end, 10);
+
+ *first = w;
+ *second = h;
+
+ if (endptr) {
+ *endptr = end;
+ }
+
+ return 0;
+}
+
+static void parseSizesList(const char *sizesStr, Vector<Size> &sizes)
+{
+ if (sizesStr == 0) {
+ return;
+ }
+
+ char *sizeStartPtr = (char *)sizesStr;
+
+ while (true) {
+ int width, height;
+ int success = parse_pair(sizeStartPtr, &width, &height, 'x',
+ &sizeStartPtr);
+ if (success == -1 || (*sizeStartPtr != ',' && *sizeStartPtr != '\0')) {
+ ALOGE("Picture sizes string \"%s\" contains invalid character.", sizesStr);
+ return;
+ }
+ sizes.push(Size(width, height));
+
+ if (*sizeStartPtr == '\0') {
+ return;
+ }
+ sizeStartPtr++;
+ }
+}
+
+void CameraParameters2::setPreviewSize(int width, int height)
+{
+ char str[32];
+ sprintf(str, "%dx%d", width, height);
+ set(CameraParameters::KEY_PREVIEW_SIZE, str);
+}
+
+void CameraParameters2::getPreviewSize(int *width, int *height) const
+{
+ *width = *height = -1;
+ // Get the current string, if it doesn't exist, leave the -1x-1
+ const char *p = get(CameraParameters::KEY_PREVIEW_SIZE);
+ if (p == 0) return;
+ parse_pair(p, width, height, 'x');
+}
+
+void CameraParameters2::getPreferredPreviewSizeForVideo(int *width, int *height) const
+{
+ *width = *height = -1;
+ const char *p = get(CameraParameters::KEY_PREFERRED_PREVIEW_SIZE_FOR_VIDEO);
+ if (p == 0) return;
+ parse_pair(p, width, height, 'x');
+}
+
+void CameraParameters2::getSupportedPreviewSizes(Vector<Size> &sizes) const
+{
+ const char *previewSizesStr = get(CameraParameters::KEY_SUPPORTED_PREVIEW_SIZES);
+ parseSizesList(previewSizesStr, sizes);
+}
+
+void CameraParameters2::setVideoSize(int width, int height)
+{
+ char str[32];
+ sprintf(str, "%dx%d", width, height);
+ set(CameraParameters::KEY_VIDEO_SIZE, str);
+}
+
+void CameraParameters2::getVideoSize(int *width, int *height) const
+{
+ *width = *height = -1;
+ const char *p = get(CameraParameters::KEY_VIDEO_SIZE);
+ if (p == 0) return;
+ parse_pair(p, width, height, 'x');
+}
+
+void CameraParameters2::getSupportedVideoSizes(Vector<Size> &sizes) const
+{
+ const char *videoSizesStr = get(CameraParameters::KEY_SUPPORTED_VIDEO_SIZES);
+ parseSizesList(videoSizesStr, sizes);
+}
+
+void CameraParameters2::setPreviewFrameRate(int fps)
+{
+ set(CameraParameters::KEY_PREVIEW_FRAME_RATE, fps);
+}
+
+int CameraParameters2::getPreviewFrameRate() const
+{
+ return getInt(CameraParameters::KEY_PREVIEW_FRAME_RATE);
+}
+
+void CameraParameters2::getPreviewFpsRange(int *min_fps, int *max_fps) const
+{
+ *min_fps = *max_fps = -1;
+ const char *p = get(CameraParameters::KEY_PREVIEW_FPS_RANGE);
+ if (p == 0) return;
+ parse_pair(p, min_fps, max_fps, ',');
+}
+
+void CameraParameters2::setPreviewFpsRange(int min_fps, int max_fps)
+{
+ String8 str = String8::format("%d,%d", min_fps, max_fps);
+ set(CameraParameters::KEY_PREVIEW_FPS_RANGE, str.string());
+}
+
+void CameraParameters2::setPreviewFormat(const char *format)
+{
+ set(CameraParameters::KEY_PREVIEW_FORMAT, format);
+}
+
+const char *CameraParameters2::getPreviewFormat() const
+{
+ return get(CameraParameters::KEY_PREVIEW_FORMAT);
+}
+
+void CameraParameters2::setPictureSize(int width, int height)
+{
+ char str[32];
+ sprintf(str, "%dx%d", width, height);
+ set(CameraParameters::KEY_PICTURE_SIZE, str);
+}
+
+void CameraParameters2::getPictureSize(int *width, int *height) const
+{
+ *width = *height = -1;
+ // Get the current string, if it doesn't exist, leave the -1x-1
+ const char *p = get(CameraParameters::KEY_PICTURE_SIZE);
+ if (p == 0) return;
+ parse_pair(p, width, height, 'x');
+}
+
+void CameraParameters2::getSupportedPictureSizes(Vector<Size> &sizes) const
+{
+ const char *pictureSizesStr = get(CameraParameters::KEY_SUPPORTED_PICTURE_SIZES);
+ parseSizesList(pictureSizesStr, sizes);
+}
+
+void CameraParameters2::setPictureFormat(const char *format)
+{
+ set(CameraParameters::KEY_PICTURE_FORMAT, format);
+}
+
+const char *CameraParameters2::getPictureFormat() const
+{
+ return get(CameraParameters::KEY_PICTURE_FORMAT);
+}
+
+void CameraParameters2::dump() const
+{
+ ALOGD("dump: mMap.size = %d", mMap.size());
+ for (size_t i = 0; i < mMap.size(); i++) {
+ String8 k, v;
+ k = mMap.keyAt(i);
+ v = mMap.valueAt(i);
+ ALOGD("%s: %s\n", k.string(), v.string());
+ }
+}
+
+status_t CameraParameters2::dump(int fd, const Vector<String16>& args) const
+{
+ const size_t SIZE = 256;
+ char buffer[SIZE];
+ String8 result;
+ snprintf(buffer, 255, "CameraParameters2::dump: mMap.size = %zu\n", mMap.size());
+ result.append(buffer);
+ for (size_t i = 0; i < mMap.size(); i++) {
+ String8 k, v;
+ k = mMap.keyAt(i);
+ v = mMap.valueAt(i);
+ snprintf(buffer, 255, "\t%s: %s\n", k.string(), v.string());
+ result.append(buffer);
+ }
+ write(fd, result.string(), result.size());
+ return NO_ERROR;
+}
+
+}; // namespace android
diff --git a/cmds/screenrecord/Overlay.cpp b/cmds/screenrecord/Overlay.cpp
index 96e25b8..35be221 100644
--- a/cmds/screenrecord/Overlay.cpp
+++ b/cmds/screenrecord/Overlay.cpp
@@ -47,7 +47,7 @@ const char* Overlay::kPropertyNames[] = {
"ro.revision",
"dalvik.vm.heapgrowthlimit",
"dalvik.vm.heapsize",
- "persist.sys.dalvik.vm.lib",
+ "persist.sys.dalvik.vm.lib.2",
//"ro.product.cpu.abi",
//"ro.bootloader",
//"this-never-appears!",
diff --git a/cmds/stagefright/codec.cpp b/cmds/stagefright/codec.cpp
index fdfefdf..d125ad1 100644
--- a/cmds/stagefright/codec.cpp
+++ b/cmds/stagefright/codec.cpp
@@ -16,6 +16,7 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "codec"
+#include <inttypes.h>
#include <utils/Log.h>
#include "SimplePlayer.h"
@@ -291,13 +292,13 @@ static int decode(
CHECK_EQ((status_t)OK, state->mCodec->release());
if (state->mIsAudio) {
- printf("track %d: %lld bytes received. %.2f KB/sec\n",
+ printf("track %zu: %" PRId64 " bytes received. %.2f KB/sec\n",
i,
state->mNumBytesDecoded,
state->mNumBytesDecoded * 1E6 / 1024 / elapsedTimeUs);
} else {
- printf("track %d: %lld frames decoded, %.2f fps. %lld bytes "
- "received. %.2f KB/sec\n",
+ printf("track %zu: %" PRId64 " frames decoded, %.2f fps. %" PRId64
+ " bytes received. %.2f KB/sec\n",
i,
state->mNumBuffersDecoded,
state->mNumBuffersDecoded * 1E6 / elapsedTimeUs,
diff --git a/cmds/stagefright/muxer.cpp b/cmds/stagefright/muxer.cpp
index cca33e0..90daea2 100644
--- a/cmds/stagefright/muxer.cpp
+++ b/cmds/stagefright/muxer.cpp
@@ -16,6 +16,7 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "muxer"
+#include <inttypes.h>
#include <utils/Log.h>
#include <binder/ProcessState.h>
@@ -198,7 +199,7 @@ static int muxing(
trackIndexMap.clear();
int64_t elapsedTimeUs = ALooper::GetNowUs() - muxerStartTimeUs;
- fprintf(stderr, "SUCCESS: muxer generate the video in %lld ms\n",
+ fprintf(stderr, "SUCCESS: muxer generate the video in %" PRId64 " ms\n",
elapsedTimeUs / 1000);
return 0;
diff --git a/cmds/stagefright/recordvideo.cpp b/cmds/stagefright/recordvideo.cpp
index c30c122..1d267f9 100644
--- a/cmds/stagefright/recordvideo.cpp
+++ b/cmds/stagefright/recordvideo.cpp
@@ -16,6 +16,7 @@
#include "SineSource.h"
+#include <inttypes.h>
#include <binder/ProcessState.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/AudioPlayer.h>
@@ -312,7 +313,7 @@ int main(int argc, char **argv) {
fprintf(stderr, "record failed: %d\n", err);
return 1;
}
- fprintf(stderr, "encoding %d frames in %lld us\n", nFrames, (end-start)/1000);
+ fprintf(stderr, "encoding %d frames in %" PRId64 " us\n", nFrames, (end-start)/1000);
fprintf(stderr, "encoding speed is: %.2f fps\n", (nFrames * 1E9) / (end-start));
return 0;
}
diff --git a/cmds/stagefright/sf2.cpp b/cmds/stagefright/sf2.cpp
index c817443..b2b9ce5 100644
--- a/cmds/stagefright/sf2.cpp
+++ b/cmds/stagefright/sf2.cpp
@@ -16,6 +16,7 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "sf2"
+#include <inttypes.h>
#include <utils/Log.h>
#include <binder/ProcessState.h>
@@ -183,11 +184,11 @@ protected:
int64_t delayUs = ALooper::GetNowUs() - mStartTimeUs;
if (mDecodeAudio) {
- printf("%lld bytes received. %.2f KB/sec\n",
+ printf("%" PRId64 " bytes received. %.2f KB/sec\n",
mTotalBytesReceived,
mTotalBytesReceived * 1E6 / 1024 / delayUs);
} else {
- printf("%d frames decoded, %.2f fps. %lld bytes "
+ printf("%d frames decoded, %.2f fps. %" PRId64 " bytes "
"received. %.2f KB/sec\n",
mNumOutputBuffersReceived,
mNumOutputBuffersReceived * 1E6 / delayUs,
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index 030bf1b..ab2c54b 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -14,15 +14,16 @@
* limitations under the License.
*/
+#include <inttypes.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/time.h>
+
//#define LOG_NDEBUG 0
#define LOG_TAG "stagefright"
#include <media/stagefright/foundation/ADebug.h>
-#include <sys/time.h>
-
-#include <stdlib.h>
-#include <string.h>
-
#include "jpeg.h"
#include "SineSource.h"
@@ -49,8 +50,6 @@
#include <private/media/VideoFrame.h>
-#include <fcntl.h>
-
#include <gui/GLConsumer.h>
#include <gui/Surface.h>
#include <gui/SurfaceComposerClient.h>
@@ -89,8 +88,8 @@ static void displayDecodeHistogram(Vector<int64_t> *decodeTimesUs) {
int64_t minUs = decodeTimesUs->itemAt(0);
int64_t maxUs = decodeTimesUs->itemAt(n - 1);
- printf("min decode time %lld us (%.2f secs)\n", minUs, minUs / 1E6);
- printf("max decode time %lld us (%.2f secs)\n", maxUs, maxUs / 1E6);
+ printf("min decode time %" PRId64 " us (%.2f secs)\n", minUs, minUs / 1E6);
+ printf("max decode time %" PRId64 " us (%.2f secs)\n", maxUs, maxUs / 1E6);
size_t counts[100];
for (size_t i = 0; i < 100; ++i) {
@@ -110,7 +109,7 @@ static void displayDecodeHistogram(Vector<int64_t> *decodeTimesUs) {
int64_t slotUs = minUs + (i * (maxUs - minUs) / 100);
double fps = 1E6 / slotUs;
- printf("[%.2f fps]: %d\n", fps, counts[i]);
+ printf("[%.2f fps]: %zu\n", fps, counts[i]);
}
}
@@ -262,7 +261,7 @@ static void playSource(OMXClient *client, sp<MediaSource> &source) {
}
}
- printf("buffer has timestamp %lld us (%.2f secs)\n",
+ printf("buffer has timestamp %" PRId64 " us (%.2f secs)\n",
timestampUs, timestampUs / 1E6);
buffer->release();
@@ -285,7 +284,7 @@ static void playSource(OMXClient *client, sp<MediaSource> &source) {
seekTimeUs = (rand() * (float)durationUs) / RAND_MAX;
options.setSeekTo(seekTimeUs);
- printf("seeking to %lld us (%.2f secs)\n",
+ printf("seeking to %" PRId64 " us (%.2f secs)\n",
seekTimeUs, seekTimeUs / 1E6);
}
}
@@ -388,7 +387,7 @@ static void playSource(OMXClient *client, sp<MediaSource> &source) {
// sizes may be different across decoders.
printf("avg. %.2f KB/sec\n", totalBytes / 1024 * 1E6 / delay);
- printf("decoded a total of %lld bytes\n", totalBytes);
+ printf("decoded a total of %" PRId64 " bytes\n", totalBytes);
}
}
@@ -574,7 +573,8 @@ static void performSeekTest(const sp<MediaSource> &source) {
int64_t timeUs;
CHECK(buffer->meta_data()->findInt64(kKeyTime, &timeUs));
- printf("%lld\t%lld\t%lld\n", seekTimeUs, timeUs, seekTimeUs - timeUs);
+ printf("%" PRId64 "\t%" PRId64 "\t%" PRId64 "\n",
+ seekTimeUs, timeUs, seekTimeUs - timeUs);
buffer->release();
buffer = NULL;
@@ -645,7 +645,7 @@ static void dumpCodecProfiles(const sp<IOMX>& omx, bool queryDecoders) {
const CodecProfileLevel &profileLevel =
results[i].mProfileLevels[j];
- printf("%s%ld/%ld", j > 0 ? ", " : "",
+ printf("%s%" PRIu32 "/%" PRIu32, j > 0 ? ", " : "",
profileLevel.mProfile, profileLevel.mLevel);
}
@@ -1071,7 +1071,7 @@ int main(int argc, char **argv) {
int64_t thumbTimeUs;
if (meta->findInt64(kKeyThumbnailTime, &thumbTimeUs)) {
- printf("thumbnailTime: %lld us (%.2f secs)\n",
+ printf("thumbnailTime: %" PRId64 " us (%.2f secs)\n",
thumbTimeUs, thumbTimeUs / 1E6);
}
diff --git a/drm/common/DrmSupportInfo.cpp b/drm/common/DrmSupportInfo.cpp
index 5400bdd..584c6a6 100644
--- a/drm/common/DrmSupportInfo.cpp
+++ b/drm/common/DrmSupportInfo.cpp
@@ -47,7 +47,7 @@ bool DrmSupportInfo::isSupportedMimeType(const String8& mimeType) const {
return false;
}
- for (unsigned int i = 0; i < mMimeTypeVector.size(); i++) {
+ for (size_t i = 0; i < mMimeTypeVector.size(); i++) {
const String8 item = mMimeTypeVector.itemAt(i);
if (!strcasecmp(item.string(), mimeType.string())) {
@@ -58,7 +58,7 @@ bool DrmSupportInfo::isSupportedMimeType(const String8& mimeType) const {
}
bool DrmSupportInfo::isSupportedFileSuffix(const String8& fileType) const {
- for (unsigned int i = 0; i < mFileSuffixVector.size(); i++) {
+ for (size_t i = 0; i < mFileSuffixVector.size(); i++) {
const String8 item = mFileSuffixVector.itemAt(i);
if (!strcasecmp(item.string(), fileType.string())) {
diff --git a/drm/drmserver/Android.mk b/drm/drmserver/Android.mk
index dc973da..48ea385 100644
--- a/drm/drmserver/Android.mk
+++ b/drm/drmserver/Android.mk
@@ -26,7 +26,8 @@ LOCAL_SHARED_LIBRARIES := \
libutils \
liblog \
libbinder \
- libdl
+ libdl \
+ libselinux
LOCAL_STATIC_LIBRARIES := libdrmframeworkcommon
@@ -39,4 +40,6 @@ LOCAL_MODULE:= drmserver
LOCAL_MODULE_TAGS := optional
+LOCAL_32_BIT_ONLY := true
+
include $(BUILD_EXECUTABLE)
diff --git a/drm/drmserver/DrmManager.cpp b/drm/drmserver/DrmManager.cpp
index dccd23d..d8aeb0c 100644
--- a/drm/drmserver/DrmManager.cpp
+++ b/drm/drmserver/DrmManager.cpp
@@ -101,7 +101,7 @@ status_t DrmManager::loadPlugIns() {
status_t DrmManager::loadPlugIns(const String8& plugInDirPath) {
mPlugInManager.loadPlugIns(plugInDirPath);
Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
- for (unsigned int i = 0; i < plugInPathList.size(); ++i) {
+ for (size_t i = 0; i < plugInPathList.size(); ++i) {
String8 plugInPath = plugInPathList[i];
DrmSupportInfo* info = mPlugInManager.getPlugIn(plugInPath).getSupportInfo(0);
if (NULL != info) {
@@ -138,7 +138,7 @@ void DrmManager::addClient(int uniqueId) {
Mutex::Autolock _l(mLock);
if (!mSupportInfoToPlugInIdMap.isEmpty()) {
Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
- for (unsigned int index = 0; index < plugInIdList.size(); index++) {
+ for (size_t index = 0; index < plugInIdList.size(); index++) {
IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
rDrmEngine.initialize(uniqueId);
rDrmEngine.setOnInfoListener(uniqueId, this);
@@ -149,7 +149,7 @@ void DrmManager::addClient(int uniqueId) {
void DrmManager::removeClient(int uniqueId) {
Mutex::Autolock _l(mLock);
Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
- for (unsigned int index = 0; index < plugInIdList.size(); index++) {
+ for (size_t index = 0; index < plugInIdList.size(); index++) {
IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
rDrmEngine.terminate(uniqueId);
}
@@ -208,7 +208,7 @@ bool DrmManager::canHandle(int uniqueId, const String8& path) {
bool result = false;
Vector<String8> plugInPathList = mPlugInManager.getPlugInIdList();
- for (unsigned int i = 0; i < plugInPathList.size(); ++i) {
+ for (size_t i = 0; i < plugInPathList.size(); ++i) {
IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInPathList[i]);
result = rDrmEngine.canHandle(uniqueId, path);
@@ -318,7 +318,7 @@ status_t DrmManager::removeRights(int uniqueId, const String8& path) {
status_t DrmManager::removeAllRights(int uniqueId) {
Vector<String8> plugInIdList = mPlugInManager.getPlugInIdList();
status_t result = DRM_ERROR_UNKNOWN;
- for (unsigned int index = 0; index < plugInIdList.size(); index++) {
+ for (size_t index = 0; index < plugInIdList.size(); index++) {
IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInIdList.itemAt(index));
result = rDrmEngine.removeAllRights(uniqueId);
if (DRM_NO_ERROR != result) {
@@ -412,7 +412,7 @@ DecryptHandle* DrmManager::openDecryptSession(
if (NULL != handle) {
handle->decryptId = mDecryptSessionId + 1;
- for (unsigned int index = 0; index < plugInIdList.size(); index++) {
+ for (size_t index = 0; index < plugInIdList.size(); index++) {
String8 plugInId = plugInIdList.itemAt(index);
IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
result = rDrmEngine.openDecryptSession(uniqueId, handle, fd, offset, length, mime);
@@ -440,7 +440,7 @@ DecryptHandle* DrmManager::openDecryptSession(
if (NULL != handle) {
handle->decryptId = mDecryptSessionId + 1;
- for (unsigned int index = 0; index < plugInIdList.size(); index++) {
+ for (size_t index = 0; index < plugInIdList.size(); index++) {
String8 plugInId = plugInIdList.itemAt(index);
IDrmEngine& rDrmEngine = mPlugInManager.getPlugIn(plugInId);
result = rDrmEngine.openDecryptSession(uniqueId, handle, uri, mime);
@@ -565,7 +565,7 @@ String8 DrmManager::getSupportedPlugInId(const String8& mimeType) {
String8 plugInId("");
if (EMPTY_STRING != mimeType) {
- for (unsigned int index = 0; index < mSupportInfoToPlugInIdMap.size(); index++) {
+ for (size_t index = 0; index < mSupportInfoToPlugInIdMap.size(); index++) {
const DrmSupportInfo& drmSupportInfo = mSupportInfoToPlugInIdMap.keyAt(index);
if (drmSupportInfo.isSupportedMimeType(mimeType)) {
@@ -581,7 +581,7 @@ String8 DrmManager::getSupportedPlugInIdFromPath(int uniqueId, const String8& pa
String8 plugInId("");
const String8 fileSuffix = path.getPathExtension();
- for (unsigned int index = 0; index < mSupportInfoToPlugInIdMap.size(); index++) {
+ for (size_t index = 0; index < mSupportInfoToPlugInIdMap.size(); index++) {
const DrmSupportInfo& drmSupportInfo = mSupportInfoToPlugInIdMap.keyAt(index);
if (drmSupportInfo.isSupportedFileSuffix(fileSuffix)) {
@@ -599,7 +599,7 @@ String8 DrmManager::getSupportedPlugInIdFromPath(int uniqueId, const String8& pa
void DrmManager::onInfo(const DrmInfoEvent& event) {
Mutex::Autolock _l(mListenerLock);
- for (unsigned int index = 0; index < mServiceListeners.size(); index++) {
+ for (size_t index = 0; index < mServiceListeners.size(); index++) {
int uniqueId = mServiceListeners.keyAt(index);
if (uniqueId == event.getUniqueId()) {
diff --git a/drm/drmserver/DrmManagerService.cpp b/drm/drmserver/DrmManagerService.cpp
index 2b71904..857d73e 100644
--- a/drm/drmserver/DrmManagerService.cpp
+++ b/drm/drmserver/DrmManagerService.cpp
@@ -29,12 +29,71 @@
#include "DrmManagerService.h"
#include "DrmManager.h"
+#include <selinux/android.h>
+
using namespace android;
+static int selinux_enabled;
+static char *drmserver_context;
static Vector<uid_t> trustedUids;
-static bool isProtectedCallAllowed() {
- return true;
+const char *const DrmManagerService::drm_perm_labels[] = {
+ "consumeRights",
+ "setPlaybackStatus",
+ "openDecryptSession",
+ "closeDecryptSession",
+ "initializeDecryptUnit",
+ "decrypt",
+ "finalizeDecryptUnit",
+ "pread"
+};
+
+const char *DrmManagerService::get_perm_label(drm_perm_t perm) {
+ unsigned int index = perm;
+
+ if (index < 0 ||
+ index >= (sizeof(drm_perm_labels) / sizeof(drm_perm_labels[0]))) {
+ ALOGE("SELinux: Failed to retrieve permission label(perm=%d).\n", perm);
+ abort();
+ }
+ return drm_perm_labels[index];
+}
+
+bool DrmManagerService::selinuxIsProtectedCallAllowed(pid_t spid, drm_perm_t perm) {
+ if (selinux_enabled <= 0) {
+ return true;
+ }
+
+ char *sctx;
+ const char *selinux_class = "drmservice";
+ const char *str_perm = get_perm_label(perm);
+
+ if (getpidcon(spid, &sctx) != 0) {
+ ALOGE("SELinux: getpidcon(pid=%d) failed.\n", spid);
+ return false;
+ }
+
+ bool allowed = (selinux_check_access(sctx, drmserver_context, selinux_class,
+ str_perm, NULL) == 0);
+ freecon(sctx);
+
+ return allowed;
+}
+
+bool DrmManagerService::isProtectedCallAllowed(drm_perm_t perm) {
+ // TODO
+ // Following implementation is just for reference.
+ // Each OEM manufacturer should implement/replace with their own solutions.
+ IPCThreadState* ipcState = IPCThreadState::self();
+ uid_t uid = ipcState->getCallingUid();
+ pid_t spid = ipcState->getCallingPid();
+
+ for (unsigned int i = 0; i < trustedUids.size(); ++i) {
+ if (trustedUids[i] == uid) {
+ return selinuxIsProtectedCallAllowed(spid, perm);
+ }
+ }
+ return false;
}
void DrmManagerService::instantiate() {
@@ -49,6 +108,16 @@ void DrmManagerService::instantiate() {
// Add trusted uids here
trustedUids.push(AID_MEDIA);
}
+
+ selinux_enabled = is_selinux_enabled();
+ if (selinux_enabled > 0 && getcon(&drmserver_context) != 0) {
+ ALOGE("SELinux: DrmManagerService failed to get context for DrmManagerService. Aborting.\n");
+ abort();
+ }
+
+ union selinux_callback cb;
+ cb.func_log = selinux_log_callback;
+ selinux_set_callback(SELINUX_CB_LOG, cb);
}
DrmManagerService::DrmManagerService() :
@@ -140,7 +209,7 @@ int DrmManagerService::checkRightsStatus(
status_t DrmManagerService::consumeRights(
int uniqueId, DecryptHandle* decryptHandle, int action, bool reserve) {
ALOGV("Entering consumeRights");
- if (!isProtectedCallAllowed()) {
+ if (!isProtectedCallAllowed(CONSUME_RIGHTS)) {
return DRM_ERROR_NO_PERMISSION;
}
return mDrmManager->consumeRights(uniqueId, decryptHandle, action, reserve);
@@ -149,7 +218,7 @@ status_t DrmManagerService::consumeRights(
status_t DrmManagerService::setPlaybackStatus(
int uniqueId, DecryptHandle* decryptHandle, int playbackStatus, int64_t position) {
ALOGV("Entering setPlaybackStatus");
- if (!isProtectedCallAllowed()) {
+ if (!isProtectedCallAllowed(SET_PLAYBACK_STATUS)) {
return DRM_ERROR_NO_PERMISSION;
}
return mDrmManager->setPlaybackStatus(uniqueId, decryptHandle, playbackStatus, position);
@@ -197,7 +266,7 @@ status_t DrmManagerService::getAllSupportInfo(
DecryptHandle* DrmManagerService::openDecryptSession(
int uniqueId, int fd, off64_t offset, off64_t length, const char* mime) {
ALOGV("Entering DrmManagerService::openDecryptSession");
- if (isProtectedCallAllowed()) {
+ if (isProtectedCallAllowed(OPEN_DECRYPT_SESSION)) {
return mDrmManager->openDecryptSession(uniqueId, fd, offset, length, mime);
}
@@ -207,7 +276,7 @@ DecryptHandle* DrmManagerService::openDecryptSession(
DecryptHandle* DrmManagerService::openDecryptSession(
int uniqueId, const char* uri, const char* mime) {
ALOGV("Entering DrmManagerService::openDecryptSession with uri");
- if (isProtectedCallAllowed()) {
+ if (isProtectedCallAllowed(OPEN_DECRYPT_SESSION)) {
return mDrmManager->openDecryptSession(uniqueId, uri, mime);
}
@@ -217,7 +286,7 @@ DecryptHandle* DrmManagerService::openDecryptSession(
DecryptHandle* DrmManagerService::openDecryptSession(
int uniqueId, const DrmBuffer& buf, const String8& mimeType) {
ALOGV("Entering DrmManagerService::openDecryptSession for streaming");
- if (isProtectedCallAllowed()) {
+ if (isProtectedCallAllowed(OPEN_DECRYPT_SESSION)) {
return mDrmManager->openDecryptSession(uniqueId, buf, mimeType);
}
@@ -226,7 +295,7 @@ DecryptHandle* DrmManagerService::openDecryptSession(
status_t DrmManagerService::closeDecryptSession(int uniqueId, DecryptHandle* decryptHandle) {
ALOGV("Entering closeDecryptSession");
- if (!isProtectedCallAllowed()) {
+ if (!isProtectedCallAllowed(CLOSE_DECRYPT_SESSION)) {
return DRM_ERROR_NO_PERMISSION;
}
return mDrmManager->closeDecryptSession(uniqueId, decryptHandle);
@@ -235,7 +304,7 @@ status_t DrmManagerService::closeDecryptSession(int uniqueId, DecryptHandle* dec
status_t DrmManagerService::initializeDecryptUnit(int uniqueId, DecryptHandle* decryptHandle,
int decryptUnitId, const DrmBuffer* headerInfo) {
ALOGV("Entering initializeDecryptUnit");
- if (!isProtectedCallAllowed()) {
+ if (!isProtectedCallAllowed(INITIALIZE_DECRYPT_UNIT)) {
return DRM_ERROR_NO_PERMISSION;
}
return mDrmManager->initializeDecryptUnit(uniqueId,decryptHandle, decryptUnitId, headerInfo);
@@ -245,7 +314,7 @@ status_t DrmManagerService::decrypt(
int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId,
const DrmBuffer* encBuffer, DrmBuffer** decBuffer, DrmBuffer* IV) {
ALOGV("Entering decrypt");
- if (!isProtectedCallAllowed()) {
+ if (!isProtectedCallAllowed(DECRYPT)) {
return DRM_ERROR_NO_PERMISSION;
}
return mDrmManager->decrypt(uniqueId, decryptHandle, decryptUnitId, encBuffer, decBuffer, IV);
@@ -254,7 +323,7 @@ status_t DrmManagerService::decrypt(
status_t DrmManagerService::finalizeDecryptUnit(
int uniqueId, DecryptHandle* decryptHandle, int decryptUnitId) {
ALOGV("Entering finalizeDecryptUnit");
- if (!isProtectedCallAllowed()) {
+ if (!isProtectedCallAllowed(FINALIZE_DECRYPT_UNIT)) {
return DRM_ERROR_NO_PERMISSION;
}
return mDrmManager->finalizeDecryptUnit(uniqueId, decryptHandle, decryptUnitId);
@@ -263,7 +332,7 @@ status_t DrmManagerService::finalizeDecryptUnit(
ssize_t DrmManagerService::pread(int uniqueId, DecryptHandle* decryptHandle,
void* buffer, ssize_t numBytes, off64_t offset) {
ALOGV("Entering pread");
- if (!isProtectedCallAllowed()) {
+ if (!isProtectedCallAllowed(PREAD)) {
return DRM_ERROR_NO_PERMISSION;
}
return mDrmManager->pread(uniqueId, decryptHandle, buffer, numBytes, offset);
diff --git a/drm/libdrmframework/include/DrmManagerService.h b/drm/libdrmframework/include/DrmManagerService.h
index 8bc59b4..45cee2e 100644
--- a/drm/libdrmframework/include/DrmManagerService.h
+++ b/drm/libdrmframework/include/DrmManagerService.h
@@ -42,9 +42,28 @@ public:
static void instantiate();
private:
+ enum drm_perm_t {
+ CONSUME_RIGHTS = 0,
+ SET_PLAYBACK_STATUS = 1,
+ OPEN_DECRYPT_SESSION = 2,
+ CLOSE_DECRYPT_SESSION = 3,
+ INITIALIZE_DECRYPT_UNIT = 4,
+ DECRYPT = 5,
+ FINALIZE_DECRYPT_UNIT = 6,
+ PREAD = 7,
+ };
+
+ static const char *const drm_perm_labels[];
+
DrmManagerService();
virtual ~DrmManagerService();
+ static const char *get_perm_label(drm_perm_t perm);
+
+ static bool selinuxIsProtectedCallAllowed(pid_t spid, drm_perm_t perm);
+
+ static bool isProtectedCallAllowed(drm_perm_t perm);
+
public:
int addUniqueId(bool isNative);
diff --git a/drm/libdrmframework/include/PlugInManager.h b/drm/libdrmframework/include/PlugInManager.h
index 7bb143f..c1d019a 100644
--- a/drm/libdrmframework/include/PlugInManager.h
+++ b/drm/libdrmframework/include/PlugInManager.h
@@ -80,7 +80,7 @@ public:
Vector<String8> plugInFileList = getPlugInPathList(rsPlugInDirPath);
if (!plugInFileList.isEmpty()) {
- for (unsigned int i = 0; i < plugInFileList.size(); ++i) {
+ for (size_t i = 0; i < plugInFileList.size(); ++i) {
loadPlugIn(plugInFileList[i]);
}
}
@@ -91,7 +91,7 @@ public:
*
*/
void unloadPlugIns() {
- for (unsigned int i = 0; i < m_plugInIdList.size(); ++i) {
+ for (size_t i = 0; i < m_plugInIdList.size(); ++i) {
unloadPlugIn(m_plugInIdList[i]);
}
m_plugInIdList.clear();
diff --git a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/Android.mk b/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/Android.mk
index e251f82..48b0afe 100644
--- a/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/Android.mk
+++ b/drm/libdrmframework/plugins/forward-lock/FwdLockEngine/Android.mk
@@ -61,7 +61,7 @@ LOCAL_C_INCLUDES += \
$(LOCAL_PATH)/include \
external/openssl/include
-LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/drm
+LOCAL_MODULE_RELATIVE_PATH := drm
LOCAL_MODULE_TAGS := optional
diff --git a/drm/mediadrm/plugins/mock/Android.mk b/drm/mediadrm/plugins/mock/Android.mk
index ada23a2..26c245b 100644
--- a/drm/mediadrm/plugins/mock/Android.mk
+++ b/drm/mediadrm/plugins/mock/Android.mk
@@ -21,7 +21,8 @@ LOCAL_SRC_FILES:= \
LOCAL_MODULE := libmockdrmcryptoplugin
-LOCAL_MODULE_PATH := $(TARGET_OUT_VENDOR_SHARED_LIBRARIES)/mediadrm
+LOCAL_PROPRIETARY_MODULE := true
+LOCAL_MODULE_RELATIVE_PATH := mediadrm
LOCAL_SHARED_LIBRARIES := \
libutils liblog
diff --git a/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp b/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp
index f2cadf7..69fa7a0 100644
--- a/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp
+++ b/drm/mediadrm/plugins/mock/MockDrmCryptoPlugin.cpp
@@ -695,7 +695,7 @@ namespace android {
{
String8 result;
for (size_t i = 0; i < numSubSamples; i++) {
- result.appendFormat("[%d] {clear:%d, encrypted:%d} ", i,
+ result.appendFormat("[%zu] {clear:%zu, encrypted:%zu} ", i,
subSamples[i].mNumBytesOfClearData,
subSamples[i].mNumBytesOfEncryptedData);
}
diff --git a/include/camera/CameraParameters2.h b/include/camera/CameraParameters2.h
new file mode 100644
index 0000000..88ad812
--- /dev/null
+++ b/include/camera/CameraParameters2.h
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HARDWARE_CAMERA_PARAMETERS2_H
+#define ANDROID_HARDWARE_CAMERA_PARAMETERS2_H
+
+#include <utils/Vector.h>
+#include <utils/String8.h>
+#include "CameraParameters.h"
+
+namespace android {
+
+/**
+ * A copy of CameraParameters plus ABI-breaking changes. Needed
+ * because some camera HALs directly link to CameraParameters and cannot
+ * tolerate an ABI change.
+ */
+class CameraParameters2
+{
+public:
+ CameraParameters2();
+ CameraParameters2(const String8 &params) { unflatten(params); }
+ ~CameraParameters2();
+
+ String8 flatten() const;
+ void unflatten(const String8 &params);
+
+ void set(const char *key, const char *value);
+ void set(const char *key, int value);
+ void setFloat(const char *key, float value);
+ // Look up string value by key.
+ // -- The string remains valid until the next set/remove of the same key,
+ // or until the map gets cleared.
+ const char *get(const char *key) const;
+ int getInt(const char *key) const;
+ float getFloat(const char *key) const;
+
+ // Compare the order that key1 was set vs the order that key2 was set.
+ //
+ // Sets the order parameter to an integer less than, equal to, or greater
+ // than zero if key1's set order was respectively, to be less than, to
+ // match, or to be greater than key2's set order.
+ //
+ // Error codes:
+ // * NAME_NOT_FOUND - if either key has not been set previously
+ // * BAD_VALUE - if any of the parameters are NULL
+ status_t compareSetOrder(const char *key1, const char *key2,
+ /*out*/
+ int *order) const;
+
+ void remove(const char *key);
+
+ void setPreviewSize(int width, int height);
+ void getPreviewSize(int *width, int *height) const;
+ void getSupportedPreviewSizes(Vector<Size> &sizes) const;
+
+ // Set the dimensions in pixels to the given width and height
+ // for video frames. The given width and height must be one
+ // of the supported dimensions returned from
+ // getSupportedVideoSizes(). Must not be called if
+ // getSupportedVideoSizes() returns an empty Vector of Size.
+ void setVideoSize(int width, int height);
+ // Retrieve the current dimensions (width and height)
+ // in pixels for video frames, which must be one of the
+ // supported dimensions returned from getSupportedVideoSizes().
+ // Must not be called if getSupportedVideoSizes() returns an
+ // empty Vector of Size.
+ void getVideoSize(int *width, int *height) const;
+ // Retrieve a Vector of supported dimensions (width and height)
+ // in pixels for video frames. If sizes returned from the method
+ // is empty, the camera does not support calls to setVideoSize()
+ // or getVideoSize(). In adddition, it also indicates that
+ // the camera only has a single output, and does not have
+ // separate output for video frames and preview frame.
+ void getSupportedVideoSizes(Vector<Size> &sizes) const;
+ // Retrieve the preferred preview size (width and height) in pixels
+ // for video recording. The given width and height must be one of
+ // supported preview sizes returned from getSupportedPreviewSizes().
+ // Must not be called if getSupportedVideoSizes() returns an empty
+ // Vector of Size. If getSupportedVideoSizes() returns an empty
+ // Vector of Size, the width and height returned from this method
+ // is invalid, and is "-1x-1".
+ void getPreferredPreviewSizeForVideo(int *width, int *height) const;
+
+ void setPreviewFrameRate(int fps);
+ int getPreviewFrameRate() const;
+ void getPreviewFpsRange(int *min_fps, int *max_fps) const;
+ void setPreviewFpsRange(int min_fps, int max_fps);
+ void setPreviewFormat(const char *format);
+ const char *getPreviewFormat() const;
+ void setPictureSize(int width, int height);
+ void getPictureSize(int *width, int *height) const;
+ void getSupportedPictureSizes(Vector<Size> &sizes) const;
+ void setPictureFormat(const char *format);
+ const char *getPictureFormat() const;
+
+ void dump() const;
+ status_t dump(int fd, const Vector<String16>& args) const;
+
+private:
+
+ // Quick and dirty map that maintains insertion order
+ template <typename KeyT, typename ValueT>
+ struct OrderedKeyedVector {
+
+ ssize_t add(const KeyT& key, const ValueT& value) {
+ return mList.add(Pair(key, value));
+ }
+
+ size_t size() const {
+ return mList.size();
+ }
+
+ const KeyT& keyAt(size_t idx) const {
+ return mList[idx].mKey;
+ }
+
+ const ValueT& valueAt(size_t idx) const {
+ return mList[idx].mValue;
+ }
+
+ const ValueT& valueFor(const KeyT& key) const {
+ ssize_t i = indexOfKey(key);
+ LOG_ALWAYS_FATAL_IF(i<0, "%s: key not found", __PRETTY_FUNCTION__);
+
+ return valueAt(i);
+ }
+
+ ssize_t indexOfKey(const KeyT& key) const {
+ size_t vectorIdx = 0;
+ for (; vectorIdx < mList.size(); ++vectorIdx) {
+ if (mList[vectorIdx].mKey == key) {
+ return (ssize_t) vectorIdx;
+ }
+ }
+
+ return NAME_NOT_FOUND;
+ }
+
+ ssize_t removeItem(const KeyT& key) {
+ size_t vectorIdx = (size_t) indexOfKey(key);
+
+ if (vectorIdx < 0) {
+ return vectorIdx;
+ }
+
+ return mList.removeAt(vectorIdx);
+ }
+
+ void clear() {
+ mList.clear();
+ }
+
+ // Same as removing and re-adding. The key's index changes to max.
+ ssize_t replaceValueFor(const KeyT& key, const ValueT& value) {
+ removeItem(key);
+ return add(key, value);
+ }
+
+ private:
+
+ struct Pair {
+ Pair() : mKey(), mValue() {}
+ Pair(const KeyT& key, const ValueT& value) :
+ mKey(key),
+ mValue(value) {}
+ KeyT mKey;
+ ValueT mValue;
+ };
+
+ Vector<Pair> mList;
+ };
+
+ /**
+ * Order matters: Keys that are set() later are stored later in the map.
+ *
+ * If two keys have meaning that conflict, then the later-set key
+ * wins.
+ *
+ * For example, preview FPS and preview FPS range conflict since only
+ * we only want to use the FPS range if that's the last thing that was set.
+ * So in that case, only use preview FPS range if it was set later than
+ * the preview FPS.
+ */
+ OrderedKeyedVector<String8,String8> mMap;
+};
+
+}; // namespace android
+
+#endif
diff --git a/include/media/AudioSystem.h b/include/media/AudioSystem.h
index 225ef76..4c22412 100644
--- a/include/media/AudioSystem.h
+++ b/include/media/AudioSystem.h
@@ -127,8 +127,8 @@ public:
// NOTE: this feature is not supported on all hardware platforms and it is
// necessary to check returned status before using the returned values.
static status_t getRenderPosition(audio_io_handle_t output,
- size_t *halFrames,
- size_t *dspFrames,
+ uint32_t *halFrames,
+ uint32_t *dspFrames,
audio_stream_type_t stream = AUDIO_STREAM_DEFAULT);
// return the number of input frames lost by HAL implementation, or 0 if the handle is invalid
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index f379ee5..4736369 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -661,7 +661,7 @@ protected:
sp<AudioTrackThread> mAudioTrackThread;
float mVolume[2];
float mSendLevel;
- uint32_t mSampleRate;
+ mutable uint32_t mSampleRate; // mutable because getSampleRate() can update it.
size_t mFrameCount; // corresponds to current IAudioTrack
size_t mReqFrameCount; // frame count to request the next time a new
// IAudioTrack is needed
@@ -740,6 +740,7 @@ protected:
bool mInUnderrun; // whether track is currently in underrun state
String8 mName; // server's name for this IAudioTrack
+ uint32_t mPausedPosition;
private:
class DeathNotifier : public IBinder::DeathRecipient {
diff --git a/include/media/EffectsFactoryApi.h b/include/media/EffectsFactoryApi.h
index b1143b9..b1ed7b0 100644
--- a/include/media/EffectsFactoryApi.h
+++ b/include/media/EffectsFactoryApi.h
@@ -171,30 +171,6 @@ int EffectGetDescriptor(const effect_uuid_t *pEffectUuid, effect_descriptor_t *p
////////////////////////////////////////////////////////////////////////////////
int EffectIsNullUuid(const effect_uuid_t *pEffectUuid);
-////////////////////////////////////////////////////////////////////////////////
-//
-// Function: EffectGetSubEffects
-//
-// Description: Returns the descriptors of the sub effects of the effect
-// whose uuid is pointed to by first argument.
-//
-// Input:
-// pEffectUuid: pointer to the effect uuid.
-// size: size of the buffer pointed by pDescriptor.
-//
-// Input/Output:
-// pDescriptor: address where to return the sub effect descriptors.
-//
-// Output:
-// returned value: 0 successful operation.
-// -ENODEV factory failed to initialize
-// -EINVAL invalid pEffectUuid or pDescriptor
-// -ENOENT no effect with this uuid found
-// *pDescriptor: updated with the sub effect descriptors.
-//
-////////////////////////////////////////////////////////////////////////////////
-int EffectGetSubEffects(const effect_uuid_t *pEffectUuid, effect_descriptor_t *pDescriptors, size_t size);
-
#if __cplusplus
} // extern "C"
#endif
diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h
index 899d79f..282f275 100644
--- a/include/media/IAudioFlinger.h
+++ b/include/media/IAudioFlinger.h
@@ -167,10 +167,10 @@ public:
virtual status_t setVoiceVolume(float volume) = 0;
- virtual status_t getRenderPosition(size_t *halFrames, size_t *dspFrames,
+ virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames,
audio_io_handle_t output) const = 0;
- virtual size_t getInputFramesLost(audio_io_handle_t ioHandle) const = 0;
+ virtual uint32_t getInputFramesLost(audio_io_handle_t ioHandle) const = 0;
virtual int newAudioSessionId() = 0;
diff --git a/include/media/IOMX.h b/include/media/IOMX.h
index 9c8451c..b74a2c7 100644
--- a/include/media/IOMX.h
+++ b/include/media/IOMX.h
@@ -38,8 +38,8 @@ class IOMX : public IInterface {
public:
DECLARE_META_INTERFACE(OMX);
- typedef void *buffer_id;
- typedef void *node_id;
+ typedef uint32_t buffer_id;
+ typedef uint32_t node_id;
// Given a node_id and the calling process' pid, returns true iff
// the implementation of the OMX interface lives in the same
@@ -142,6 +142,7 @@ public:
enum InternalOptionType {
INTERNAL_OPTION_SUSPEND, // data is a bool
INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY, // data is an int64_t
+ INTERNAL_OPTION_MAX_TIMESTAMP_GAP, // data is int64_t
};
virtual status_t setInternalOption(
node_id node,
diff --git a/include/media/MediaMetadataRetrieverInterface.h b/include/media/MediaMetadataRetrieverInterface.h
index ecc3b65..cd5bf88 100644
--- a/include/media/MediaMetadataRetrieverInterface.h
+++ b/include/media/MediaMetadataRetrieverInterface.h
@@ -20,6 +20,7 @@
#include <utils/RefBase.h>
#include <media/mediametadataretriever.h>
+#include <media/mediascanner.h>
#include <private/media/VideoFrame.h>
namespace android {
diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h
index cc244f0..26d8729 100644
--- a/include/media/MediaPlayerInterface.h
+++ b/include/media/MediaPlayerInterface.h
@@ -100,6 +100,7 @@ public:
virtual status_t getFramesWritten(uint32_t *frameswritten) const = 0;
virtual int getSessionId() const = 0;
virtual audio_stream_type_t getAudioStreamType() const = 0;
+ virtual uint32_t getSampleRate() const = 0;
// If no callback is specified, use the "write" API below to submit
// audio data.
diff --git a/include/media/mediascanner.h b/include/media/mediascanner.h
index a73403b..37a83c6 100644
--- a/include/media/mediascanner.h
+++ b/include/media/mediascanner.h
@@ -41,6 +41,31 @@ enum MediaScanResult {
MEDIA_SCAN_RESULT_ERROR,
};
+struct MediaAlbumArt {
+public:
+ static MediaAlbumArt *fromData(int32_t size, const void* data);
+
+ static void init(MediaAlbumArt* instance, int32_t size, const void* data);
+
+ MediaAlbumArt *clone();
+
+ const char *data() {
+ return &mData[0];
+ }
+
+ int32_t size() {
+ return mSize;
+ }
+
+private:
+ int32_t mSize;
+ char mData[];
+
+ // You can't construct instances of this class directly because this is a
+ // variable-sized object passed through the binder.
+ MediaAlbumArt();
+} __packed;
+
struct MediaScanner {
MediaScanner();
virtual ~MediaScanner();
@@ -53,8 +78,7 @@ struct MediaScanner {
void setLocale(const char *locale);
- // extracts album art as a block of data
- virtual char *extractAlbumArt(int fd) = 0;
+ virtual MediaAlbumArt *extractAlbumArt(int fd) = 0;
protected:
const char *locale() const;
diff --git a/include/media/nbaio/NBLog.h b/include/media/nbaio/NBLog.h
index 6d59ea7..bcbbc04 100644
--- a/include/media/nbaio/NBLog.h
+++ b/include/media/nbaio/NBLog.h
@@ -25,6 +25,8 @@
namespace android {
+class String8;
+
class NBLog {
public:
@@ -187,6 +189,10 @@ private:
const Shared* const mShared; // raw pointer to shared memory
const sp<IMemory> mIMemory; // ref-counted version
int32_t mFront; // index of oldest acknowledged Entry
+ int mFd; // file descriptor
+ int mIndent; // indentation level
+
+ void dumpLine(const String8& timestamp, String8& body);
static const size_t kSquashTimestamp = 5; // squash this many or more adjacent timestamps
};
diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h
index e796ab3..46c62dc 100644
--- a/include/media/stagefright/ACodec.h
+++ b/include/media/stagefright/ACodec.h
@@ -67,6 +67,8 @@ struct ACodec : public AHierarchicalStateMachine {
void signalRequestIDRFrame();
+ bool isConfiguredForAdaptivePlayback() { return mIsConfiguredForAdaptivePlayback; }
+
struct PortDescription : public RefBase {
size_t countBuffers();
IOMX::buffer_id bufferIDAt(size_t index) const;
@@ -116,6 +118,7 @@ private:
kWhatStart = 'star',
kWhatRequestIDRFrame = 'ridr',
kWhatSetParameters = 'setP',
+ kWhatSubmitOutputMetaDataBufferIfEOS = 'subm',
};
enum {
@@ -186,6 +189,7 @@ private:
bool mIsEncoder;
bool mUseMetadataOnEncoderOutput;
bool mShutdownInProgress;
+ bool mIsConfiguredForAdaptivePlayback;
// If "mKeepComponentAllocated" we only transition back to Loaded state
// and do not release the component instance.
@@ -199,8 +203,10 @@ private:
unsigned mDequeueCounter;
bool mStoreMetaDataInOutputBuffers;
int32_t mMetaDataBuffersToSubmit;
+ size_t mNumUndequeuedBuffers;
int64_t mRepeatFrameDelayUs;
+ int64_t mMaxPtsGapUs;
status_t setCyclicIntraMacroblockRefresh(const sp<AMessage> &msg, int32_t mode);
status_t allocateBuffersOnPort(OMX_U32 portIndex);
@@ -212,6 +218,7 @@ private:
OMX_U32 *nMinUndequeuedBuffers);
status_t allocateOutputMetaDataBuffers();
status_t submitOutputMetaDataBuffer();
+ void signalSubmitOutputMetaDataBufferIfEOS_workaround();
status_t allocateOutputBuffersFromNativeWindow();
status_t cancelBufferToNativeWindow(BufferInfo *info);
status_t freeOutputBuffersNotOwnedByComponent();
diff --git a/include/media/stagefright/AudioPlayer.h b/include/media/stagefright/AudioPlayer.h
index 912a43c..14afb85 100644
--- a/include/media/stagefright/AudioPlayer.h
+++ b/include/media/stagefright/AudioPlayer.h
@@ -129,7 +129,7 @@ private:
void reset();
uint32_t getNumFramesPendingPlayout() const;
- int64_t getOutputPlayPositionUs_l() const;
+ int64_t getOutputPlayPositionUs_l();
bool allowDeepBuffering() const { return (mCreateFlags & ALLOW_DEEP_BUFFERING) != 0; }
bool useOffload() const { return (mCreateFlags & USE_OFFLOAD) != 0; }
diff --git a/include/media/stagefright/ClockEstimator.h b/include/media/stagefright/ClockEstimator.h
new file mode 100644
index 0000000..2fd6e75
--- /dev/null
+++ b/include/media/stagefright/ClockEstimator.h
@@ -0,0 +1,110 @@
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#ifndef CLOCK_ESTIMATOR_H_
+
+#define CLOCK_ESTIMATOR_H_
+
+
+#include <utils/RefBase.h>
+#include <utils/Vector.h>
+
+namespace android {
+// ---------------------------------------------------------------------------
+
+struct ClockEstimator : RefBase {
+ virtual double estimate(double x, double y) = 0;
+ virtual void reset() = 0;
+};
+
+struct WindowedLinearFitEstimator : ClockEstimator {
+ struct LinearFit {
+ /**
+ * Fit y = a * x + b, where each input has a weight
+ */
+ double mX; // sum(w_i * x_i)
+ double mXX; // sum(w_i * x_i^2)
+ double mY; // sum(w_i * y_i)
+ double mYY; // sum(w_i * y_i^2)
+ double mXY; // sum(w_i * x_i * y_i)
+ double mW; // sum(w_i)
+
+ LinearFit();
+ void reset();
+ void combine(const LinearFit &lf);
+ void add(double x, double y, double w);
+ void scale(double w);
+ double interpolate(double x);
+ double size() const;
+
+ DISALLOW_EVIL_CONSTRUCTORS(LinearFit);
+ };
+
+ /**
+ * Estimator for f(x) = y' where input y' is noisy, but
+ * theoretically linear:
+ *
+ * y' =~ y = a * x + b
+ *
+ * It uses linear fit regression over a tapering rolling window
+ * to get an estimate for y (from the current and past inputs
+ * (x, y')).
+ *
+ * ____________
+ * /| |\
+ * / | | \
+ * / | | \ <--- new data (x, y')
+ * / | main | \
+ * <--><----------><-->
+ * tail head
+ *
+ * weight is 1 under the main window, tapers exponentially by
+ * the factors given in the head and the tail.
+ *
+ * Assuming that x and y' are monotonic, that x is somewhat
+ * evenly sampled, and that a =~ 1, the estimated y is also
+ * going to be monotonic.
+ */
+ WindowedLinearFitEstimator(
+ size_t headLength = 5, double headFactor = 0.5,
+ size_t mainLength = 0, double tailFactor = 0.99);
+
+ virtual void reset();
+
+ // add a new sample (x -> y') and return an estimated value for the true y
+ virtual double estimate(double x, double y);
+
+private:
+ Vector<double> mXHistory; // circular buffer
+ Vector<double> mYHistory; // circular buffer
+ LinearFit mHead;
+ LinearFit mMain;
+ LinearFit mTail;
+ double mHeadFactorInv;
+ double mTailFactor;
+ double mFirstWeight;
+ size_t mHistoryLength;
+ size_t mHeadLength;
+ size_t mNumSamples;
+ size_t mSampleIx;
+
+ DISALLOW_EVIL_CONSTRUCTORS(WindowedLinearFitEstimator);
+};
+
+}; // namespace android
+
+#endif
diff --git a/include/media/stagefright/FileSource.h b/include/media/stagefright/FileSource.h
index d994cb3..be152e7 100644
--- a/include/media/stagefright/FileSource.h
+++ b/include/media/stagefright/FileSource.h
@@ -55,7 +55,7 @@ private:
sp<DecryptHandle> mDecryptHandle;
DrmManagerClient *mDrmManagerClient;
int64_t mDrmBufOffset;
- int64_t mDrmBufSize;
+ size_t mDrmBufSize;
unsigned char *mDrmBuf;
ssize_t readAtDRM(off64_t offset, void *data, size_t size);
diff --git a/include/media/stagefright/MediaCodec.h b/include/media/stagefright/MediaCodec.h
index 76aa503..1f17efe 100644
--- a/include/media/stagefright/MediaCodec.h
+++ b/include/media/stagefright/MediaCodec.h
@@ -182,7 +182,7 @@ private:
};
struct BufferInfo {
- void *mBufferID;
+ uint32_t mBufferID;
sp<ABuffer> mData;
sp<ABuffer> mEncryptedData;
sp<AMessage> mNotify;
diff --git a/include/media/stagefright/MediaSource.h b/include/media/stagefright/MediaSource.h
index 3818e63..204d1c6 100644
--- a/include/media/stagefright/MediaSource.h
+++ b/include/media/stagefright/MediaSource.h
@@ -105,7 +105,7 @@ struct MediaSource : public virtual RefBase {
// This will be called after a successful start() and before the
// first read() call.
// Callee assumes ownership of the buffers if no error is returned.
- virtual status_t setBuffers(const Vector<MediaBuffer *> &buffers) {
+ virtual status_t setBuffers(const Vector<MediaBuffer *> & /* buffers */) {
return ERROR_UNSUPPORTED;
}
diff --git a/include/media/stagefright/MetaData.h b/include/media/stagefright/MetaData.h
index de3fc36..db8216b 100644
--- a/include/media/stagefright/MetaData.h
+++ b/include/media/stagefright/MetaData.h
@@ -134,6 +134,7 @@ enum {
kKeyRequiresSecureBuffers = 'secu', // bool (int32_t)
kKeyIsADTS = 'adts', // bool (int32_t)
+ kKeyAACAOT = 'aaot', // int32_t
// If a MediaBuffer's data represents (at least partially) encrypted
// data, the following fields aid in decryption.
@@ -214,6 +215,8 @@ public:
bool findData(uint32_t key, uint32_t *type,
const void **data, size_t *size) const;
+ bool hasData(uint32_t key) const;
+
void dumpToLog() const;
protected:
diff --git a/include/media/stagefright/StagefrightMediaScanner.h b/include/media/stagefright/StagefrightMediaScanner.h
index 6510a59..eb3accc 100644
--- a/include/media/stagefright/StagefrightMediaScanner.h
+++ b/include/media/stagefright/StagefrightMediaScanner.h
@@ -30,7 +30,7 @@ struct StagefrightMediaScanner : public MediaScanner {
const char *path, const char *mimeType,
MediaScannerClient &client);
- virtual char *extractAlbumArt(int fd);
+ virtual MediaAlbumArt *extractAlbumArt(int fd);
private:
StagefrightMediaScanner(const StagefrightMediaScanner &);
diff --git a/include/private/media/AudioTrackShared.h b/include/private/media/AudioTrackShared.h
index 7fd9379..2d033e6 100644
--- a/include/private/media/AudioTrackShared.h
+++ b/include/private/media/AudioTrackShared.h
@@ -65,7 +65,9 @@ typedef SingleStateQueue<StaticAudioTrackState> StaticAudioTrackSingleStateQueue
struct AudioTrackSharedStatic {
StaticAudioTrackSingleStateQueue::Shared
mSingleStateQueue;
- size_t mBufferPosition; // updated asynchronously by server,
+ // This field should be a size_t, but since it is located in shared memory we
+ // force to 32-bit. The client and server may have different typedefs for size_t.
+ uint32_t mBufferPosition; // updated asynchronously by server,
// "for entertainment purposes only"
};
@@ -108,7 +110,9 @@ struct audio_track_cblk_t
private:
- size_t mMinimum; // server wakes up client if available >= mMinimum
+ // This field should be a size_t, but since it is located in shared memory we
+ // force to 32-bit. The client and server may have different typedefs for size_t.
+ uint32_t mMinimum; // server wakes up client if available >= mMinimum
// Channel volumes are fixed point U4.12, so 0x1000 means 1.0.
// Left channel is in [0:15], right channel is in [16:31].
@@ -245,7 +249,11 @@ public:
}
void setMinimum(size_t minimum) {
- mCblk->mMinimum = minimum;
+ // This can only happen on a 64-bit client
+ if (minimum > UINT32_MAX) {
+ minimum = UINT32_MAX;
+ }
+ mCblk->mMinimum = (uint32_t) minimum;
}
// Return the number of frames that would need to be obtained and released
diff --git a/include/private/media/StaticAudioTrackState.h b/include/private/media/StaticAudioTrackState.h
index 46a5946..d483061 100644
--- a/include/private/media/StaticAudioTrackState.h
+++ b/include/private/media/StaticAudioTrackState.h
@@ -25,9 +25,13 @@ namespace android {
// state is wrapped by a SingleStateQueue.
struct StaticAudioTrackState {
// do not define constructors, destructors, or virtual methods
- size_t mLoopStart;
- size_t mLoopEnd;
- int mLoopCount;
+
+ // These fields should both be size_t, but since they are located in shared memory we
+ // force to 32-bit. The client and server may have different typedefs for size_t.
+ uint32_t mLoopStart;
+ uint32_t mLoopEnd;
+
+ int mLoopCount;
};
} // namespace android
diff --git a/include/private/media/VideoFrame.h b/include/private/media/VideoFrame.h
index a211ed9..5dd425b 100644
--- a/include/private/media/VideoFrame.h
+++ b/include/private/media/VideoFrame.h
@@ -25,64 +25,6 @@
namespace android {
-// A simple buffer to hold binary data
-class MediaAlbumArt
-{
-public:
- MediaAlbumArt(): mSize(0), mData(0) {}
-
- explicit MediaAlbumArt(const char* url) {
- mSize = 0;
- mData = NULL;
- FILE *in = fopen(url, "r");
- if (!in) {
- return;
- }
- fseek(in, 0, SEEK_END);
- mSize = ftell(in); // Allocating buffer of size equals to the external file size.
- if (mSize == 0 || (mData = new uint8_t[mSize]) == NULL) {
- fclose(in);
- if (mSize != 0) {
- mSize = 0;
- }
- return;
- }
- rewind(in);
- if (fread(mData, 1, mSize, in) != mSize) { // Read failed.
- delete[] mData;
- mData = NULL;
- mSize = 0;
- return;
- }
- fclose(in);
- }
-
- MediaAlbumArt(const MediaAlbumArt& copy) {
- mSize = copy.mSize;
- mData = NULL; // initialize it first
- if (mSize > 0 && copy.mData != NULL) {
- mData = new uint8_t[copy.mSize];
- if (mData != NULL) {
- memcpy(mData, copy.mData, mSize);
- } else {
- mSize = 0;
- }
- }
- }
-
- ~MediaAlbumArt() {
- if (mData != 0) {
- delete[] mData;
- }
- }
-
- // Intentional public access modifier:
- // We have to know the internal structure in order to share it between
- // processes?
- uint32_t mSize; // Number of bytes in mData
- uint8_t* mData; // Actual binary data
-};
-
// Represents a color converted (RGB-based) video frame
// with bitmap pixels stored in FrameBuffer
class VideoFrame
diff --git a/libvideoeditor/lvpp/Android.mk b/libvideoeditor/lvpp/Android.mk
index 2286827..a84ddad 100755
--- a/libvideoeditor/lvpp/Android.mk
+++ b/libvideoeditor/lvpp/Android.mk
@@ -46,7 +46,7 @@ LOCAL_STATIC_LIBRARIES := \
LOCAL_SHARED_LIBRARIES := \
- libaudioflinger \
+ libaudioresampler \
libaudioutils \
libbinder \
libcutils \
@@ -81,15 +81,10 @@ LOCAL_C_INCLUDES += \
$(TOP)/frameworks/av/services/audioflinger \
$(TOP)/frameworks/native/include/media/editor \
$(TOP)/frameworks/native/include/media/openmax \
- $(TOP)/frameworks/native/services/audioflinger
LOCAL_SHARED_LIBRARIES += libdl
-# All of the shared libraries we link against.
-LOCAL_LDLIBS := \
- -lpthread -ldl
-
LOCAL_CFLAGS += -Wno-multichar \
-DM4_ENABLE_RENDERINGMODE \
-DUSE_STAGEFRIGHT_CODECS \
diff --git a/libvideoeditor/lvpp/DummyVideoSource.cpp b/libvideoeditor/lvpp/DummyVideoSource.cpp
index b06f937..6dbcf2a 100755
--- a/libvideoeditor/lvpp/DummyVideoSource.cpp
+++ b/libvideoeditor/lvpp/DummyVideoSource.cpp
@@ -16,6 +16,7 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "DummyVideoSource"
+#include <inttypes.h>
#include <stdlib.h>
#include <utils/Log.h>
#include <media/stagefright/foundation/ADebug.h>
@@ -146,7 +147,7 @@ status_t DummyVideoSource::read(
if (mIsFirstImageFrame) {
M4OSA_clockGetTime(&mImagePlayStartTime, kTimeScale);
mFrameTimeUs = (mImageSeekTime + 1);
- ALOGV("read: jpg 1st frame timeUs = %lld, begin cut time = %ld",
+ ALOGV("read: jpg 1st frame timeUs = %lld, begin cut time = %" PRIu32,
mFrameTimeUs, mImageSeekTime);
mIsFirstImageFrame = false;
diff --git a/libvideoeditor/lvpp/VideoEditorAudioPlayer.cpp b/libvideoeditor/lvpp/VideoEditorAudioPlayer.cpp
index 176f8e9..91dc590 100755
--- a/libvideoeditor/lvpp/VideoEditorAudioPlayer.cpp
+++ b/libvideoeditor/lvpp/VideoEditorAudioPlayer.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include <inttypes.h>
+
#define LOG_NDEBUG 1
#define LOG_TAG "VideoEditorAudioPlayer"
#include <utils/Log.h>
@@ -372,7 +374,7 @@ status_t VideoEditorAudioPlayer::start(bool sourceAlreadyStarted) {
// Get the duration in time of the audio BT
if ( result == M4NO_ERROR ) {
- ALOGV("VEAP: channels = %d freq = %d",
+ ALOGV("VEAP: channels = %" PRIu32 " freq = %" PRIu32,
mAudioMixSettings->uiNbChannels, mAudioMixSettings->uiSamplingFrequency);
// No trim
@@ -440,7 +442,7 @@ status_t VideoEditorAudioPlayer::start(bool sourceAlreadyStarted) {
// do nothing
}
- ALOGV("VideoEditorAudioPlayer::startTime %d", startTime);
+ ALOGV("VideoEditorAudioPlayer::startTime %" PRIu32, startTime);
seekTimeStamp = 0;
if (startTime) {
if (startTime >= mBGAudioPCMFileDuration) {
@@ -671,8 +673,9 @@ size_t VideoEditorAudioPlayer::fillBuffer(void *data, size_t size) {
M4OSA_Void* ptr;
- ptr = (M4OSA_Void*)((unsigned int)mInputBuffer->data() +
- mInputBuffer->range_offset());
+ ptr = reinterpret_cast<M4OSA_Void*>(
+ reinterpret_cast<uintptr_t>(mInputBuffer->data()) +
+ mInputBuffer->range_offset());
M4OSA_UInt32 len = mInputBuffer->range_length();
M4OSA_Context fp = M4OSA_NULL;
@@ -700,8 +703,8 @@ size_t VideoEditorAudioPlayer::fillBuffer(void *data, size_t size) {
mBGAudioPCMFileOriginalSeekPoint <=
(mBGAudioPCMFileTrimmedLength - len)) {
- ALOGV("Checking mBGAudioPCMFileHandle %d",
- (unsigned int)mBGAudioPCMFileHandle);
+ ALOGV("Checking mBGAudioPCMFileHandle %p",
+ mBGAudioPCMFileHandle);
if (mBGAudioPCMFileHandle != M4OSA_NULL) {
ALOGV("fillBuffer seeking file to %lld",
diff --git a/libvideoeditor/lvpp/VideoEditorBGAudioProcessing.cpp b/libvideoeditor/lvpp/VideoEditorBGAudioProcessing.cpp
index e24fcf4..0c12aac 100755
--- a/libvideoeditor/lvpp/VideoEditorBGAudioProcessing.cpp
+++ b/libvideoeditor/lvpp/VideoEditorBGAudioProcessing.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include <inttypes.h>
+
//#define LOG_NDEBUG 0
#define LOG_TAG "VideoEditorBGAudioProcessing"
#include <utils/Log.h>
@@ -50,8 +52,8 @@ M4OSA_Int32 VideoEditorBGAudioProcessing::mixAndDuck(
void *backgroundTrackBuffer,
void *outBuffer) {
- ALOGV("mixAndDuck: track buffers (primary: 0x%x and background: 0x%x) "
- "and out buffer 0x%x",
+ ALOGV("mixAndDuck: track buffers (primary: %p and background: %p) "
+ "and out buffer %p",
primaryTrackBuffer, backgroundTrackBuffer, outBuffer);
M4AM_Buffer16* pPrimaryTrack = (M4AM_Buffer16*)primaryTrackBuffer;
@@ -217,7 +219,7 @@ void VideoEditorBGAudioProcessing::setMixParams(
mDoDucking = 0;
mDuckingFactor = 1.0;
- ALOGV("ducking enable 0x%x lowVolume %f threshold %d "
+ ALOGV("ducking enable 0x%x lowVolume %f threshold %" PRIu32 " "
"fPTVolLevel %f BTVolLevel %f",
mDucking_enable, mDucking_lowVolume, mDucking_threshold,
mPTVolLevel, mPTVolLevel);
diff --git a/libvideoeditor/lvpp/VideoEditorPlayer.cpp b/libvideoeditor/lvpp/VideoEditorPlayer.cpp
index 5aeba4f..8d656c4 100755
--- a/libvideoeditor/lvpp/VideoEditorPlayer.cpp
+++ b/libvideoeditor/lvpp/VideoEditorPlayer.cpp
@@ -585,4 +585,11 @@ int VideoEditorPlayer::VeAudioOutput::getSessionId() const {
return mSessionId;
}
+uint32_t VideoEditorPlayer::VeAudioOutput::getSampleRate() const {
+ if (mMsecsPerFrame == 0) {
+ return 0;
+ }
+ return (uint32_t)(1.e3 / mMsecsPerFrame);
+}
+
} // namespace android
diff --git a/libvideoeditor/lvpp/VideoEditorPlayer.h b/libvideoeditor/lvpp/VideoEditorPlayer.h
index 5862c08..b8c1254 100755
--- a/libvideoeditor/lvpp/VideoEditorPlayer.h
+++ b/libvideoeditor/lvpp/VideoEditorPlayer.h
@@ -48,6 +48,7 @@ class VideoEditorPlayer : public MediaPlayerInterface {
virtual status_t getPosition(uint32_t *position) const;
virtual status_t getFramesWritten(uint32_t*) const;
virtual int getSessionId() const;
+ virtual uint32_t getSampleRate() const;
virtual status_t open(
uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask,
diff --git a/libvideoeditor/lvpp/VideoEditorPreviewController.cpp b/libvideoeditor/lvpp/VideoEditorPreviewController.cpp
index 149c4ea..c3cd3d0 100755
--- a/libvideoeditor/lvpp/VideoEditorPreviewController.cpp
+++ b/libvideoeditor/lvpp/VideoEditorPreviewController.cpp
@@ -1248,7 +1248,7 @@ void VideoEditorPreviewController::notify(
case MEDIA_SET_VIDEO_SIZE:
ALOGV("MEDIA_SET_VIDEO_SIZE; New video size %d x %d", ext1, ext2);
break;
- case 0xAAAAAAAA:
+ case static_cast<int>(0xAAAAAAAA):
ALOGV("VIDEO PLAYBACK ALMOST over, prepare next player");
// Select next player and prepare it
// If there is a clip after this one
@@ -1268,7 +1268,7 @@ void VideoEditorPreviewController::notify(
}
}
break;
- case 0xBBBBBBBB:
+ case static_cast<int>(0xBBBBBBBB):
{
ALOGV("VIDEO PLAYBACK, Update Overlay");
int overlayIndex = ext2;
diff --git a/libvideoeditor/lvpp/VideoEditorSRC.cpp b/libvideoeditor/lvpp/VideoEditorSRC.cpp
index 36d0812..6beabfa 100755
--- a/libvideoeditor/lvpp/VideoEditorSRC.cpp
+++ b/libvideoeditor/lvpp/VideoEditorSRC.cpp
@@ -284,7 +284,7 @@ status_t VideoEditorSRC::getNextBuffer(AudioBufferProvider::Buffer *pBuffer, int
void VideoEditorSRC::releaseBuffer(AudioBufferProvider::Buffer *pBuffer) {
- ALOGV("releaseBuffer: %p", pBuffers);
+ ALOGV("releaseBuffer: %p", pBuffer);
free(pBuffer->raw);
pBuffer->raw = NULL;
pBuffer->frameCount = 0;
diff --git a/libvideoeditor/osal/inc/M4OSA_Error.h b/libvideoeditor/osal/inc/M4OSA_Error.h
index 4d59529..75c3177 100755
--- a/libvideoeditor/osal/inc/M4OSA_Error.h
+++ b/libvideoeditor/osal/inc/M4OSA_Error.h
@@ -57,7 +57,7 @@ typedef M4OSA_UInt32 M4OSA_ERR;
* @arg coreID: (IN) [M4OSA_UInt32] CoreID to put in the error code
* @arg errorID: (IN) [M4OSA_UInt32] ErrorID to put in the error code*/
#define M4OSA_ERR_CREATE(severity, coreID, errorID)\
- (M4OSA_Int32)((((M4OSA_UInt32)severity)<<30)+((((M4OSA_UInt32)coreID)&0x003FFF)<<16)+(((M4OSA_UInt32)errorID)&0x00FFFF))
+ (M4OSA_UInt32)((((M4OSA_UInt32)severity)<<30)+((((M4OSA_UInt32)coreID)&0x003FFF)<<16)+(((M4OSA_UInt32)errorID)&0x00FFFF))
/** This macro extracts the 3 fields from the error:
* @arg error: (IN) [M4OSA_ERR] Error code
diff --git a/libvideoeditor/osal/inc/M4OSA_Types.h b/libvideoeditor/osal/inc/M4OSA_Types.h
index 92a68d8..ee258a0 100755
--- a/libvideoeditor/osal/inc/M4OSA_Types.h
+++ b/libvideoeditor/osal/inc/M4OSA_Types.h
@@ -36,13 +36,13 @@ extern "C" {
#endif
-typedef signed char M4OSA_Bool;
-typedef unsigned char M4OSA_UInt8;
-typedef signed char M4OSA_Int8;
-typedef unsigned short M4OSA_UInt16;
-typedef signed short M4OSA_Int16;
-typedef unsigned long M4OSA_UInt32;
-typedef signed long M4OSA_Int32;
+typedef int8_t M4OSA_Bool;
+typedef uint8_t M4OSA_UInt8;
+typedef int8_t M4OSA_Int8;
+typedef uint16_t M4OSA_UInt16;
+typedef int16_t M4OSA_Int16;
+typedef uint32_t M4OSA_UInt32;
+typedef int32_t M4OSA_Int32;
typedef signed char M4OSA_Char;
typedef unsigned char M4OSA_UChar;
diff --git a/libvideoeditor/osal/src/Android.mk b/libvideoeditor/osal/src/Android.mk
index 4f38b0c..b613387 100755
--- a/libvideoeditor/osal/src/Android.mk
+++ b/libvideoeditor/osal/src/Android.mk
@@ -48,10 +48,6 @@ LOCAL_C_INCLUDES += \
LOCAL_SHARED_LIBRARIES += libdl
-# All of the shared libraries we link against.
-LOCAL_LDLIBS := \
- -lpthread -ldl
-
LOCAL_CFLAGS += -Wno-multichar \
-D__ANDROID__ \
-DM4OSA_FILE_BLOCK_WITH_SEMAPHORE \
diff --git a/libvideoeditor/osal/src/M4OSA_Thread.c b/libvideoeditor/osal/src/M4OSA_Thread.c
index db54245..3e82fb3 100755
--- a/libvideoeditor/osal/src/M4OSA_Thread.c
+++ b/libvideoeditor/osal/src/M4OSA_Thread.c
@@ -524,7 +524,7 @@ M4OSA_ERR M4OSA_SetThreadSyncPriority(M4OSA_Context context,
M4OSA_TRACE2_2("M4OSA_SetThreadSyncPriority\t\tM4OSA_Context 0x%x\t"
"M4OSA_DataOption 0x%x", context, optionValue);
- if((M4OSA_UInt32)optionValue>M4OSA_kThreadLowestPriority)
+ if((M4OSA_UInt32)(uintptr_t)optionValue>M4OSA_kThreadLowestPriority)
{
return M4ERR_PARAMETER;
}
@@ -590,7 +590,7 @@ M4OSA_ERR M4OSA_SetThreadSyncStackSize(M4OSA_Context context,
M4OSA_TRACE2_2("M4OSA_SetThreadSyncStackSize\t\tM4OSA_Context 0x%x\t"
"M4OSA_DataOption 0x%x", context, optionValue);
- threadContext->stackSize = (M4OSA_UInt32)optionValue;
+ threadContext->stackSize = (M4OSA_UInt32)(uintptr_t)optionValue;
return M4NO_ERROR;
}
diff --git a/libvideoeditor/osal/src/M4PSW_DebugTrace.c b/libvideoeditor/osal/src/M4PSW_DebugTrace.c
index 0fcba94..850ed91 100755
--- a/libvideoeditor/osal/src/M4PSW_DebugTrace.c
+++ b/libvideoeditor/osal/src/M4PSW_DebugTrace.c
@@ -25,6 +25,7 @@
*/
+#include <inttypes.h>
#include <stdio.h> /*for printf */
#include "M4OSA_Types.h"
@@ -65,9 +66,9 @@ M4OSAL_TRACE_EXPORT_TYPE void M4OSA_DebugTrace(M4OSA_Int32 line,
}
#ifdef NO_FILE
- printf("Error: %li, on %s: %s\n",err,cond,msg);
+ printf("Error: %" PRIu32 ", on %s: %s\n",err,cond,msg);
#else /* NO_FILE */
- printf("Error: %li, on %s: %s Line %lu in: %s\n",err,cond,msg,line,file);
+ printf("Error: %" PRIu32 ", on %s: %s Line %" PRIu32 " in: %s\n",err,cond,msg,line,file);
#endif /* NO_FILE */
}
diff --git a/libvideoeditor/vss/3gpwriter/src/Android.mk b/libvideoeditor/vss/3gpwriter/src/Android.mk
index 8ab32ba..b70300f 100755
--- a/libvideoeditor/vss/3gpwriter/src/Android.mk
+++ b/libvideoeditor/vss/3gpwriter/src/Android.mk
@@ -43,12 +43,7 @@ LOCAL_C_INCLUDES += \
LOCAL_SHARED_LIBRARIES += libdl
-# All of the shared libraries we link against.
-LOCAL_LDLIBS := \
- -lpthread -ldl
-
LOCAL_CFLAGS += -Wno-multichar \
-DDUPLICATE_STTS_IN_LAST_AU
include $(BUILD_STATIC_LIBRARY)
-
diff --git a/libvideoeditor/vss/common/inc/marker.h b/libvideoeditor/vss/common/inc/marker.h
deleted file mode 100755
index 83cade0..0000000
--- a/libvideoeditor/vss/common/inc/marker.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2011 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#ifndef MARKER_H
-#define MARKER_H
-
-#define ADD_CODE_MARKER_FUN(m_condition) \
- if ( !(m_condition) ) \
- { \
- __asm__ volatile ( \
- ".word 0x21614062\n\t" /* '!a@b' */ \
- ".word 0x47712543\n\t" /* 'Gq%C' */ \
- ".word 0x5F5F5F43\n\t" /* '___C' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x245F5F5F" /* '$___' */ \
- ); \
- }
-
-#define ADD_TEXT_MARKER_FUN(m_condition) \
- if ( !(m_condition) ) \
- { \
- __asm__ volatile ( \
- ".word 0x21614062\n\t" /* '!a@b' */ \
- ".word 0x47712543\n\t" /* 'Gq%C' */ \
- ".word 0x5F5F5F54\n\t" /* '___T' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x5F5F5F5F\n\t" /* '____' */ \
- ".word 0x245F5F5F" /* '$___' */ \
- ); \
- }
-
-#endif
diff --git a/libvideoeditor/vss/mcs/src/Android.mk b/libvideoeditor/vss/mcs/src/Android.mk
index b470e6b..330aa61 100755
--- a/libvideoeditor/vss/mcs/src/Android.mk
+++ b/libvideoeditor/vss/mcs/src/Android.mk
@@ -47,12 +47,7 @@ LOCAL_C_INCLUDES += \
LOCAL_SHARED_LIBRARIES += libdl
-# All of the shared libraries we link against.
-LOCAL_LDLIBS := \
- -lpthread -ldl
-
LOCAL_CFLAGS += -Wno-multichar \
-DM4MCS_WITH_FAST_OPEN
include $(BUILD_STATIC_LIBRARY)
-
diff --git a/libvideoeditor/vss/src/Android.mk b/libvideoeditor/vss/src/Android.mk
index 0caa15b..0a3d64e 100755
--- a/libvideoeditor/vss/src/Android.mk
+++ b/libvideoeditor/vss/src/Android.mk
@@ -53,7 +53,7 @@ LOCAL_SRC_FILES:= \
LOCAL_MODULE_TAGS := optional
LOCAL_SHARED_LIBRARIES := \
- libaudioflinger \
+ libaudioresampler \
libaudioutils \
libbinder \
libcutils \
@@ -81,17 +81,12 @@ LOCAL_C_INCLUDES += \
$(TOP)/frameworks/av/libvideoeditor/vss/stagefrightshells/inc \
$(TOP)/frameworks/av/services/audioflinger \
$(TOP)/frameworks/native/include/media/openmax \
- $(TOP)/frameworks/native/services/audioflinger \
$(TOP)/system/media/audio_effects/include \
$(TOP)/system/media/audio_utils/include
LOCAL_SHARED_LIBRARIES += libdl
-# All of the shared libraries we link against.
-LOCAL_LDLIBS := \
- -lpthread -ldl
-
LOCAL_CFLAGS += -Wno-multichar \
-DM4xVSS_RESERVED_MOOV_DISK_SPACEno \
-DDECODE_GIF_ON_SAVING
diff --git a/libvideoeditor/vss/src/M4DECODER_Null.c b/libvideoeditor/vss/src/M4DECODER_Null.c
index a0dad30..ce260e5 100755
--- a/libvideoeditor/vss/src/M4DECODER_Null.c
+++ b/libvideoeditor/vss/src/M4DECODER_Null.c
@@ -210,7 +210,7 @@ M4OSA_ERR M4DECODER_NULL_setOption(M4OSA_Context context,
break;
case M4DECODER_kOptionID_EnableYuvWithEffect:
- pStreamContext->bYuvWithEffectSet = (M4OSA_Bool)pValue;
+ pStreamContext->bYuvWithEffectSet = (M4OSA_Bool)(intptr_t)pValue;
break;
case M4DECODER_kOptionID_YuvWithEffectNonContiguous:
diff --git a/libvideoeditor/vss/src/M4PCMR_CoreReader.c b/libvideoeditor/vss/src/M4PCMR_CoreReader.c
index 3343254..19f07dd 100755
--- a/libvideoeditor/vss/src/M4PCMR_CoreReader.c
+++ b/libvideoeditor/vss/src/M4PCMR_CoreReader.c
@@ -690,7 +690,7 @@ M4OSA_ERR M4PCMR_setOption(M4OSA_Context context, M4PCMR_OptionID optionID, M4OS
switch(optionID)
{
case M4PCMR_kPCMblockSize:
- c->m_blockSize = (M4OSA_UInt32)Value;
+ c->m_blockSize = (M4OSA_UInt32)(uintptr_t)Value;
break;
default:
diff --git a/libvideoeditor/vss/src/M4READER_Amr.c b/libvideoeditor/vss/src/M4READER_Amr.c
index 0859157..71f0e28 100755
--- a/libvideoeditor/vss/src/M4READER_Amr.c
+++ b/libvideoeditor/vss/src/M4READER_Amr.c
@@ -303,7 +303,7 @@ M4OSA_ERR M4READER_AMR_getNextStream(M4OSA_Context context, M4READER_MediaFamily
pStreamHandler->m_decoderSpecificInfoSize = streamDesc.decoderSpecificInfoSize;
pStreamHandler->m_streamId = streamDesc.streamID;
pStreamHandler->m_duration = streamDesc.duration;
- pStreamHandler->m_pUserData = (void*)streamDesc.timeScale; /*trick to change*/
+ pStreamHandler->m_pUserData = (void*)(intptr_t)streamDesc.timeScale; /*trick to change*/
if (streamDesc.duration > pC->m_maxDuration)
{
@@ -704,7 +704,7 @@ M4OSA_ERR M4READER_AMR_getNextAu(M4OSA_Context context, M4_StreamHandler *pStrea
if (err == M4NO_ERROR)
{
- timeScale = (M4OSA_Float)(M4OSA_Int32)(pStreamHandler->m_pUserData)/1000;
+ timeScale = (M4OSA_Float)(M4OSA_Int32)(intptr_t)(pStreamHandler->m_pUserData)/1000;
pAccessUnit->m_dataAddress = (M4OSA_MemAddr8)pAu->dataAddress;
pAccessUnit->m_size = pAu->size;
pAccessUnit->m_CTS = (M4_MediaTime)pAu->CTS/*/timeScale*/;
diff --git a/libvideoeditor/vss/src/M4READER_Pcm.c b/libvideoeditor/vss/src/M4READER_Pcm.c
index 833930b..392367f 100755
--- a/libvideoeditor/vss/src/M4READER_Pcm.c
+++ b/libvideoeditor/vss/src/M4READER_Pcm.c
@@ -386,7 +386,7 @@ M4OSA_ERR M4READER_PCM_getNextStream(M4OSA_Context context, M4READER_MediaFamily
pC->m_pAudioStream->m_decoderSpecificInfoSize = streamDesc.decoderSpecificInfoSize;
pC->m_pAudioStream->m_streamId = streamDesc.streamID;
pC->m_pAudioStream->m_pUserData =
- (void*)streamDesc.timeScale; /*trick to change*/
+ (void*)(intptr_t)streamDesc.timeScale; /*trick to change*/
pC->m_pAudioStream->m_averageBitRate = streamDesc.averageBitrate;
pC->m_pAudioStream->m_maxAUSize =
pAudioStreamHandler->m_byteFrameLength*pAudioStreamHandler->m_byteSampleSize\
diff --git a/libvideoeditor/vss/src/M4VD_EXTERNAL_BitstreamParser.c b/libvideoeditor/vss/src/M4VD_EXTERNAL_BitstreamParser.c
index cc67e72..fb83952 100755
--- a/libvideoeditor/vss/src/M4VD_EXTERNAL_BitstreamParser.c
+++ b/libvideoeditor/vss/src/M4VD_EXTERNAL_BitstreamParser.c
@@ -13,6 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#include <inttypes.h>
+
#include "utils/Log.h"
#include "M4OSA_Types.h"
#include "M4OSA_Debug.h"
@@ -505,7 +507,7 @@ M4OSA_ERR getAVCProfileAndLevel(M4OSA_UInt8* pDSI, M4OSA_Int32 DSISize,
}
constraintSet3 = (pDSI[index+2] & 0x10);
- ALOGV("getAVCProfileAndLevel profile_byte %d, level_byte: %d constrain3flag",
+ ALOGV("getAVCProfileAndLevel profile_byte %d, level_byte: %d constrain3flag: %d",
pDSI[index+1], pDSI[index+3], constraintSet3);
switch (pDSI[index+1]) {
@@ -586,7 +588,8 @@ M4OSA_ERR getAVCProfileAndLevel(M4OSA_UInt8* pDSI, M4OSA_Int32 DSISize,
default:
*pLevel = M4VIDEOEDITING_VIDEO_UNKNOWN_LEVEL;
}
- ALOGV("getAVCProfileAndLevel profile %ld level %ld", *pProfile, *pLevel);
+ ALOGV("getAVCProfileAndLevel profile %" PRId32 " level %" PRId32,
+ *pProfile, *pLevel);
return M4NO_ERROR;
}
@@ -606,7 +609,7 @@ M4OSA_ERR getH263ProfileAndLevel(M4OSA_UInt8* pDSI, M4OSA_Int32 DSISize,
*pLevel = M4VIDEOEDITING_VIDEO_UNKNOWN_LEVEL;
return M4ERR_PARAMETER;
}
- ALOGV("getH263ProfileAndLevel profile_byte %d, level_byte",
+ ALOGV("getH263ProfileAndLevel profile_byte %d, level_byte %d",
pDSI[6], pDSI[5]);
/* get the H263 level */
switch (pDSI[5]) {
@@ -670,7 +673,8 @@ M4OSA_ERR getH263ProfileAndLevel(M4OSA_UInt8* pDSI, M4OSA_Int32 DSISize,
default:
*pProfile = M4VIDEOEDITING_VIDEO_UNKNOWN_PROFILE;
}
- ALOGV("getH263ProfileAndLevel profile %ld level %ld", *pProfile, *pLevel);
+ ALOGV("getH263ProfileAndLevel profile %" PRId32 " level %" PRId32,
+ *pProfile, *pLevel);
return M4NO_ERROR;
}
@@ -693,6 +697,7 @@ M4OSA_ERR getMPEG4ProfileAndLevel(M4OSA_UInt8 profileAndLevel,
break;
}
}
- ALOGV("getMPEG4ProfileAndLevel profile %ld level %ld", *pProfile, *pLevel);
+ ALOGV("getMPEG4ProfileAndLevel profile %" PRId32 " level %" PRId32,
+ *pProfile, *pLevel);
return M4NO_ERROR;
}
diff --git a/libvideoeditor/vss/src/M4xVSS_internal.c b/libvideoeditor/vss/src/M4xVSS_internal.c
index 64a6f40..84959ec 100755
--- a/libvideoeditor/vss/src/M4xVSS_internal.c
+++ b/libvideoeditor/vss/src/M4xVSS_internal.c
@@ -4156,12 +4156,12 @@ M4OSA_ERR M4VSS3GPP_externalVideoEffectZoom(
M4VIFI_ImagePlane boxPlane[3];
- if(M4xVSS_kVideoEffectType_ZoomOut == (M4OSA_UInt32)pFunctionContext)
+ if((M4OSA_Void *)M4xVSS_kVideoEffectType_ZoomOut == pFunctionContext)
{
//ratio = 16 - (15 * pProgress->uiProgress)/1000;
ratio = 16 - pProgress->uiProgress / 66 ;
}
- else if(M4xVSS_kVideoEffectType_ZoomIn == (M4OSA_UInt32)pFunctionContext)
+ else if((M4OSA_Void *)M4xVSS_kVideoEffectType_ZoomIn == pFunctionContext)
{
//ratio = 1 + (15 * pProgress->uiProgress)/1000;
ratio = 1 + pProgress->uiProgress / 66 ;
diff --git a/libvideoeditor/vss/src/VideoEditorResampler.cpp b/libvideoeditor/vss/src/VideoEditorResampler.cpp
index 1129c3c..53537f0 100755
--- a/libvideoeditor/vss/src/VideoEditorResampler.cpp
+++ b/libvideoeditor/vss/src/VideoEditorResampler.cpp
@@ -17,7 +17,7 @@
#define LOG_NDEBUG 1
#include <audio_utils/primitives.h>
#include <utils/Log.h>
-#include "AudioMixer.h"
+#include "AudioResampler.h"
#include "VideoEditorResampler.h"
namespace android {
diff --git a/libvideoeditor/vss/stagefrightshells/src/VideoEditor3gpReader.cpp b/libvideoeditor/vss/stagefrightshells/src/VideoEditor3gpReader.cpp
index 3c8915a..99cf9ec 100755
--- a/libvideoeditor/vss/stagefrightshells/src/VideoEditor3gpReader.cpp
+++ b/libvideoeditor/vss/stagefrightshells/src/VideoEditor3gpReader.cpp
@@ -776,16 +776,16 @@ M4OSA_ERR VideoEditor3gpReader_setOption(M4OSA_Context context,
case M4READER_kOptionID_SetOsaFileReaderFctsPtr:
break;
- case M4READER_3GP_kOptionID_AudioOnly:
+ case static_cast<M4OSA_OptionID>(M4READER_3GP_kOptionID_AudioOnly):
break;
- case M4READER_3GP_kOptionID_VideoOnly:
+ case static_cast<M4OSA_OptionID>(M4READER_3GP_kOptionID_VideoOnly):
break;
- case M4READER_3GP_kOptionID_FastOpenMode:
+ case static_cast<M4OSA_OptionID>(M4READER_3GP_kOptionID_FastOpenMode):
break;
- case M4READER_kOptionID_MaxMetadataSize:
+ case static_cast<M4OSA_OptionID>(M4READER_kOptionID_MaxMetadataSize):
break;
default:
diff --git a/libvideoeditor/vss/stagefrightshells/src/VideoEditorAudioDecoder.cpp b/libvideoeditor/vss/stagefrightshells/src/VideoEditorAudioDecoder.cpp
index 9b35d07..e4c7ea1 100755
--- a/libvideoeditor/vss/stagefrightshells/src/VideoEditorAudioDecoder.cpp
+++ b/libvideoeditor/vss/stagefrightshells/src/VideoEditorAudioDecoder.cpp
@@ -809,7 +809,7 @@ M4OSA_ERR VideoEditorAudioDecoder_setOption(M4AD_Context pContext,
pDecoderContext = (VideoEditorAudioDecoder_Context*)pContext;
switch( optionID ) {
- case M4AD_kOptionID_UserParam:
+ case static_cast<M4OSA_UInt32>(M4AD_kOptionID_UserParam):
ALOGV("VideoEditorAudioDecodersetOption UserParam is not supported");
err = M4ERR_NOT_IMPLEMENTED;
break;
diff --git a/libvideoeditor/vss/stagefrightshells/src/VideoEditorBuffer.c b/libvideoeditor/vss/stagefrightshells/src/VideoEditorBuffer.c
index f4cfa7c..5a7b28e 100755
--- a/libvideoeditor/vss/stagefrightshells/src/VideoEditorBuffer.c
+++ b/libvideoeditor/vss/stagefrightshells/src/VideoEditorBuffer.c
@@ -22,6 +22,8 @@
#undef M4OSA_TRACE_LEVEL
#define M4OSA_TRACE_LEVEL 1
+#include <inttypes.h>
+
#include "VideoEditorBuffer.h"
#include "utils/Log.h"
@@ -55,7 +57,7 @@ M4OSA_ERR VIDEOEDITOR_BUFFER_allocatePool(VIDEOEDITOR_BUFFER_Pool** ppool,
VIDEOEDITOR_BUFFER_Pool* pool;
M4OSA_UInt32 index;
- ALOGV("VIDEOEDITOR_BUFFER_allocatePool : ppool = 0x%x nbBuffers = %d ",
+ ALOGV("VIDEOEDITOR_BUFFER_allocatePool : ppool = %p nbBuffers = %" PRIu32,
ppool, nbBuffers);
pool = M4OSA_NULL;
@@ -131,7 +133,7 @@ M4OSA_ERR VIDEOEDITOR_BUFFER_freePool(VIDEOEDITOR_BUFFER_Pool* ppool)
M4OSA_ERR err;
M4OSA_UInt32 j = 0;
- ALOGV("VIDEOEDITOR_BUFFER_freePool : ppool = 0x%x", ppool);
+ ALOGV("VIDEOEDITOR_BUFFER_freePool : ppool = %p", ppool);
err = M4NO_ERROR;
@@ -200,7 +202,7 @@ M4OSA_ERR VIDEOEDITOR_BUFFER_getBuffer(VIDEOEDITOR_BUFFER_Pool* ppool,
/* case where a buffer has been found */
*pNXPBuffer = &(ppool->pNXPBuffer[ibuf]);
- ALOGV("VIDEOEDITOR_BUFFER_getBuffer: idx = %d", ibuf);
+ ALOGV("VIDEOEDITOR_BUFFER_getBuffer: idx = %" PRIu32, ibuf);
return(err);
}
diff --git a/libvideoeditor/vss/stagefrightshells/src/VideoEditorMp3Reader.cpp b/libvideoeditor/vss/stagefrightshells/src/VideoEditorMp3Reader.cpp
index af53c54..2e0d05d 100755
--- a/libvideoeditor/vss/stagefrightshells/src/VideoEditorMp3Reader.cpp
+++ b/libvideoeditor/vss/stagefrightshells/src/VideoEditorMp3Reader.cpp
@@ -334,8 +334,8 @@ M4OSA_ERR VideoEditorMp3Reader_setOption(M4OSA_Context context,
(VideoEditorMp3Reader_Context*)context;
M4OSA_ERR err = M4NO_ERROR;
- ALOGV("VideoEditorMp3Reader_Context begin: optionId: %d Value: %d ",
- (int)optionId,(int)pValue);
+ ALOGV("VideoEditorMp3Reader_Context begin: optionId: %u Value: %p ",
+ optionId, pValue);
M4OSA_DEBUG_IF1((M4OSA_NULL == pReaderContext), M4ERR_PARAMETER,
"invalid context pointer");
diff --git a/libvideoeditor/vss/stagefrightshells/src/VideoEditorUtils.cpp b/libvideoeditor/vss/stagefrightshells/src/VideoEditorUtils.cpp
index 5a7237d..d264a2e 100755
--- a/libvideoeditor/vss/stagefrightshells/src/VideoEditorUtils.cpp
+++ b/libvideoeditor/vss/stagefrightshells/src/VideoEditorUtils.cpp
@@ -84,17 +84,17 @@ void displayMetaData(const sp<MetaData> meta) {
LOG1("displayMetaData kKeyBitRate %d", int32Data);
}
if (meta->findData(kKeyESDS, &type, &data, &size)) {
- LOG1("displayMetaData kKeyESDS type=%d size=%d", type, size);
+ LOG1("displayMetaData kKeyESDS type=%d size=%zu", type, size);
}
if (meta->findData(kKeyAVCC, &type, &data, &size)) {
- LOG1("displayMetaData kKeyAVCC data=0x%X type=%d size=%d",
+ LOG1("displayMetaData kKeyAVCC data=0x%X type=%d size=%zu",
*((unsigned int*)data), type, size);
}
if (meta->findData(kKeyVorbisInfo, &type, &data, &size)) {
- LOG1("displayMetaData kKeyVorbisInfo type=%d size=%d", type, size);
+ LOG1("displayMetaData kKeyVorbisInfo type=%d size=%zu", type, size);
}
if (meta->findData(kKeyVorbisBooks, &type, &data, &size)) {
- LOG1("displayMetaData kKeyVorbisBooks type=%d size=%d", type, size);
+ LOG1("displayMetaData kKeyVorbisBooks type=%d size=%zu", type, size);
}
if (meta->findInt32(kKeyWantsNALFragments, &int32Data)) {
LOG1("displayMetaData kKeyWantsNALFragments %d", int32Data);
@@ -115,7 +115,7 @@ void displayMetaData(const sp<MetaData> meta) {
LOG1("displayMetaData kKeyColorFormat %d", int32Data);
}
if (meta->findPointer(kKeyPlatformPrivate, &ptr)) {
- LOG1("displayMetaData kKeyPlatformPrivate pointer=0x%x", (int32_t) ptr);
+ LOG1("displayMetaData kKeyPlatformPrivate pointer=%p", ptr);
}
if (meta->findCString(kKeyDecoderComponent, &charData)) {
LOG1("displayMetaData kKeyDecoderComponent %s", charData);
@@ -151,7 +151,7 @@ void displayMetaData(const sp<MetaData> meta) {
LOG1("displayMetaData kKeyYear %s", charData);
}
if (meta->findData(kKeyAlbumArt, &type, &data, &size)) {
- LOG1("displayMetaData kKeyAlbumArt type=%d size=%d", type, size);
+ LOG1("displayMetaData kKeyAlbumArt type=%d size=%zu", type, size);
}
if (meta->findCString(kKeyAlbumArtMIME, &charData)) {
LOG1("displayMetaData kKeyAlbumArtMIME %s", charData);
@@ -277,7 +277,7 @@ status_t buildAVCCodecSpecificData(uint8_t **pOutputData, size_t *pOutputSize,
}
if (size < 4) {
- ALOGE("Codec specific data length too short: %d", size);
+ ALOGE("Codec specific data length too short: %zu", size);
return ERROR_MALFORMED;
}
@@ -286,7 +286,7 @@ status_t buildAVCCodecSpecificData(uint8_t **pOutputData, size_t *pOutputSize,
// 2 bytes for each of the parameter set length field
// plus the 7 bytes for the header
if (size < 4 + 7) {
- ALOGE("Codec specific data length too short: %d", size);
+ ALOGE("Codec specific data length too short: %zu", size);
return ERROR_MALFORMED;
}
@@ -355,7 +355,7 @@ status_t buildAVCCodecSpecificData(uint8_t **pOutputData, size_t *pOutputSize,
}
if (nSeqParamSets > 0x1F) {
- ALOGE("Too many seq parameter sets (%d) found", nSeqParamSets);
+ ALOGE("Too many seq parameter sets (%zu) found", nSeqParamSets);
return ERROR_MALFORMED;
}
}
@@ -368,7 +368,7 @@ status_t buildAVCCodecSpecificData(uint8_t **pOutputData, size_t *pOutputSize,
return ERROR_MALFORMED;
}
if (nPicParamSets > 0xFF) {
- ALOGE("Too many pic parameter sets (%d) found", nPicParamSets);
+ ALOGE("Too many pic parameter sets (%zu) found", nPicParamSets);
return ERROR_MALFORMED;
}
}
diff --git a/libvideoeditor/vss/stagefrightshells/src/VideoEditorVideoEncoder.cpp b/libvideoeditor/vss/stagefrightshells/src/VideoEditorVideoEncoder.cpp
index 4787680..ca7db68 100755
--- a/libvideoeditor/vss/stagefrightshells/src/VideoEditorVideoEncoder.cpp
+++ b/libvideoeditor/vss/stagefrightshells/src/VideoEditorVideoEncoder.cpp
@@ -857,7 +857,7 @@ M4OSA_ERR VideoEditorVideoEncoder_processOutputBuffer(
ALOGV("VideoEditorVideoEncoder_processOutputBuffer : buffer is empty");
goto cleanUp;
}
- VIDEOEDITOR_CHECK(0 == ((M4OSA_UInt32)buffer->data())%4, M4ERR_PARAMETER);
+ VIDEOEDITOR_CHECK(0 == (((intptr_t)buffer->data())%4), M4ERR_PARAMETER);
VIDEOEDITOR_CHECK(buffer->meta_data().get(), M4ERR_PARAMETER);
if ( buffer->meta_data()->findInt32(kKeyIsCodecConfig, &i32Tmp) && i32Tmp ){
{ // Display the DSI
diff --git a/libvideoeditor/vss/video_filters/src/Android.mk b/libvideoeditor/vss/video_filters/src/Android.mk
index 85a530c..88fa974 100755
--- a/libvideoeditor/vss/video_filters/src/Android.mk
+++ b/libvideoeditor/vss/video_filters/src/Android.mk
@@ -47,11 +47,6 @@ LOCAL_C_INCLUDES += \
LOCAL_SHARED_LIBRARIES += libdl
-# All of the shared libraries we link against.
-LOCAL_LDLIBS := \
- -lpthread -ldl
-
LOCAL_CFLAGS += -Wno-multichar
include $(BUILD_SHARED_LIBRARY)
-
diff --git a/media/common_time/utils.cpp b/media/common_time/utils.cpp
index 6539171..91cf2fd 100644
--- a/media/common_time/utils.cpp
+++ b/media/common_time/utils.cpp
@@ -59,7 +59,7 @@ void serializeSockaddr(Parcel* p, const struct sockaddr_storage* addr) {
}
void deserializeSockaddr(const Parcel* p, struct sockaddr_storage* addr) {
- memset(addr, 0, sizeof(addr));
+ memset(addr, 0, sizeof(*addr));
addr->ss_family = p->readInt32();
switch(addr->ss_family) {
diff --git a/media/libcpustats/Android.mk b/media/libcpustats/Android.mk
index b506353..ee283a6 100644
--- a/media/libcpustats/Android.mk
+++ b/media/libcpustats/Android.mk
@@ -1,4 +1,4 @@
-LOCAL_PATH:= $(call my-dir)
+LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
@@ -8,4 +8,6 @@ LOCAL_SRC_FILES := \
LOCAL_MODULE := libcpustats
+LOCAL_CFLAGS := -std=gnu++11 -Werror
+
include $(BUILD_STATIC_LIBRARY)
diff --git a/media/libcpustats/ThreadCpuUsage.cpp b/media/libcpustats/ThreadCpuUsage.cpp
index 637402a..cfdcb51 100644
--- a/media/libcpustats/ThreadCpuUsage.cpp
+++ b/media/libcpustats/ThreadCpuUsage.cpp
@@ -21,7 +21,6 @@
#include <stdlib.h>
#include <time.h>
-#include <utils/Debug.h>
#include <utils/Log.h>
#include <cpustats/ThreadCpuUsage.h>
@@ -218,7 +217,7 @@ uint32_t ThreadCpuUsage::getCpukHz(int cpuNum)
#define FREQ_SIZE 64
char freq_path[FREQ_SIZE];
#define FREQ_DIGIT 27
- COMPILE_TIME_ASSERT_FUNCTION_SCOPE(MAX_CPU <= 10);
+ static_assert(MAX_CPU <= 10, "MAX_CPU too large");
#define FREQ_PATH "/sys/devices/system/cpu/cpu?/cpufreq/scaling_cur_freq"
strlcpy(freq_path, FREQ_PATH, sizeof(freq_path));
freq_path[FREQ_DIGIT] = cpuNum + '0';
diff --git a/media/libeffects/downmix/Android.mk b/media/libeffects/downmix/Android.mk
index 5d0a87c..2bb6dbe 100644
--- a/media/libeffects/downmix/Android.mk
+++ b/media/libeffects/downmix/Android.mk
@@ -13,7 +13,7 @@ LOCAL_MODULE:= libdownmix
LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/soundfx
+LOCAL_MODULE_RELATIVE_PATH := soundfx
ifeq ($(TARGET_OS)-$(TARGET_SIMULATOR),linux-true)
LOCAL_LDLIBS += -ldl
diff --git a/media/libeffects/downmix/EffectDownmix.c b/media/libeffects/downmix/EffectDownmix.c
index f779876..1663d47 100644
--- a/media/libeffects/downmix/EffectDownmix.c
+++ b/media/libeffects/downmix/EffectDownmix.c
@@ -16,7 +16,8 @@
#define LOG_TAG "EffectDownmix"
//#define LOG_NDEBUG 0
-#include <cutils/log.h>
+#include <log/log.h>
+#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
@@ -99,7 +100,7 @@ const int kNbEffects = sizeof(gDescriptors) / sizeof(const effect_descriptor_t *
// strictly for testing, logs the indices of the channels for a given mask,
// uses the same code as Downmix_foldGeneric()
void Downmix_testIndexComputation(uint32_t mask) {
- ALOGI("Testing index computation for 0x%x:", mask);
+ ALOGI("Testing index computation for 0x%" PRIx32 ":", mask);
// check against unsupported channels
if (mask & kUnsupported) {
ALOGE("Unsupported channels (top or front left/right of center)");
@@ -220,7 +221,7 @@ int32_t DownmixLib_Create(const effect_uuid_t *uuid,
*pHandle = (effect_handle_t) module;
- ALOGV("DownmixLib_Create() %p , size %d", module, sizeof(downmix_module_t));
+ ALOGV("DownmixLib_Create() %p , size %zu", module, sizeof(downmix_module_t));
return 0;
}
@@ -254,7 +255,7 @@ int32_t DownmixLib_GetDescriptor(const effect_uuid_t *uuid, effect_descriptor_t
ALOGV("DownmixLib_GetDescriptor() i=%d", i);
if (memcmp(uuid, &gDescriptors[i]->uuid, sizeof(effect_uuid_t)) == 0) {
memcpy(pDescriptor, gDescriptors[i], sizeof(effect_descriptor_t));
- ALOGV("EffectGetDescriptor - UUID matched downmix type %d, UUID = %x",
+ ALOGV("EffectGetDescriptor - UUID matched downmix type %d, UUID = %" PRIx32,
i, gDescriptors[i]->uuid.timeLow);
return 0;
}
@@ -328,7 +329,7 @@ static int Downmix_Process(effect_handle_t self,
// bypass the optimized downmix routines for the common formats
if (!Downmix_foldGeneric(
downmixInputChannelMask, pSrc, pDst, numFrames, accumulate)) {
- ALOGE("Multichannel configuration 0x%x is not supported", downmixInputChannelMask);
+ ALOGE("Multichannel configuration 0x%" PRIx32 " is not supported", downmixInputChannelMask);
return -EINVAL;
}
break;
@@ -352,7 +353,7 @@ static int Downmix_Process(effect_handle_t self,
default:
if (!Downmix_foldGeneric(
downmixInputChannelMask, pSrc, pDst, numFrames, accumulate)) {
- ALOGE("Multichannel configuration 0x%x is not supported", downmixInputChannelMask);
+ ALOGE("Multichannel configuration 0x%" PRIx32 " is not supported", downmixInputChannelMask);
return -EINVAL;
}
break;
@@ -380,7 +381,7 @@ static int Downmix_Command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdS
pDownmixer = (downmix_object_t*) &pDwmModule->context;
- ALOGV("Downmix_Command command %d cmdSize %d",cmdCode, cmdSize);
+ ALOGV("Downmix_Command command %" PRIu32 " cmdSize %" PRIu32, cmdCode, cmdSize);
switch (cmdCode) {
case EFFECT_CMD_INIT:
@@ -404,7 +405,7 @@ static int Downmix_Command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdS
break;
case EFFECT_CMD_GET_PARAM:
- ALOGV("Downmix_Command EFFECT_CMD_GET_PARAM pCmdData %p, *replySize %d, pReplyData: %p",
+ ALOGV("Downmix_Command EFFECT_CMD_GET_PARAM pCmdData %p, *replySize %" PRIu32 ", pReplyData: %p",
pCmdData, *replySize, pReplyData);
if (pCmdData == NULL || cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)) ||
pReplyData == NULL ||
@@ -413,7 +414,7 @@ static int Downmix_Command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdS
}
effect_param_t *rep = (effect_param_t *) pReplyData;
memcpy(pReplyData, pCmdData, sizeof(effect_param_t) + sizeof(int32_t));
- ALOGV("Downmix_Command EFFECT_CMD_GET_PARAM param %d, replySize %d",
+ ALOGV("Downmix_Command EFFECT_CMD_GET_PARAM param %" PRId32 ", replySize %" PRIu32,
*(int32_t *)rep->data, rep->vsize);
rep->status = Downmix_getParameter(pDownmixer, *(int32_t *)rep->data, &rep->vsize,
rep->data + sizeof(int32_t));
@@ -421,8 +422,8 @@ static int Downmix_Command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdS
break;
case EFFECT_CMD_SET_PARAM:
- ALOGV("Downmix_Command EFFECT_CMD_SET_PARAM cmdSize %d pCmdData %p, *replySize %d, " \
- "pReplyData %p", cmdSize, pCmdData, *replySize, pReplyData);
+ ALOGV("Downmix_Command EFFECT_CMD_SET_PARAM cmdSize %d pCmdData %p, *replySize %" PRIu32
+ ", pReplyData %p", cmdSize, pCmdData, *replySize, pReplyData);
if (pCmdData == NULL || (cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)))
|| pReplyData == NULL || *replySize != (int)sizeof(int32_t)) {
return -EINVAL;
@@ -471,7 +472,7 @@ static int Downmix_Command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdS
return -EINVAL;
}
// FIXME change type if playing on headset vs speaker
- ALOGV("Downmix_Command EFFECT_CMD_SET_DEVICE: 0x%08x", *(uint32_t *)pCmdData);
+ ALOGV("Downmix_Command EFFECT_CMD_SET_DEVICE: 0x%08" PRIx32, *(uint32_t *)pCmdData);
break;
case EFFECT_CMD_SET_VOLUME: {
@@ -491,7 +492,7 @@ static int Downmix_Command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdS
if (pCmdData == NULL || cmdSize != (int)sizeof(uint32_t)) {
return -EINVAL;
}
- ALOGV("Downmix_Command EFFECT_CMD_SET_AUDIO_MODE: %d", *(uint32_t *)pCmdData);
+ ALOGV("Downmix_Command EFFECT_CMD_SET_AUDIO_MODE: %" PRIu32, *(uint32_t *)pCmdData);
break;
case EFFECT_CMD_SET_CONFIG_REVERSE:
@@ -500,7 +501,7 @@ static int Downmix_Command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdS
break;
default:
- ALOGW("Downmix_Command invalid command %d",cmdCode);
+ ALOGW("Downmix_Command invalid command %" PRIu32, cmdCode);
return -EINVAL;
}
@@ -629,7 +630,9 @@ int Downmix_Configure(downmix_module_t *pDwmModule, effect_config_t *pConfig, bo
return -EINVAL;
}
- memcpy(&pDwmModule->config, pConfig, sizeof(effect_config_t));
+ if (&pDwmModule->config != pConfig) {
+ memcpy(&pDwmModule->config, pConfig, sizeof(effect_config_t));
+ }
if (init) {
pDownmixer->type = DOWNMIX_TYPE_FOLD;
@@ -697,31 +700,31 @@ int Downmix_Reset(downmix_object_t *pDownmixer, bool init) {
*
*----------------------------------------------------------------------------
*/
-int Downmix_setParameter(downmix_object_t *pDownmixer, int32_t param, size_t size, void *pValue) {
+int Downmix_setParameter(downmix_object_t *pDownmixer, int32_t param, uint32_t size, void *pValue) {
int16_t value16;
- ALOGV("Downmix_setParameter, context %p, param %d, value16 %d, value32 %d",
+ ALOGV("Downmix_setParameter, context %p, param %" PRId32 ", value16 %" PRId16 ", value32 %" PRId32,
pDownmixer, param, *(int16_t *)pValue, *(int32_t *)pValue);
switch (param) {
case DOWNMIX_PARAM_TYPE:
if (size != sizeof(downmix_type_t)) {
- ALOGE("Downmix_setParameter(DOWNMIX_PARAM_TYPE) invalid size %d, should be %d",
+ ALOGE("Downmix_setParameter(DOWNMIX_PARAM_TYPE) invalid size %" PRIu32 ", should be %zu",
size, sizeof(downmix_type_t));
return -EINVAL;
}
value16 = *(int16_t *)pValue;
- ALOGV("set DOWNMIX_PARAM_TYPE, type %d", value16);
+ ALOGV("set DOWNMIX_PARAM_TYPE, type %" PRId16, value16);
if (!((value16 > DOWNMIX_TYPE_INVALID) && (value16 <= DOWNMIX_TYPE_LAST))) {
- ALOGE("Downmix_setParameter invalid DOWNMIX_PARAM_TYPE value %d", value16);
+ ALOGE("Downmix_setParameter invalid DOWNMIX_PARAM_TYPE value %" PRId16, value16);
return -EINVAL;
} else {
pDownmixer->type = (downmix_type_t) value16;
break;
default:
- ALOGE("Downmix_setParameter unknown parameter %d", param);
+ ALOGE("Downmix_setParameter unknown parameter %" PRId32, param);
return -EINVAL;
}
}
@@ -753,24 +756,24 @@ int Downmix_setParameter(downmix_object_t *pDownmixer, int32_t param, size_t siz
*
*----------------------------------------------------------------------------
*/
-int Downmix_getParameter(downmix_object_t *pDownmixer, int32_t param, size_t *pSize, void *pValue) {
+int Downmix_getParameter(downmix_object_t *pDownmixer, int32_t param, uint32_t *pSize, void *pValue) {
int16_t *pValue16;
switch (param) {
case DOWNMIX_PARAM_TYPE:
if (*pSize < sizeof(int16_t)) {
- ALOGE("Downmix_getParameter invalid parameter size %d for DOWNMIX_PARAM_TYPE", *pSize);
+ ALOGE("Downmix_getParameter invalid parameter size %" PRIu32 " for DOWNMIX_PARAM_TYPE", *pSize);
return -EINVAL;
}
pValue16 = (int16_t *)pValue;
*pValue16 = (int16_t) pDownmixer->type;
*pSize = sizeof(int16_t);
- ALOGV("Downmix_getParameter DOWNMIX_PARAM_TYPE is %d", *pValue16);
+ ALOGV("Downmix_getParameter DOWNMIX_PARAM_TYPE is %" PRId16, *pValue16);
break;
default:
- ALOGE("Downmix_getParameter unknown parameter %d", param);
+ ALOGE("Downmix_getParameter unknown parameter %" PRId16, param);
return -EINVAL;
}
diff --git a/media/libeffects/downmix/EffectDownmix.h b/media/libeffects/downmix/EffectDownmix.h
index cb6b957..fcb3c9e 100644
--- a/media/libeffects/downmix/EffectDownmix.h
+++ b/media/libeffects/downmix/EffectDownmix.h
@@ -93,8 +93,8 @@ static int Downmix_GetDescriptor(effect_handle_t self,
int Downmix_Init(downmix_module_t *pDwmModule);
int Downmix_Configure(downmix_module_t *pDwmModule, effect_config_t *pConfig, bool init);
int Downmix_Reset(downmix_object_t *pDownmixer, bool init);
-int Downmix_setParameter(downmix_object_t *pDownmixer, int32_t param, size_t size, void *pValue);
-int Downmix_getParameter(downmix_object_t *pDownmixer, int32_t param, size_t *pSize, void *pValue);
+int Downmix_setParameter(downmix_object_t *pDownmixer, int32_t param, uint32_t size, void *pValue);
+int Downmix_getParameter(downmix_object_t *pDownmixer, int32_t param, uint32_t *pSize, void *pValue);
void Downmix_foldFromQuad(int16_t *pSrc, int16_t*pDst, size_t numFrames, bool accumulate);
void Downmix_foldFromSurround(int16_t *pSrc, int16_t*pDst, size_t numFrames, bool accumulate);
diff --git a/media/libeffects/factory/Android.mk b/media/libeffects/factory/Android.mk
index 60a6ce5..a932af7 100644
--- a/media/libeffects/factory/Android.mk
+++ b/media/libeffects/factory/Android.mk
@@ -9,7 +9,6 @@ LOCAL_SRC_FILES:= \
LOCAL_SHARED_LIBRARIES := \
libcutils liblog
-LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)
LOCAL_MODULE:= libeffects
LOCAL_SHARED_LIBRARIES += libdl
diff --git a/media/libeffects/factory/EffectsFactory.c b/media/libeffects/factory/EffectsFactory.c
index f8d6041..6d30d64 100644
--- a/media/libeffects/factory/EffectsFactory.c
+++ b/media/libeffects/factory/EffectsFactory.c
@@ -368,27 +368,21 @@ int EffectRelease(effect_handle_t handle)
}
if (e1 == NULL) {
ret = -ENOENT;
- pthread_mutex_unlock(&gLibLock);
goto exit;
}
// release effect in library
if (fx->lib == NULL) {
ALOGW("EffectRelease() fx %p library already unloaded", handle);
- pthread_mutex_unlock(&gLibLock);
} else {
pthread_mutex_lock(&fx->lib->lock);
- // Releasing the gLibLock here as the list access is over as the
- // effect is removed from the list.
- // If the gLibLock is not released, we will have a deadlock situation
- // since we call the sub effect release inside the EffectRelease of Proxy
- pthread_mutex_unlock(&gLibLock);
fx->lib->desc->release_effect(fx->subItfe);
pthread_mutex_unlock(&fx->lib->lock);
}
free(fx);
exit:
+ pthread_mutex_unlock(&gLibLock);
return ret;
}
@@ -404,8 +398,8 @@ int EffectIsNullUuid(const effect_uuid_t *uuid)
// is pointed by the first argument. It searches the gSubEffectList for the
// matching uuid and then copies the corresponding sub effect descriptors
// to the inout param
-int EffectGetSubEffects(const effect_uuid_t *uuid,
- effect_descriptor_t *pDescriptors, size_t size)
+int EffectGetSubEffects(const effect_uuid_t *uuid, sub_effect_entry_t **pSube,
+ size_t size)
{
ALOGV("EffectGetSubEffects() UUID: %08X-%04X-%04X-%04X-%02X%02X%02X%02X%02X"
"%02X\n",uuid->timeLow, uuid->timeMid, uuid->timeHiAndVersion,
@@ -413,8 +407,7 @@ int EffectGetSubEffects(const effect_uuid_t *uuid,
uuid->node[3],uuid->node[4],uuid->node[5]);
// Check if the size of the desc buffer is large enough for 2 subeffects
- if ((uuid == NULL) || (pDescriptors == NULL) ||
- (size < 2*sizeof(effect_descriptor_t))) {
+ if ((uuid == NULL) || (pSube == NULL) || (size < 2)) {
ALOGW("NULL pointer or insufficient memory. Cannot query subeffects");
return -EINVAL;
}
@@ -432,11 +425,10 @@ int EffectGetSubEffects(const effect_uuid_t *uuid,
list_elem_t *subefx = e->sub_elem;
while (subefx != NULL) {
subeffect = (sub_effect_entry_t*)subefx->object;
- d = (effect_descriptor_t*)(subeffect->object);
- pDescriptors[count++] = *d;
+ pSube[count++] = subeffect;
subefx = subefx->next;
}
- ALOGV("EffectGetSubEffects end - copied the sub effect descriptors");
+ ALOGV("EffectGetSubEffects end - copied the sub effect structures");
return count;
}
e = e->next;
diff --git a/media/libeffects/factory/EffectsFactory.h b/media/libeffects/factory/EffectsFactory.h
index 147ff18..560b485 100644
--- a/media/libeffects/factory/EffectsFactory.h
+++ b/media/libeffects/factory/EffectsFactory.h
@@ -20,7 +20,7 @@
#include <cutils/log.h>
#include <pthread.h>
#include <dirent.h>
-#include <media/EffectsFactoryApi.h>
+#include <hardware/audio_effect.h>
#if __cplusplus
extern "C" {
@@ -66,6 +66,32 @@ typedef struct sub_effect_entry_s {
void *object;
} sub_effect_entry_t;
+
+////////////////////////////////////////////////////////////////////////////////
+//
+// Function: EffectGetSubEffects
+//
+// Description: Returns the descriptors of the sub effects of the effect
+// whose uuid is pointed to by first argument.
+//
+// Input:
+// pEffectUuid: pointer to the effect uuid.
+// size: max number of sub_effect_entry_t * in pSube.
+//
+// Input/Output:
+// pSube: address where to return the sub effect structures.
+// Output:
+// returned value: 0 successful operation.
+// -ENODEV factory failed to initialize
+// -EINVAL invalid pEffectUuid or pDescriptor
+// -ENOENT no effect with this uuid found
+// *pDescriptor: updated with the sub effect descriptors.
+//
+////////////////////////////////////////////////////////////////////////////////
+int EffectGetSubEffects(const effect_uuid_t *pEffectUuid,
+ sub_effect_entry_t **pSube,
+ size_t size);
+
#if __cplusplus
} // extern "C"
#endif
diff --git a/media/libeffects/loudness/Android.mk b/media/libeffects/loudness/Android.mk
index dcb7b27..edf964e 100644
--- a/media/libeffects/loudness/Android.mk
+++ b/media/libeffects/loudness/Android.mk
@@ -14,7 +14,7 @@ LOCAL_SHARED_LIBRARIES := \
liblog \
libstlport
-LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/soundfx
+LOCAL_MODULE_RELATIVE_PATH := soundfx
LOCAL_MODULE:= libldnhncr
LOCAL_C_INCLUDES := \
diff --git a/media/libeffects/loudness/EffectLoudnessEnhancer.cpp b/media/libeffects/loudness/EffectLoudnessEnhancer.cpp
index 91ed677..3c2b320 100644
--- a/media/libeffects/loudness/EffectLoudnessEnhancer.cpp
+++ b/media/libeffects/loudness/EffectLoudnessEnhancer.cpp
@@ -453,13 +453,13 @@ const struct effect_interface_s gLEInterface = {
// This is the only symbol that needs to be exported
__attribute__ ((visibility ("default")))
audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {
- tag : AUDIO_EFFECT_LIBRARY_TAG,
- version : EFFECT_LIBRARY_API_VERSION,
- name : "Loudness Enhancer Library",
- implementor : "The Android Open Source Project",
- create_effect : LELib_Create,
- release_effect : LELib_Release,
- get_descriptor : LELib_GetDescriptor,
+ .tag = AUDIO_EFFECT_LIBRARY_TAG,
+ .version = EFFECT_LIBRARY_API_VERSION,
+ .name = "Loudness Enhancer Library",
+ .implementor = "The Android Open Source Project",
+ .create_effect = LELib_Create,
+ .release_effect = LELib_Release,
+ .get_descriptor = LELib_GetDescriptor,
};
}; // extern "C"
diff --git a/media/libeffects/lvm/lib/Bass/src/LVDBE_Init.c b/media/libeffects/lvm/lib/Bass/src/LVDBE_Init.c
index 32c4ce0..35e5bc8 100644
--- a/media/libeffects/lvm/lib/Bass/src/LVDBE_Init.c
+++ b/media/libeffects/lvm/lib/Bass/src/LVDBE_Init.c
@@ -178,7 +178,7 @@ LVDBE_ReturnStatus_en LVDBE_Init(LVDBE_Handle_t *phInstance,
{
return(LVDBE_NULLADDRESS);
}
- if (((LVM_UINT32)pMemoryTable->Region[i].pBaseAddress % pMemoryTable->Region[i].Alignment)!=0){
+ if (((uintptr_t)pMemoryTable->Region[i].pBaseAddress % pMemoryTable->Region[i].Alignment)!=0){
return(LVDBE_ALIGNMENTERROR);
}
}
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Process.c b/media/libeffects/lvm/lib/Bundle/src/LVM_Process.c
index 794271b..f5a01f3 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Process.c
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Process.c
@@ -99,7 +99,7 @@ LVM_ReturnStatus_en LVM_Process(LVM_Handle_t hInstance,
/*
* Check the buffer alignment
*/
- if((((LVM_UINT32)pInData % 4) != 0) || (((LVM_UINT32)pOutData % 4) != 0))
+ if((((uintptr_t)pInData % 4) != 0) || (((uintptr_t)pOutData % 4) != 0))
{
return(LVM_ALIGNMENTERROR);
}
diff --git a/media/libeffects/lvm/lib/Common/lib/InstAlloc.h b/media/libeffects/lvm/lib/Common/lib/InstAlloc.h
index c6954f2..7f725f4 100644
--- a/media/libeffects/lvm/lib/Common/lib/InstAlloc.h
+++ b/media/libeffects/lvm/lib/Common/lib/InstAlloc.h
@@ -29,7 +29,7 @@ extern "C" {
typedef struct
{
LVM_UINT32 TotalSize; /* Accumulative total memory size */
- LVM_UINT32 pNextMember; /* Pointer to the next instance member to be allocated */
+ uintptr_t pNextMember; /* Pointer to the next instance member to be allocated */
} INST_ALLOC;
diff --git a/media/libeffects/lvm/lib/Common/lib/LVM_Types.h b/media/libeffects/lvm/lib/Common/lib/LVM_Types.h
index 81655dd..0c6fb25 100644
--- a/media/libeffects/lvm/lib/Common/lib/LVM_Types.h
+++ b/media/libeffects/lvm/lib/Common/lib/LVM_Types.h
@@ -29,6 +29,7 @@
extern "C" {
#endif /* __cplusplus */
+#include <stdint.h>
/****************************************************************************************/
/* */
@@ -85,14 +86,14 @@ extern "C" {
typedef char LVM_CHAR; /* ASCII character */
-typedef char LVM_INT8; /* Signed 8-bit word */
-typedef unsigned char LVM_UINT8; /* Unsigned 8-bit word */
+typedef int8_t LVM_INT8; /* Signed 8-bit word */
+typedef uint8_t LVM_UINT8; /* Unsigned 8-bit word */
-typedef short LVM_INT16; /* Signed 16-bit word */
-typedef unsigned short LVM_UINT16; /* Unsigned 16-bit word */
+typedef int16_t LVM_INT16; /* Signed 16-bit word */
+typedef uint16_t LVM_UINT16; /* Unsigned 16-bit word */
-typedef long LVM_INT32; /* Signed 32-bit word */
-typedef unsigned long LVM_UINT32; /* Unsigned 32-bit word */
+typedef int32_t LVM_INT32; /* Signed 32-bit word */
+typedef uint32_t LVM_UINT32; /* Unsigned 32-bit word */
/****************************************************************************************/
diff --git a/media/libeffects/lvm/lib/Common/src/InstAlloc.c b/media/libeffects/lvm/lib/Common/src/InstAlloc.c
index 481df84..a89a5c3 100644
--- a/media/libeffects/lvm/lib/Common/src/InstAlloc.c
+++ b/media/libeffects/lvm/lib/Common/src/InstAlloc.c
@@ -30,7 +30,7 @@ void InstAlloc_Init( INST_ALLOC *pms,
void *StartAddr )
{
pms->TotalSize = 3;
- pms->pNextMember = (LVM_UINT32)(((LVM_UINT32)StartAddr + 3) & 0xFFFFFFFC);/* This code will fail if the platform address space is more than 32-bits*/
+ pms->pNextMember = (((uintptr_t)StartAddr + 3) & (uintptr_t)~3);
}
@@ -51,7 +51,7 @@ void* InstAlloc_AddMember( INST_ALLOC *pms,
void *NewMemberAddress; /* Variable to temporarily store the return value */
NewMemberAddress = (void*)pms->pNextMember;
- Size = ((Size + 3) & 0xFFFFFFFC); /* Ceil the size to a multiple of four */
+ Size = ((Size + 3) & (LVM_UINT32)~3); /* Ceil the size to a multiple of four */
pms->TotalSize += Size;
pms->pNextMember += Size;
@@ -84,30 +84,30 @@ LVM_UINT32 InstAlloc_GetTotal( INST_ALLOC *pms)
void InstAlloc_InitAll( INST_ALLOC *pms,
LVM_MemoryTable_st *pMemoryTable)
{
- LVM_UINT32 StartAddr;
+ uintptr_t StartAddr;
- StartAddr = (LVM_UINT32)pMemoryTable->Region[LVM_PERSISTENT_SLOW_DATA].pBaseAddress;
+ StartAddr = (uintptr_t)pMemoryTable->Region[LVM_PERSISTENT_SLOW_DATA].pBaseAddress;
pms[0].TotalSize = 3;
- pms[0].pNextMember = (LVM_UINT32)(((LVM_UINT32)StartAddr + 3) & 0xFFFFFFFC);
+ pms[0].pNextMember = ((StartAddr + 3) & (uintptr_t)~3);
- StartAddr = (LVM_UINT32)pMemoryTable->Region[LVM_PERSISTENT_FAST_DATA].pBaseAddress;
+ StartAddr = (uintptr_t)pMemoryTable->Region[LVM_PERSISTENT_FAST_DATA].pBaseAddress;
pms[1].TotalSize = 3;
- pms[1].pNextMember = (LVM_UINT32)(((LVM_UINT32)StartAddr + 3) & 0xFFFFFFFC);
+ pms[1].pNextMember = ((StartAddr + 3) & (uintptr_t)~3);
- StartAddr = (LVM_UINT32)pMemoryTable->Region[LVM_PERSISTENT_FAST_COEF].pBaseAddress;
+ StartAddr = (uintptr_t)pMemoryTable->Region[LVM_PERSISTENT_FAST_COEF].pBaseAddress;
pms[2].TotalSize = 3;
- pms[2].pNextMember = (LVM_UINT32)(((LVM_UINT32)StartAddr + 3) & 0xFFFFFFFC);
+ pms[2].pNextMember = ((StartAddr + 3) & (uintptr_t)~3);
- StartAddr = (LVM_UINT32)pMemoryTable->Region[LVM_TEMPORARY_FAST].pBaseAddress;
+ StartAddr = (uintptr_t)pMemoryTable->Region[LVM_TEMPORARY_FAST].pBaseAddress;
pms[3].TotalSize = 3;
- pms[3].pNextMember = (LVM_UINT32)(((LVM_UINT32)StartAddr + 3) & 0xFFFFFFFC);
+ pms[3].pNextMember = ((StartAddr + 3) & (uintptr_t)~3);
}
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Init.c b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Init.c
index c4767a8..e01c1c5 100644
--- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Init.c
+++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Init.c
@@ -25,6 +25,7 @@
#include "LVEQNB.h"
#include "LVEQNB_Private.h"
#include "InstAlloc.h"
+#include <string.h> /* For memset */
/****************************************************************************************/
/* */
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Process.c b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Process.c
index ac3c740..58f58ed 100644
--- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Process.c
+++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Process.c
@@ -77,7 +77,7 @@ LVEQNB_ReturnStatus_en LVEQNB_Process(LVEQNB_Handle_t hInstance,
}
/* Check if the input and output data buffers are 32-bit aligned */
- if ((((LVM_INT32)pInData % 4) != 0) || (((LVM_INT32)pOutData % 4) != 0))
+ if ((((uintptr_t)pInData % 4) != 0) || (((uintptr_t)pOutData % 4) != 0))
{
return LVEQNB_ALIGNMENTERROR;
}
diff --git a/media/libeffects/lvm/wrapper/Android.mk b/media/libeffects/lvm/wrapper/Android.mk
index f1af389..68ba34c 100644
--- a/media/libeffects/lvm/wrapper/Android.mk
+++ b/media/libeffects/lvm/wrapper/Android.mk
@@ -13,7 +13,7 @@ LOCAL_CFLAGS += -fvisibility=hidden
LOCAL_MODULE:= libbundlewrapper
-LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/soundfx
+LOCAL_MODULE_RELATIVE_PATH := soundfx
LOCAL_STATIC_LIBRARIES += libmusicbundle
@@ -42,7 +42,7 @@ LOCAL_CFLAGS += -fvisibility=hidden
LOCAL_MODULE:= libreverbwrapper
-LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/soundfx
+LOCAL_MODULE_RELATIVE_PATH := soundfx
LOCAL_STATIC_LIBRARIES += libreverb
diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
index 28d239a..db5c78f 100644
--- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
+++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
@@ -138,22 +138,22 @@ void Effect_getConfig (EffectContext *pContext, effect_config_t *pConfi
int BassBoost_setParameter (EffectContext *pContext, void *pParam, void *pValue);
int BassBoost_getParameter (EffectContext *pContext,
void *pParam,
- size_t *pValueSize,
+ uint32_t *pValueSize,
void *pValue);
int Virtualizer_setParameter (EffectContext *pContext, void *pParam, void *pValue);
int Virtualizer_getParameter (EffectContext *pContext,
void *pParam,
- size_t *pValueSize,
+ uint32_t *pValueSize,
void *pValue);
int Equalizer_setParameter (EffectContext *pContext, void *pParam, void *pValue);
int Equalizer_getParameter (EffectContext *pContext,
void *pParam,
- size_t *pValueSize,
+ uint32_t *pValueSize,
void *pValue);
int Volume_setParameter (EffectContext *pContext, void *pParam, void *pValue);
int Volume_getParameter (EffectContext *pContext,
void *pParam,
- size_t *pValueSize,
+ uint32_t *pValueSize,
void *pValue);
int Effect_setEnabled(EffectContext *pContext, bool enabled);
@@ -1758,7 +1758,7 @@ int32_t VolumeEnableStereoPosition(EffectContext *pContext, uint32_t enabled){
int BassBoost_getParameter(EffectContext *pContext,
void *pParam,
- size_t *pValueSize,
+ uint32_t *pValueSize,
void *pValue){
int status = 0;
int32_t *pParamTemp = (int32_t *)pParam;
@@ -1876,7 +1876,7 @@ int BassBoost_setParameter (EffectContext *pContext, void *pParam, void *pValue)
int Virtualizer_getParameter(EffectContext *pContext,
void *pParam,
- size_t *pValueSize,
+ uint32_t *pValueSize,
void *pValue){
int status = 0;
int32_t *pParamTemp = (int32_t *)pParam;
@@ -1994,7 +1994,7 @@ int Virtualizer_setParameter (EffectContext *pContext, void *pParam, void *pValu
//----------------------------------------------------------------------------
int Equalizer_getParameter(EffectContext *pContext,
void *pParam,
- size_t *pValueSize,
+ uint32_t *pValueSize,
void *pValue){
int status = 0;
int bMute = 0;
@@ -2252,7 +2252,7 @@ int Equalizer_setParameter (EffectContext *pContext, void *pParam, void *pValue)
int Volume_getParameter(EffectContext *pContext,
void *pParam,
- size_t *pValueSize,
+ uint32_t *pValueSize,
void *pValue){
int status = 0;
int bMute = 0;
@@ -2813,9 +2813,9 @@ int Effect_command(effect_handle_t self,
if(pContext->EffectType == LVM_BASS_BOOST){
if (pCmdData == NULL ||
- cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)) ||
+ cmdSize < (sizeof(effect_param_t) + sizeof(int32_t)) ||
pReplyData == NULL ||
- *replySize < (int) (sizeof(effect_param_t) + sizeof(int32_t))){
+ *replySize < (sizeof(effect_param_t) + sizeof(int32_t))){
ALOGV("\tLVM_ERROR : BassBoost_command cmdCode Case: "
"EFFECT_CMD_GET_PARAM: ERROR");
return -EINVAL;
@@ -2830,7 +2830,7 @@ int Effect_command(effect_handle_t self,
p->status = android::BassBoost_getParameter(pContext,
p->data,
- (size_t *)&p->vsize,
+ &p->vsize,
p->data + voffset);
*replySize = sizeof(effect_param_t) + voffset + p->vsize;
@@ -2844,9 +2844,9 @@ int Effect_command(effect_handle_t self,
if(pContext->EffectType == LVM_VIRTUALIZER){
if (pCmdData == NULL ||
- cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)) ||
+ cmdSize < (sizeof(effect_param_t) + sizeof(int32_t)) ||
pReplyData == NULL ||
- *replySize < (int) (sizeof(effect_param_t) + sizeof(int32_t))){
+ *replySize < (sizeof(effect_param_t) + sizeof(int32_t))){
ALOGV("\tLVM_ERROR : Virtualizer_command cmdCode Case: "
"EFFECT_CMD_GET_PARAM: ERROR");
return -EINVAL;
@@ -2860,8 +2860,8 @@ int Effect_command(effect_handle_t self,
int voffset = ((p->psize - 1) / sizeof(int32_t) + 1) * sizeof(int32_t);
p->status = android::Virtualizer_getParameter(pContext,
- (void *)p->data,
- (size_t *)&p->vsize,
+ (void *)p->data,
+ &p->vsize,
p->data + voffset);
*replySize = sizeof(effect_param_t) + voffset + p->vsize;
@@ -2876,7 +2876,7 @@ int Effect_command(effect_handle_t self,
//ALOGV("\tEqualizer_command cmdCode Case: "
// "EFFECT_CMD_GET_PARAM start");
if (pCmdData == NULL ||
- cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)) ||
+ cmdSize < (sizeof(effect_param_t) + sizeof(int32_t)) ||
pReplyData == NULL ||
*replySize < (int) (sizeof(effect_param_t) + sizeof(int32_t))) {
ALOGV("\tLVM_ERROR : Equalizer_command cmdCode Case: "
@@ -2908,7 +2908,7 @@ int Effect_command(effect_handle_t self,
if(pContext->EffectType == LVM_VOLUME){
//ALOGV("\tVolume_command cmdCode Case: EFFECT_CMD_GET_PARAM start");
if (pCmdData == NULL ||
- cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)) ||
+ cmdSize < (sizeof(effect_param_t) + sizeof(int32_t)) ||
pReplyData == NULL ||
*replySize < (int) (sizeof(effect_param_t) + sizeof(int32_t))){
ALOGV("\tLVM_ERROR : Volume_command cmdCode Case: "
@@ -2925,7 +2925,7 @@ int Effect_command(effect_handle_t self,
p->status = android::Volume_getParameter(pContext,
(void *)p->data,
- (size_t *)&p->vsize,
+ &p->vsize,
p->data + voffset);
*replySize = sizeof(effect_param_t) + voffset + p->vsize;
@@ -2947,7 +2947,7 @@ int Effect_command(effect_handle_t self,
// *(int16_t *)((char *)pCmdData + sizeof(effect_param_t) + sizeof(int32_t)));
if (pCmdData == NULL||
- cmdSize != (int)(sizeof(effect_param_t) + sizeof(int32_t) +sizeof(int16_t))||
+ cmdSize != (sizeof(effect_param_t) + sizeof(int32_t) +sizeof(int16_t))||
pReplyData == NULL||
*replySize != sizeof(int32_t)){
ALOGV("\tLVM_ERROR : BassBoost_command cmdCode Case: "
@@ -2980,7 +2980,7 @@ int Effect_command(effect_handle_t self,
// *(int16_t *)((char *)pCmdData + sizeof(effect_param_t) + sizeof(int32_t)));
if (pCmdData == NULL||
- cmdSize != (int)(sizeof(effect_param_t) + sizeof(int32_t) +sizeof(int16_t))||
+ cmdSize != (sizeof(effect_param_t) + sizeof(int32_t) +sizeof(int16_t))||
pReplyData == NULL||
*replySize != sizeof(int32_t)){
ALOGV("\tLVM_ERROR : Virtualizer_command cmdCode Case: "
@@ -3014,7 +3014,7 @@ int Effect_command(effect_handle_t self,
// *replySize,
// *(int16_t *)((char *)pCmdData + sizeof(effect_param_t) + sizeof(int32_t)));
- if (pCmdData == NULL || cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)) ||
+ if (pCmdData == NULL || cmdSize < (sizeof(effect_param_t) + sizeof(int32_t)) ||
pReplyData == NULL || *replySize != sizeof(int32_t)) {
ALOGV("\tLVM_ERROR : Equalizer_command cmdCode Case: "
"EFFECT_CMD_SET_PARAM: ERROR");
@@ -3034,7 +3034,7 @@ int Effect_command(effect_handle_t self,
// *(int16_t *)((char *)pCmdData + sizeof(effect_param_t) +sizeof(int32_t)));
if ( pCmdData == NULL||
- cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t))||
+ cmdSize < (sizeof(effect_param_t) + sizeof(int32_t))||
pReplyData == NULL||
*replySize != sizeof(int32_t)){
ALOGV("\tLVM_ERROR : Volume_command cmdCode Case: "
diff --git a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
index 0367302..c6d3759 100644
--- a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
+++ b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
@@ -181,7 +181,7 @@ void Reverb_getConfig (ReverbContext *pContext, effect_config_t *pConfig);
int Reverb_setParameter (ReverbContext *pContext, void *pParam, void *pValue);
int Reverb_getParameter (ReverbContext *pContext,
void *pParam,
- size_t *pValueSize,
+ uint32_t *pValueSize,
void *pValue);
int Reverb_LoadPreset (ReverbContext *pContext);
@@ -1534,7 +1534,7 @@ int Reverb_LoadPreset(ReverbContext *pContext)
int Reverb_getParameter(ReverbContext *pContext,
void *pParam,
- size_t *pValueSize,
+ uint32_t *pValueSize,
void *pValue){
int status = 0;
int32_t *pParamTemp = (int32_t *)pParam;
@@ -1956,9 +1956,9 @@ int Reverb_command(effect_handle_t self,
//ALOGV("\tReverb_command cmdCode Case: "
// "EFFECT_CMD_GET_PARAM start");
if (pCmdData == NULL ||
- cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)) ||
+ cmdSize < (sizeof(effect_param_t) + sizeof(int32_t)) ||
pReplyData == NULL ||
- *replySize < (int) (sizeof(effect_param_t) + sizeof(int32_t))){
+ *replySize < (sizeof(effect_param_t) + sizeof(int32_t))){
ALOGV("\tLVM_ERROR : Reverb_command cmdCode Case: "
"EFFECT_CMD_GET_PARAM: ERROR");
return -EINVAL;
@@ -1973,7 +1973,7 @@ int Reverb_command(effect_handle_t self,
p->status = android::Reverb_getParameter(pContext,
(void *)p->data,
- (size_t *)&p->vsize,
+ &p->vsize,
p->data + voffset);
*replySize = sizeof(effect_param_t) + voffset + p->vsize;
@@ -1994,8 +1994,8 @@ int Reverb_command(effect_handle_t self,
// *replySize,
// *(int16_t *)((char *)pCmdData + sizeof(effect_param_t) + sizeof(int32_t)));
- if (pCmdData == NULL || (cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)))
- || pReplyData == NULL || *replySize != (int)sizeof(int32_t)) {
+ if (pCmdData == NULL || (cmdSize < (sizeof(effect_param_t) + sizeof(int32_t)))
+ || pReplyData == NULL || *replySize != sizeof(int32_t)) {
ALOGV("\tLVM_ERROR : Reverb_command cmdCode Case: "
"EFFECT_CMD_SET_PARAM: ERROR");
return -EINVAL;
diff --git a/media/libeffects/preprocessing/Android.mk b/media/libeffects/preprocessing/Android.mk
index c344352..9e8cb83 100644
--- a/media/libeffects/preprocessing/Android.mk
+++ b/media/libeffects/preprocessing/Android.mk
@@ -5,7 +5,7 @@ include $(CLEAR_VARS)
LOCAL_MODULE:= libaudiopreprocessing
LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/soundfx
+LOCAL_MODULE_RELATIVE_PATH := soundfx
LOCAL_SRC_FILES:= \
PreProcessing.cpp
diff --git a/media/libeffects/preprocessing/PreProcessing.cpp b/media/libeffects/preprocessing/PreProcessing.cpp
index d72eaf5..a96a703 100644
--- a/media/libeffects/preprocessing/PreProcessing.cpp
+++ b/media/libeffects/preprocessing/PreProcessing.cpp
@@ -77,7 +77,7 @@ struct preproc_ops_s {
void (* enable)(preproc_effect_t *fx);
void (* disable)(preproc_effect_t *fx);
int (* set_parameter)(preproc_effect_t *fx, void *param, void *value);
- int (* get_parameter)(preproc_effect_t *fx, void *param, size_t *size, void *value);
+ int (* get_parameter)(preproc_effect_t *fx, void *param, uint32_t *size, void *value);
int (* set_device)(preproc_effect_t *fx, uint32_t device);
};
@@ -291,7 +291,7 @@ int AgcCreate(preproc_effect_t *effect)
int AgcGetParameter(preproc_effect_t *effect,
void *pParam,
- size_t *pValueSize,
+ uint32_t *pValueSize,
void *pValue)
{
int status = 0;
@@ -452,9 +452,9 @@ int AecCreate(preproc_effect_t *effect)
return 0;
}
-int AecGetParameter(preproc_effect_t *effect,
+int AecGetParameter(preproc_effect_t *effect,
void *pParam,
- size_t *pValueSize,
+ uint32_t *pValueSize,
void *pValue)
{
int status = 0;
@@ -575,9 +575,9 @@ int NsCreate(preproc_effect_t *effect)
return 0;
}
-int NsGetParameter(preproc_effect_t *effect,
+int NsGetParameter(preproc_effect_t *effect,
void *pParam,
- size_t *pValueSize,
+ uint32_t *pValueSize,
void *pValue)
{
int status = 0;
@@ -1233,8 +1233,8 @@ int PreProcessingFx_Process(effect_handle_t self,
if (session->framesIn < session->frameCount) {
return 0;
}
- size_t frIn = session->framesIn;
- size_t frOut = session->apmFrameCount;
+ spx_uint32_t frIn = session->framesIn;
+ spx_uint32_t frOut = session->apmFrameCount;
if (session->inChannelCount == 1) {
speex_resampler_process_int(session->inResampler,
0,
@@ -1290,8 +1290,8 @@ int PreProcessingFx_Process(effect_handle_t self,
}
if (session->outResampler != NULL) {
- size_t frIn = session->apmFrameCount;
- size_t frOut = session->frameCount;
+ spx_uint32_t frIn = session->apmFrameCount;
+ spx_uint32_t frOut = session->frameCount;
if (session->inChannelCount == 1) {
speex_resampler_process_int(session->outResampler,
0,
@@ -1453,7 +1453,7 @@ int PreProcessingFx_Command(effect_handle_t self,
if (effect->ops->get_parameter) {
p->status = effect->ops->get_parameter(effect, p->data,
- (size_t *)&p->vsize,
+ &p->vsize,
p->data + voffset);
*replySize = sizeof(effect_param_t) + voffset + p->vsize;
}
@@ -1754,8 +1754,8 @@ int PreProcessingFx_ProcessReverse(effect_handle_t self,
if (session->framesRev < session->frameCount) {
return 0;
}
- size_t frIn = session->framesRev;
- size_t frOut = session->apmFrameCount;
+ spx_uint32_t frIn = session->framesRev;
+ spx_uint32_t frOut = session->apmFrameCount;
if (session->inChannelCount == 1) {
speex_resampler_process_int(session->revResampler,
0,
diff --git a/media/libeffects/proxy/Android.mk b/media/libeffects/proxy/Android.mk
index 01b3be1..b438796 100644
--- a/media/libeffects/proxy/Android.mk
+++ b/media/libeffects/proxy/Android.mk
@@ -15,7 +15,7 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE:= libeffectproxy
-LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/soundfx
+LOCAL_MODULE_RELATIVE_PATH := soundfx
LOCAL_MODULE_TAGS := optional
@@ -28,7 +28,8 @@ LOCAL_SHARED_LIBRARIES := liblog libcutils libutils libdl libeffects
LOCAL_C_INCLUDES := \
system/media/audio_effects/include \
- bionic/libc/include
+ bionic/libc/include \
+ frameworks/av/media/libeffects/factory
include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libeffects/proxy/EffectProxy.cpp b/media/libeffects/proxy/EffectProxy.cpp
index dd4ad08..62d3fd3 100644
--- a/media/libeffects/proxy/EffectProxy.cpp
+++ b/media/libeffects/proxy/EffectProxy.cpp
@@ -56,6 +56,8 @@ int EffectProxyCreate(const effect_uuid_t *uuid,
effect_handle_t *pHandle) {
effect_descriptor_t* desc;
+ audio_effect_library_t** aeli;
+ sub_effect_entry_t** sube;
EffectContext* pContext;
if (pHandle == NULL || uuid == NULL) {
ALOGE("EffectProxyCreate() called with NULL pointer");
@@ -74,31 +76,52 @@ int EffectProxyCreate(const effect_uuid_t *uuid,
// Get the HW and SW sub effect descriptors from the effects factory
desc = new effect_descriptor_t[SUB_FX_COUNT];
+ aeli = new audio_effect_library_t*[SUB_FX_COUNT];
+ sube = new sub_effect_entry_t*[SUB_FX_COUNT];
+ pContext->sube = new sub_effect_entry_t*[SUB_FX_COUNT];
pContext->desc = new effect_descriptor_t[SUB_FX_COUNT];
- int retValue = EffectGetSubEffects(uuid, desc,
- sizeof(effect_descriptor_t) * SUB_FX_COUNT);
+ pContext->aeli = new audio_effect_library_t*[SUB_FX_COUNT];
+ int retValue = EffectGetSubEffects(uuid, sube, SUB_FX_COUNT);
// EffectGetSubEffects returns the number of sub-effects copied.
if (retValue != SUB_FX_COUNT) {
ALOGE("EffectCreate() could not get the sub effects");
- delete desc;
- delete pContext->desc;
+ delete[] sube;
+ delete[] desc;
+ delete[] aeli;
+ delete[] pContext->sube;
+ delete[] pContext->desc;
+ delete[] pContext->aeli;
return -EINVAL;
}
// Check which is the HW descriptor and copy the descriptors
// to the Context desc array
// Also check if there is only one HW and one SW descriptor.
// HW descriptor alone has the HW_TUNNEL flag.
+ desc[0] = *(effect_descriptor_t*)(sube[0])->object;
+ desc[1] = *(effect_descriptor_t*)(sube[1])->object;
+ aeli[0] = sube[0]->lib->desc;
+ aeli[1] = sube[1]->lib->desc;
if ((desc[0].flags & EFFECT_FLAG_HW_ACC_TUNNEL) &&
!(desc[1].flags & EFFECT_FLAG_HW_ACC_TUNNEL)) {
+ pContext->sube[SUB_FX_OFFLOAD] = sube[0];
pContext->desc[SUB_FX_OFFLOAD] = desc[0];
+ pContext->aeli[SUB_FX_OFFLOAD] = aeli[0];
+ pContext->sube[SUB_FX_HOST] = sube[1];
pContext->desc[SUB_FX_HOST] = desc[1];
+ pContext->aeli[SUB_FX_HOST] = aeli[1];
}
else if ((desc[1].flags & EFFECT_FLAG_HW_ACC_TUNNEL) &&
!(desc[0].flags & EFFECT_FLAG_HW_ACC_TUNNEL)) {
+ pContext->sube[SUB_FX_HOST] = sube[0];
pContext->desc[SUB_FX_HOST] = desc[0];
+ pContext->aeli[SUB_FX_HOST] = aeli[0];
+ pContext->sube[SUB_FX_OFFLOAD] = sube[1];
pContext->desc[SUB_FX_OFFLOAD] = desc[1];
+ pContext->aeli[SUB_FX_OFFLOAD] = aeli[1];
}
- delete desc;
+ delete[] desc;
+ delete[] aeli;
+ delete[] sube;
#if (LOG_NDEBUG == 0)
effect_uuid_t uuid_print = pContext->desc[SUB_FX_HOST].uuid;
ALOGV("EffectCreate() UUID of HOST: %08X-%04X-%04X-%04X-%02X%02X%02X%02X"
@@ -128,13 +151,15 @@ int EffectProxyRelease(effect_handle_t handle) {
return -EINVAL;
}
ALOGV("EffectRelease");
- delete pContext->desc;
+ delete[] pContext->desc;
free(pContext->replyData);
if (pContext->eHandle[SUB_FX_HOST])
- EffectRelease(pContext->eHandle[SUB_FX_HOST]);
+ pContext->aeli[SUB_FX_HOST]->release_effect(pContext->eHandle[SUB_FX_HOST]);
if (pContext->eHandle[SUB_FX_OFFLOAD])
- EffectRelease(pContext->eHandle[SUB_FX_OFFLOAD]);
+ pContext->aeli[SUB_FX_OFFLOAD]->release_effect(pContext->eHandle[SUB_FX_OFFLOAD]);
+ delete[] pContext->aeli;
+ delete[] pContext->sube;
delete pContext;
pContext = NULL;
return 0;
@@ -187,7 +212,8 @@ int Effect_command(effect_handle_t self,
}
if (pContext->eHandle[SUB_FX_HOST] == NULL) {
ALOGV("Effect_command() Calling HOST EffectCreate");
- status = EffectCreate(&pContext->desc[SUB_FX_HOST].uuid,
+ status = pContext->aeli[SUB_FX_HOST]->create_effect(
+ &pContext->desc[SUB_FX_HOST].uuid,
pContext->sessionId, pContext->ioId,
&(pContext->eHandle[SUB_FX_HOST]));
if (status != NO_ERROR || (pContext->eHandle[SUB_FX_HOST] == NULL)) {
@@ -197,11 +223,13 @@ int Effect_command(effect_handle_t self,
}
if (pContext->eHandle[SUB_FX_OFFLOAD] == NULL) {
ALOGV("Effect_command() Calling OFFLOAD EffectCreate");
- status = EffectCreate(&pContext->desc[SUB_FX_OFFLOAD].uuid,
+ status = pContext->aeli[SUB_FX_OFFLOAD]->create_effect(
+ &pContext->desc[SUB_FX_OFFLOAD].uuid,
pContext->sessionId, pContext->ioId,
&(pContext->eHandle[SUB_FX_OFFLOAD]));
if (status != NO_ERROR || (pContext->eHandle[SUB_FX_OFFLOAD] == NULL)) {
ALOGV("Effect_command() Error creating HW effect");
+ pContext->eHandle[SUB_FX_OFFLOAD] = NULL;
// Do not return error here as SW effect is created
// Return error if the CMD_OFFLOAD sends the index as OFFLOAD
}
@@ -233,11 +261,17 @@ int Effect_command(effect_handle_t self,
// Update the DSP wrapper with the new ioHandle.
// Pass the OFFLOAD command to the wrapper.
// The DSP wrapper needs to handle this CMD
- if (pContext->eHandle[SUB_FX_OFFLOAD])
- status = (*pContext->eHandle[SUB_FX_OFFLOAD])->command(
- pContext->eHandle[SUB_FX_OFFLOAD], cmdCode, cmdSize,
- pCmdData, replySize, pReplyData);
- return status;
+ if (pContext->eHandle[SUB_FX_OFFLOAD]) {
+ ALOGV("Effect_command: Calling OFFLOAD command");
+ return (*pContext->eHandle[SUB_FX_OFFLOAD])->command(
+ pContext->eHandle[SUB_FX_OFFLOAD], cmdCode, cmdSize,
+ pCmdData, replySize, pReplyData);
+ }
+ *(int*)pReplyData = NO_ERROR;
+ ALOGV("Effect_command OFFLOAD return 0, replyData %d",
+ *(int*)pReplyData);
+
+ return NO_ERROR;
}
int index = pContext->index;
@@ -329,11 +363,11 @@ int Effect_getDescriptor(effect_handle_t self,
__attribute__ ((visibility ("default")))
audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = {
- tag : AUDIO_EFFECT_LIBRARY_TAG,
- version : EFFECT_LIBRARY_API_VERSION,
- name : "Effect Proxy",
- implementor : "AOSP",
- create_effect : android::EffectProxyCreate,
- release_effect : android::EffectProxyRelease,
- get_descriptor : android::EffectProxyGetDescriptor,
+ .tag = AUDIO_EFFECT_LIBRARY_TAG,
+ .version = EFFECT_LIBRARY_API_VERSION,
+ .name = "Effect Proxy",
+ .implementor = "AOSP",
+ .create_effect = android::EffectProxyCreate,
+ .release_effect = android::EffectProxyRelease,
+ .get_descriptor = android::EffectProxyGetDescriptor,
};
diff --git a/media/libeffects/proxy/EffectProxy.h b/media/libeffects/proxy/EffectProxy.h
index acbe17e..046b93e 100644
--- a/media/libeffects/proxy/EffectProxy.h
+++ b/media/libeffects/proxy/EffectProxy.h
@@ -16,6 +16,8 @@
#include <hardware/audio.h>
#include <hardware/audio_effect.h>
+#include "EffectsFactory.h"
+
namespace android {
enum {
SUB_FX_HOST, // Index of HOST in the descriptor and handle arrays
@@ -62,7 +64,9 @@ const struct effect_interface_s gEffectInterface = {
struct EffectContext {
const struct effect_interface_s *common_itfe; // Holds the itfe of the Proxy
+ sub_effect_entry_t** sube; // Points to the sub effects
effect_descriptor_t* desc; // Points to the sub effect descriptors
+ audio_effect_library_t** aeli; // Points to the sub effect aeli
effect_handle_t eHandle[SUB_FX_COUNT]; // The effect handles of the sub effects
int index; // The index that is currently active - HOST or OFFLOAD
int32_t sessionId; // The sessiond in which the effect is created.
diff --git a/media/libeffects/testlibs/Android.mk_ b/media/libeffects/testlibs/Android.mk_
index 2954908..672ebba 100644
--- a/media/libeffects/testlibs/Android.mk_
+++ b/media/libeffects/testlibs/Android.mk_
@@ -11,7 +11,7 @@ LOCAL_CFLAGS+= -O2
LOCAL_SHARED_LIBRARIES := \
libcutils
-LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/soundfx
+LOCAL_MODULE_RELATIVE_PATH := soundfx
LOCAL_MODULE:= libreverbtest
ifeq ($(TARGET_OS)-$(TARGET_SIMULATOR),linux-true)
@@ -47,7 +47,7 @@ LOCAL_CFLAGS+= -O2
LOCAL_SHARED_LIBRARIES := \
libcutils
-LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/soundfx
+LOCAL_MODULE_RELATIVE_PATH := soundfx
LOCAL_MODULE:= libequalizertest
ifeq ($(TARGET_OS)-$(TARGET_SIMULATOR),linux-true)
diff --git a/media/libeffects/testlibs/EffectEqualizer.cpp b/media/libeffects/testlibs/EffectEqualizer.cpp
index 8d00206..3cb13f2 100644
--- a/media/libeffects/testlibs/EffectEqualizer.cpp
+++ b/media/libeffects/testlibs/EffectEqualizer.cpp
@@ -115,7 +115,7 @@ struct EqualizerContext {
int Equalizer_init(EqualizerContext *pContext);
int Equalizer_setConfig(EqualizerContext *pContext, effect_config_t *pConfig);
-int Equalizer_getParameter(AudioEqualizer * pEqualizer, int32_t *pParam, size_t *pValueSize, void *pValue);
+int Equalizer_getParameter(AudioEqualizer * pEqualizer, int32_t *pParam, uint32_t *pValueSize, void *pValue);
int Equalizer_setParameter(AudioEqualizer * pEqualizer, int32_t *pParam, void *pValue);
@@ -360,7 +360,7 @@ int Equalizer_init(EqualizerContext *pContext)
//
//----------------------------------------------------------------------------
-int Equalizer_getParameter(AudioEqualizer * pEqualizer, int32_t *pParam, size_t *pValueSize, void *pValue)
+int Equalizer_getParameter(AudioEqualizer * pEqualizer, int32_t *pParam, uint32_t *pValueSize, void *pValue)
{
int status = 0;
int32_t param = *pParam++;
@@ -662,8 +662,8 @@ extern "C" int Equalizer_command(effect_handle_t self, uint32_t cmdCode, uint32_
Equalizer_setConfig(pContext, &pContext->config);
break;
case EFFECT_CMD_GET_PARAM: {
- if (pCmdData == NULL || cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)) ||
- pReplyData == NULL || *replySize < (int) (sizeof(effect_param_t) + sizeof(int32_t))) {
+ if (pCmdData == NULL || cmdSize < (sizeof(effect_param_t) + sizeof(int32_t)) ||
+ pReplyData == NULL || *replySize < (sizeof(effect_param_t) + sizeof(int32_t))) {
return -EINVAL;
}
effect_param_t *p = (effect_param_t *)pCmdData;
@@ -682,7 +682,7 @@ extern "C" int Equalizer_command(effect_handle_t self, uint32_t cmdCode, uint32_
case EFFECT_CMD_SET_PARAM: {
ALOGV("Equalizer_command EFFECT_CMD_SET_PARAM cmdSize %d pCmdData %p, *replySize %d, pReplyData %p",
cmdSize, pCmdData, *replySize, pReplyData);
- if (pCmdData == NULL || cmdSize < (int)(sizeof(effect_param_t) + sizeof(int32_t)) ||
+ if (pCmdData == NULL || cmdSize < (sizeof(effect_param_t) + sizeof(int32_t)) ||
pReplyData == NULL || *replySize != sizeof(int32_t)) {
return -EINVAL;
}
diff --git a/media/libeffects/testlibs/EffectReverb.c b/media/libeffects/testlibs/EffectReverb.c
index c37f392..f056d19 100644
--- a/media/libeffects/testlibs/EffectReverb.c
+++ b/media/libeffects/testlibs/EffectReverb.c
@@ -750,7 +750,7 @@ void Reverb_Reset(reverb_object_t *pReverb, bool init) {
*
*----------------------------------------------------------------------------
*/
-int Reverb_getParameter(reverb_object_t *pReverb, int32_t param, size_t *pSize,
+int Reverb_getParameter(reverb_object_t *pReverb, int32_t param, uint32_t *pSize,
void *pValue) {
int32_t *pValue32;
int16_t *pValue16;
@@ -758,7 +758,7 @@ int Reverb_getParameter(reverb_object_t *pReverb, int32_t param, size_t *pSize,
int32_t i;
int32_t temp;
int32_t temp2;
- size_t size;
+ uint32_t size;
if (pReverb->m_Preset) {
if (param != REVERB_PARAM_PRESET || *pSize < sizeof(int16_t)) {
@@ -1033,7 +1033,7 @@ int Reverb_getParameter(reverb_object_t *pReverb, int32_t param, size_t *pSize,
*
*----------------------------------------------------------------------------
*/
-int Reverb_setParameter(reverb_object_t *pReverb, int32_t param, size_t size,
+int Reverb_setParameter(reverb_object_t *pReverb, int32_t param, uint32_t size,
void *pValue) {
int32_t value32;
int16_t value16;
@@ -1044,7 +1044,7 @@ int Reverb_setParameter(reverb_object_t *pReverb, int32_t param, size_t size,
reverb_preset_t *pPreset;
int maxSamples;
int32_t averageDelay;
- size_t paramSize;
+ uint32_t paramSize;
ALOGV("Reverb_setParameter, context %p, param %d, value16 %d, value32 %d",
pReverb, param, *(int16_t *)pValue, *(int32_t *)pValue);
diff --git a/media/libeffects/testlibs/EffectReverb.h b/media/libeffects/testlibs/EffectReverb.h
index e5248fe..756c5ea 100644
--- a/media/libeffects/testlibs/EffectReverb.h
+++ b/media/libeffects/testlibs/EffectReverb.h
@@ -330,8 +330,8 @@ int Reverb_setConfig(reverb_module_t *pRvbModule, effect_config_t *pConfig, bool
void Reverb_getConfig(reverb_module_t *pRvbModule, effect_config_t *pConfig);
void Reverb_Reset(reverb_object_t *pReverb, bool init);
-int Reverb_setParameter (reverb_object_t *pReverb, int32_t param, size_t size, void *pValue);
-int Reverb_getParameter(reverb_object_t *pReverb, int32_t param, size_t *pSize, void *pValue);
+int Reverb_setParameter (reverb_object_t *pReverb, int32_t param, uint32_t size, void *pValue);
+int Reverb_getParameter(reverb_object_t *pReverb, int32_t param, uint32_t *pSize, void *pValue);
/*----------------------------------------------------------------------------
* ReverbUpdateXfade
diff --git a/media/libeffects/visualizer/Android.mk b/media/libeffects/visualizer/Android.mk
index e196eb2..dd2d306 100644
--- a/media/libeffects/visualizer/Android.mk
+++ b/media/libeffects/visualizer/Android.mk
@@ -13,7 +13,7 @@ LOCAL_SHARED_LIBRARIES := \
liblog \
libdl
-LOCAL_MODULE_PATH := $(TARGET_OUT_SHARED_LIBRARIES)/soundfx
+LOCAL_MODULE_RELATIVE_PATH := soundfx
LOCAL_MODULE:= libvisualizer
LOCAL_C_INCLUDES := \
diff --git a/media/libeffects/visualizer/EffectVisualizer.cpp b/media/libeffects/visualizer/EffectVisualizer.cpp
index 2d66eef..47cab62 100644
--- a/media/libeffects/visualizer/EffectVisualizer.cpp
+++ b/media/libeffects/visualizer/EffectVisualizer.cpp
@@ -16,8 +16,9 @@
#define LOG_TAG "EffectVisualizer"
//#define LOG_NDEBUG 0
-#include <cutils/log.h>
+#include <log/log.h>
#include <assert.h>
+#include <inttypes.h>
#include <stdlib.h>
#include <string.h>
#include <new>
@@ -226,8 +227,8 @@ int Visualizer_init(VisualizerContext *pContext)
//
int VisualizerLib_Create(const effect_uuid_t *uuid,
- int32_t sessionId,
- int32_t ioId,
+ int32_t /*sessionId*/,
+ int32_t /*ioId*/,
effect_handle_t *pHandle) {
int ret;
int i;
@@ -418,7 +419,7 @@ int Visualizer_command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize,
return -EINVAL;
}
-// ALOGV("Visualizer_command command %d cmdSize %d",cmdCode, cmdSize);
+// ALOGV("Visualizer_command command %" PRIu32 " cmdSize %" PRIu32, cmdCode, cmdSize);
switch (cmdCode) {
case EFFECT_CMD_INIT:
@@ -484,19 +485,19 @@ int Visualizer_command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize,
}
switch (*(uint32_t *)p->data) {
case VISUALIZER_PARAM_CAPTURE_SIZE:
- ALOGV("get mCaptureSize = %d", pContext->mCaptureSize);
+ ALOGV("get mCaptureSize = %" PRIu32, pContext->mCaptureSize);
*((uint32_t *)p->data + 1) = pContext->mCaptureSize;
p->vsize = sizeof(uint32_t);
*replySize += sizeof(uint32_t);
break;
case VISUALIZER_PARAM_SCALING_MODE:
- ALOGV("get mScalingMode = %d", pContext->mScalingMode);
+ ALOGV("get mScalingMode = %" PRIu32, pContext->mScalingMode);
*((uint32_t *)p->data + 1) = pContext->mScalingMode;
p->vsize = sizeof(uint32_t);
*replySize += sizeof(uint32_t);
break;
case VISUALIZER_PARAM_MEASUREMENT_MODE:
- ALOGV("get mMeasurementMode = %d", pContext->mMeasurementMode);
+ ALOGV("get mMeasurementMode = %" PRIu32, pContext->mMeasurementMode);
*((uint32_t *)p->data + 1) = pContext->mMeasurementMode;
p->vsize = sizeof(uint32_t);
*replySize += sizeof(uint32_t);
@@ -520,19 +521,19 @@ int Visualizer_command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize,
switch (*(uint32_t *)p->data) {
case VISUALIZER_PARAM_CAPTURE_SIZE:
pContext->mCaptureSize = *((uint32_t *)p->data + 1);
- ALOGV("set mCaptureSize = %d", pContext->mCaptureSize);
+ ALOGV("set mCaptureSize = %" PRIu32, pContext->mCaptureSize);
break;
case VISUALIZER_PARAM_SCALING_MODE:
pContext->mScalingMode = *((uint32_t *)p->data + 1);
- ALOGV("set mScalingMode = %d", pContext->mScalingMode);
+ ALOGV("set mScalingMode = %" PRIu32, pContext->mScalingMode);
break;
case VISUALIZER_PARAM_LATENCY:
pContext->mLatency = *((uint32_t *)p->data + 1);
- ALOGV("set mLatency = %d", pContext->mLatency);
+ ALOGV("set mLatency = %" PRIu32, pContext->mLatency);
break;
case VISUALIZER_PARAM_MEASUREMENT_MODE:
pContext->mMeasurementMode = *((uint32_t *)p->data + 1);
- ALOGV("set mMeasurementMode = %d", pContext->mMeasurementMode);
+ ALOGV("set mMeasurementMode = %" PRIu32, pContext->mMeasurementMode);
break;
default:
*(int32_t *)pReplyData = -EINVAL;
@@ -544,56 +545,57 @@ int Visualizer_command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize,
break;
- case VISUALIZER_CMD_CAPTURE:
- if (pReplyData == NULL || *replySize != pContext->mCaptureSize) {
- ALOGV("VISUALIZER_CMD_CAPTURE() error *replySize %d pContext->mCaptureSize %d",
- *replySize, pContext->mCaptureSize);
+ case VISUALIZER_CMD_CAPTURE: {
+ uint32_t captureSize = pContext->mCaptureSize;
+ if (pReplyData == NULL || *replySize != captureSize) {
+ ALOGV("VISUALIZER_CMD_CAPTURE() error *replySize %" PRIu32 " captureSize %" PRIu32,
+ *replySize, captureSize);
return -EINVAL;
}
if (pContext->mState == VISUALIZER_STATE_ACTIVE) {
- int32_t latencyMs = pContext->mLatency;
const uint32_t deltaMs = Visualizer_getDeltaTimeMsFromUpdatedTime(pContext);
- latencyMs -= deltaMs;
- if (latencyMs < 0) {
- latencyMs = 0;
- }
- const uint32_t deltaSmpl = pContext->mConfig.inputCfg.samplingRate * latencyMs / 1000;
-
- int32_t capturePoint = pContext->mCaptureIdx - pContext->mCaptureSize - deltaSmpl;
- int32_t captureSize = pContext->mCaptureSize;
- if (capturePoint < 0) {
- int32_t size = -capturePoint;
- if (size > captureSize) {
- size = captureSize;
- }
- memcpy(pReplyData,
- pContext->mCaptureBuf + CAPTURE_BUF_SIZE + capturePoint,
- size);
- pReplyData = (char *)pReplyData + size;
- captureSize -= size;
- capturePoint = 0;
- }
- memcpy(pReplyData,
- pContext->mCaptureBuf + capturePoint,
- captureSize);
-
// if audio framework has stopped playing audio although the effect is still
// active we must clear the capture buffer to return silence
if ((pContext->mLastCaptureIdx == pContext->mCaptureIdx) &&
- (pContext->mBufferUpdateTime.tv_sec != 0)) {
- if (deltaMs > MAX_STALL_TIME_MS) {
+ (pContext->mBufferUpdateTime.tv_sec != 0) &&
+ (deltaMs > MAX_STALL_TIME_MS)) {
ALOGV("capture going to idle");
pContext->mBufferUpdateTime.tv_sec = 0;
- memset(pReplyData, 0x80, pContext->mCaptureSize);
+ memset(pReplyData, 0x80, captureSize);
+ } else {
+ int32_t latencyMs = pContext->mLatency;
+ latencyMs -= deltaMs;
+ if (latencyMs < 0) {
+ latencyMs = 0;
}
+ const uint32_t deltaSmpl =
+ pContext->mConfig.inputCfg.samplingRate * latencyMs / 1000;
+ int32_t capturePoint = pContext->mCaptureIdx - captureSize - deltaSmpl;
+
+ if (capturePoint < 0) {
+ uint32_t size = -capturePoint;
+ if (size > captureSize) {
+ size = captureSize;
+ }
+ memcpy(pReplyData,
+ pContext->mCaptureBuf + CAPTURE_BUF_SIZE + capturePoint,
+ size);
+ pReplyData = (char *)pReplyData + size;
+ captureSize -= size;
+ capturePoint = 0;
+ }
+ memcpy(pReplyData,
+ pContext->mCaptureBuf + capturePoint,
+ captureSize);
}
+
pContext->mLastCaptureIdx = pContext->mCaptureIdx;
} else {
- memset(pReplyData, 0x80, pContext->mCaptureSize);
+ memset(pReplyData, 0x80, captureSize);
}
- break;
+ } break;
case VISUALIZER_CMD_MEASURE: {
uint16_t peakU16 = 0;
@@ -603,7 +605,7 @@ int Visualizer_command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize,
// measurements aren't relevant anymore and shouldn't bias the new one)
const int32_t delayMs = Visualizer_getDeltaTimeMsFromUpdatedTime(pContext);
if (delayMs > DISCARD_MEASUREMENTS_TIME_MS) {
- ALOGV("Discarding measurements, last measurement is %dms old", delayMs);
+ ALOGV("Discarding measurements, last measurement is %" PRId32 "ms old", delayMs);
for (uint32_t i=0 ; i<pContext->mMeasurementWindowSizeInBuffers ; i++) {
pContext->mPastMeasurements[i].mIsValid = false;
pContext->mPastMeasurements[i].mPeakU16 = 0;
@@ -637,14 +639,14 @@ int Visualizer_command(effect_handle_t self, uint32_t cmdCode, uint32_t cmdSize,
} else {
pIntReplyData[MEASUREMENT_IDX_PEAK] = (int32_t) (2000 * log10(peakU16 / 32767.0f));
}
- ALOGV("VISUALIZER_CMD_MEASURE peak=%d (%dmB), rms=%.1f (%dmB)",
+ ALOGV("VISUALIZER_CMD_MEASURE peak=%" PRIu16 " (%" PRId32 "mB), rms=%.1f (%" PRId32 "mB)",
peakU16, pIntReplyData[MEASUREMENT_IDX_PEAK],
rms, pIntReplyData[MEASUREMENT_IDX_RMS]);
}
break;
default:
- ALOGW("Visualizer_command invalid command %d",cmdCode);
+ ALOGW("Visualizer_command invalid command %" PRIu32, cmdCode);
return -EINVAL;
}
diff --git a/media/libmedia/Android.mk b/media/libmedia/Android.mk
index 56e7787..1e322f9 100644
--- a/media/libmedia/Android.mk
+++ b/media/libmedia/Android.mk
@@ -76,7 +76,7 @@ LOCAL_MODULE:= libmedia
LOCAL_C_INCLUDES := \
$(call include-path-for, graphics corecg) \
$(TOP)/frameworks/native/include/media/openmax \
- external/icu4c/common \
+ external/icu/icu4c/source/common \
$(call include-path-for, audio-effects) \
$(call include-path-for, audio-utils)
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index 666fafa..ccbc5a3 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -545,13 +545,13 @@ status_t AudioRecord::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
}
const struct timespec *requested;
+ struct timespec timeout;
if (waitCount == -1) {
requested = &ClientProxy::kForever;
} else if (waitCount == 0) {
requested = &ClientProxy::kNonBlocking;
} else if (waitCount > 0) {
long long ms = WAIT_PERIOD_MS * (long long) waitCount;
- struct timespec timeout;
timeout.tv_sec = ms / 1000;
timeout.tv_nsec = (int) (ms % 1000) * 1000000;
requested = &timeout;
diff --git a/media/libmedia/AudioSystem.cpp b/media/libmedia/AudioSystem.cpp
index 8033c2c..cc5b810 100644
--- a/media/libmedia/AudioSystem.cpp
+++ b/media/libmedia/AudioSystem.cpp
@@ -370,8 +370,8 @@ status_t AudioSystem::setVoiceVolume(float value)
return af->setVoiceVolume(value);
}
-status_t AudioSystem::getRenderPosition(audio_io_handle_t output, size_t *halFrames,
- size_t *dspFrames, audio_stream_type_t stream)
+status_t AudioSystem::getRenderPosition(audio_io_handle_t output, uint32_t *halFrames,
+ uint32_t *dspFrames, audio_stream_type_t stream)
{
const sp<IAudioFlinger>& af = AudioSystem::get_audio_flinger();
if (af == 0) return PERMISSION_DENIED;
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index b8a89a0..3f3a88c 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -85,7 +85,8 @@ AudioTrack::AudioTrack()
: mStatus(NO_INIT),
mIsTimed(false),
mPreviousPriority(ANDROID_PRIORITY_NORMAL),
- mPreviousSchedulingGroup(SP_DEFAULT)
+ mPreviousSchedulingGroup(SP_DEFAULT),
+ mPausedPosition(0)
{
}
@@ -106,7 +107,8 @@ AudioTrack::AudioTrack(
: mStatus(NO_INIT),
mIsTimed(false),
mPreviousPriority(ANDROID_PRIORITY_NORMAL),
- mPreviousSchedulingGroup(SP_DEFAULT)
+ mPreviousSchedulingGroup(SP_DEFAULT),
+ mPausedPosition(0)
{
mStatus = set(streamType, sampleRate, format, channelMask,
frameCount, flags, cbf, user, notificationFrames,
@@ -131,7 +133,8 @@ AudioTrack::AudioTrack(
: mStatus(NO_INIT),
mIsTimed(false),
mPreviousPriority(ANDROID_PRIORITY_NORMAL),
- mPreviousSchedulingGroup(SP_DEFAULT)
+ mPreviousSchedulingGroup(SP_DEFAULT),
+ mPausedPosition(0)
{
mStatus = set(streamType, sampleRate, format, channelMask,
0 /*frameCount*/, flags, cbf, user, notificationFrames,
@@ -529,6 +532,16 @@ void AudioTrack::pause()
}
mProxy->interrupt();
mAudioTrack->pause();
+
+ if (isOffloaded()) {
+ if (mOutput != 0) {
+ uint32_t halFrames;
+ // OffloadThread sends HAL pause in its threadLoop.. time saved
+ // here can be slightly off
+ AudioSystem::getRenderPosition(mOutput, &halFrames, &mPausedPosition);
+ ALOGV("AudioTrack::pause for offload, cache current position %u", mPausedPosition);
+ }
+ }
}
status_t AudioTrack::setVolume(float left, float right)
@@ -603,6 +616,19 @@ uint32_t AudioTrack::getSampleRate() const
}
AutoMutex lock(mLock);
+
+ // sample rate can be updated during playback by the offloaded decoder so we need to
+ // query the HAL and update if needed.
+// FIXME use Proxy return channel to update the rate from server and avoid polling here
+ if (isOffloaded()) {
+ if (mOutput != 0) {
+ uint32_t sampleRate = 0;
+ status_t status = AudioSystem::getSamplingRate(mOutput, mStreamType, &sampleRate);
+ if (status == NO_ERROR) {
+ mSampleRate = sampleRate;
+ }
+ }
+ }
return mSampleRate;
}
@@ -734,6 +760,12 @@ status_t AudioTrack::getPosition(uint32_t *position) const
if (isOffloaded()) {
uint32_t dspFrames = 0;
+ if ((mState == STATE_PAUSED) || (mState == STATE_PAUSED_STOPPING)) {
+ ALOGV("getPosition called in paused state, return cached position %u", mPausedPosition);
+ *position = mPausedPosition;
+ return NO_ERROR;
+ }
+
if (mOutput != 0) {
uint32_t halFrames;
AudioSystem::getRenderPosition(mOutput, &halFrames, &dspFrames);
@@ -747,7 +779,7 @@ status_t AudioTrack::getPosition(uint32_t *position) const
return NO_ERROR;
}
-status_t AudioTrack::getBufferPosition(size_t *position)
+status_t AudioTrack::getBufferPosition(uint32_t *position)
{
if (mSharedBuffer == 0 || mIsTimed) {
return INVALID_OPERATION;
@@ -865,8 +897,15 @@ status_t AudioTrack::createTrack_l(
}
ALOGV("createTrack_l() output %d afLatency %d", output, afLatency);
+ if ((flags & AUDIO_OUTPUT_FLAG_FAST) && sampleRate != afSampleRate) {
+ ALOGW("AUDIO_OUTPUT_FLAG_FAST denied by client due to mismatching sample rate (%d vs %d)",
+ sampleRate, afSampleRate);
+ flags = (audio_output_flags_t) (flags & ~AUDIO_OUTPUT_FLAG_FAST);
+ }
+
// The client's AudioTrack buffer is divided into n parts for purpose of wakeup by server, where
- // n = 1 fast track; nBuffering is ignored
+ // n = 1 fast track with single buffering; nBuffering is ignored
+ // n = 2 fast track with double buffering
// n = 2 normal track, no sample rate conversion
// n = 3 normal track, with sample rate conversion
// (pessimistic; some non-1:1 conversion ratios don't actually need triple-buffering)
@@ -895,7 +934,7 @@ status_t AudioTrack::createTrack_l(
// More than 2 channels does not require stronger alignment than stereo
alignment <<= 1;
}
- if (((size_t)sharedBuffer->pointer() & (alignment - 1)) != 0) {
+ if (((uintptr_t)sharedBuffer->pointer() & (alignment - 1)) != 0) {
ALOGE("Invalid buffer alignment: address %p, channel count %u",
sharedBuffer->pointer(), mChannelCount);
return BAD_VALUE;
@@ -1006,9 +1045,11 @@ status_t AudioTrack::createTrack_l(
ALOGV("AUDIO_OUTPUT_FLAG_FAST successful; frameCount %u", frameCount);
mAwaitBoost = true;
if (sharedBuffer == 0) {
- // double-buffering is not required for fast tracks, due to tighter scheduling
- if (mNotificationFramesAct == 0 || mNotificationFramesAct > frameCount) {
- mNotificationFramesAct = frameCount;
+ // Theoretically double-buffering is not required for fast tracks,
+ // due to tighter scheduling. But in practice, to accommodate kernels with
+ // scheduling jitter, and apps with computation jitter, we use double-buffering.
+ if (mNotificationFramesAct == 0 || mNotificationFramesAct > frameCount/nBuffering) {
+ mNotificationFramesAct = frameCount/nBuffering;
}
}
} else {
@@ -1091,13 +1132,13 @@ status_t AudioTrack::obtainBuffer(Buffer* audioBuffer, int32_t waitCount)
}
const struct timespec *requested;
+ struct timespec timeout;
if (waitCount == -1) {
requested = &ClientProxy::kForever;
} else if (waitCount == 0) {
requested = &ClientProxy::kNonBlocking;
} else if (waitCount > 0) {
long long ms = WAIT_PERIOD_MS * (long long) waitCount;
- struct timespec timeout;
timeout.tv_sec = ms / 1000;
timeout.tv_nsec = (int) (ms % 1000) * 1000000;
requested = &timeout;
@@ -1222,7 +1263,7 @@ ssize_t AudioTrack::write(const void* buffer, size_t userSize)
if (ssize_t(userSize) < 0 || (buffer == NULL && userSize != 0)) {
// Sanity-check: user is most-likely passing an error code, and it would
// make the return value ambiguous (actualSize vs error).
- ALOGE("AudioTrack::write(buffer=%p, size=%u (%d)", buffer, userSize, userSize);
+ ALOGE("AudioTrack::write(buffer=%p, size=%zu (%zd)", buffer, userSize, userSize);
return BAD_VALUE;
}
@@ -1429,6 +1470,7 @@ nsecs_t AudioTrack::processAudioBuffer(const sp<AudioTrackThread>& thread)
}
size_t misalignment = mProxy->getMisalignment();
uint32_t sequence = mSequence;
+ sp<AudioTrackClientProxy> proxy = mProxy;
// These fields don't need to be cached, because they are assigned only by set():
// mTransfer, mCbf, mUserData, mFormat, mFrameSize, mFrameSizeAF, mFlags
@@ -1437,35 +1479,32 @@ nsecs_t AudioTrack::processAudioBuffer(const sp<AudioTrackThread>& thread)
mLock.unlock();
if (waitStreamEnd) {
- AutoMutex lock(mLock);
-
- sp<AudioTrackClientProxy> proxy = mProxy;
- sp<IMemory> iMem = mCblkMemory;
-
struct timespec timeout;
timeout.tv_sec = WAIT_STREAM_END_TIMEOUT_SEC;
timeout.tv_nsec = 0;
- mLock.unlock();
- status_t status = mProxy->waitStreamEndDone(&timeout);
- mLock.lock();
+ status_t status = proxy->waitStreamEndDone(&timeout);
switch (status) {
case NO_ERROR:
case DEAD_OBJECT:
case TIMED_OUT:
- mLock.unlock();
mCbf(EVENT_STREAM_END, mUserData, NULL);
- mLock.lock();
- if (mState == STATE_STOPPING) {
- mState = STATE_STOPPED;
- if (status != DEAD_OBJECT) {
- return NS_INACTIVE;
+ {
+ AutoMutex lock(mLock);
+ // The previously assigned value of waitStreamEnd is no longer valid,
+ // since the mutex has been unlocked and either the callback handler
+ // or another thread could have re-started the AudioTrack during that time.
+ waitStreamEnd = mState == STATE_STOPPING;
+ if (waitStreamEnd) {
+ mState = STATE_STOPPED;
}
}
- return 0;
- default:
- return 0;
+ if (waitStreamEnd && status != DEAD_OBJECT) {
+ return NS_INACTIVE;
+ }
+ break;
}
+ return 0;
}
// perform callbacks while unlocked
@@ -1675,7 +1714,6 @@ status_t AudioTrack::restoreTrack_l(const char *from)
// take the frames that will be lost by track recreation into account in saved position
size_t position = mProxy->getPosition() + mProxy->getFramesFilled();
- mNewPosition = position + mUpdatePeriod;
size_t bufferPosition = mStaticProxy != NULL ? mStaticProxy->getBufferPosition() : 0;
result = createTrack_l(mStreamType,
mSampleRate,
@@ -1766,7 +1804,7 @@ status_t AudioTrack::dump(int fd, const Vector<String16>& args) const
snprintf(buffer, 255, " stream type(%d), left - right volume(%f, %f)\n", mStreamType,
mVolume[0], mVolume[1]);
result.append(buffer);
- snprintf(buffer, 255, " format(%d), channel count(%d), frame count(%d)\n", mFormat,
+ snprintf(buffer, 255, " format(%d), channel count(%d), frame count(%zu)\n", mFormat,
mChannelCount, mFrameCount);
result.append(buffer);
snprintf(buffer, 255, " sample rate(%u), status(%d)\n", mSampleRate, mStatus);
diff --git a/media/libmedia/AudioTrackShared.cpp b/media/libmedia/AudioTrackShared.cpp
index caa7900..d5b0b07 100644
--- a/media/libmedia/AudioTrackShared.cpp
+++ b/media/libmedia/AudioTrackShared.cpp
@@ -19,9 +19,9 @@
#include <private/media/AudioTrackShared.h>
#include <utils/Log.h>
-extern "C" {
-#include "../private/bionic_futex.h"
-}
+
+#include <linux/futex.h>
+#include <sys/syscall.h>
namespace android {
@@ -206,12 +206,12 @@ status_t ClientProxy::obtainBuffer(Buffer* buffer, const struct timespec *reques
}
int32_t old = android_atomic_and(~CBLK_FUTEX_WAKE, &cblk->mFutex);
if (!(old & CBLK_FUTEX_WAKE)) {
- int rc;
if (measure && !beforeIsValid) {
clock_gettime(CLOCK_MONOTONIC, &before);
beforeIsValid = true;
}
- int ret = __futex_syscall4(&cblk->mFutex,
+ errno = 0;
+ (void) syscall(__NR_futex, &cblk->mFutex,
mClientInServer ? FUTEX_WAIT_PRIVATE : FUTEX_WAIT, old & ~CBLK_FUTEX_WAKE, ts);
// update total elapsed time spent waiting
if (measure) {
@@ -230,16 +230,16 @@ status_t ClientProxy::obtainBuffer(Buffer* buffer, const struct timespec *reques
before = after;
beforeIsValid = true;
}
- switch (ret) {
- case 0: // normal wakeup by server, or by binderDied()
- case -EWOULDBLOCK: // benign race condition with server
- case -EINTR: // wait was interrupted by signal or other spurious wakeup
- case -ETIMEDOUT: // time-out expired
+ switch (errno) {
+ case 0: // normal wakeup by server, or by binderDied()
+ case EWOULDBLOCK: // benign race condition with server
+ case EINTR: // wait was interrupted by signal or other spurious wakeup
+ case ETIMEDOUT: // time-out expired
// FIXME these error/non-0 status are being dropped
break;
default:
- ALOGE("%s unexpected error %d", __func__, ret);
- status = -ret;
+ status = errno;
+ ALOGE("%s unexpected error %s", __func__, strerror(status));
goto end;
}
}
@@ -295,7 +295,7 @@ void ClientProxy::binderDied()
audio_track_cblk_t* cblk = mCblk;
if (!(android_atomic_or(CBLK_INVALID, &cblk->mFlags) & CBLK_INVALID)) {
// it seems that a FUTEX_WAKE_PRIVATE will not wake a FUTEX_WAIT, even within same process
- (void) __futex_syscall3(&cblk->mFutex, mClientInServer ? FUTEX_WAKE_PRIVATE : FUTEX_WAKE,
+ (void) syscall(__NR_futex, &cblk->mFutex, mClientInServer ? FUTEX_WAKE_PRIVATE : FUTEX_WAKE,
1);
}
}
@@ -304,7 +304,7 @@ void ClientProxy::interrupt()
{
audio_track_cblk_t* cblk = mCblk;
if (!(android_atomic_or(CBLK_INTERRUPT, &cblk->mFlags) & CBLK_INTERRUPT)) {
- (void) __futex_syscall3(&cblk->mFutex, mClientInServer ? FUTEX_WAKE_PRIVATE : FUTEX_WAKE,
+ (void) syscall(__NR_futex, &cblk->mFutex, mClientInServer ? FUTEX_WAKE_PRIVATE : FUTEX_WAKE,
1);
}
}
@@ -435,18 +435,18 @@ status_t AudioTrackClientProxy::waitStreamEndDone(const struct timespec *request
}
int32_t old = android_atomic_and(~CBLK_FUTEX_WAKE, &cblk->mFutex);
if (!(old & CBLK_FUTEX_WAKE)) {
- int rc;
- int ret = __futex_syscall4(&cblk->mFutex,
+ errno = 0;
+ (void) syscall(__NR_futex, &cblk->mFutex,
mClientInServer ? FUTEX_WAIT_PRIVATE : FUTEX_WAIT, old & ~CBLK_FUTEX_WAKE, ts);
- switch (ret) {
- case 0: // normal wakeup by server, or by binderDied()
- case -EWOULDBLOCK: // benign race condition with server
- case -EINTR: // wait was interrupted by signal or other spurious wakeup
- case -ETIMEDOUT: // time-out expired
+ switch (errno) {
+ case 0: // normal wakeup by server, or by binderDied()
+ case EWOULDBLOCK: // benign race condition with server
+ case EINTR: // wait was interrupted by signal or other spurious wakeup
+ case ETIMEDOUT: // time-out expired
break;
default:
- ALOGE("%s unexpected error %d", __func__, ret);
- status = -ret;
+ status = errno;
+ ALOGE("%s unexpected error %s", __func__, strerror(status));
goto end;
}
}
@@ -475,9 +475,14 @@ void StaticAudioTrackClientProxy::flush()
void StaticAudioTrackClientProxy::setLoop(size_t loopStart, size_t loopEnd, int loopCount)
{
+ // This can only happen on a 64-bit client
+ if (loopStart > UINT32_MAX || loopEnd > UINT32_MAX) {
+ // FIXME Should return an error status
+ return;
+ }
StaticAudioTrackState newState;
- newState.mLoopStart = loopStart;
- newState.mLoopEnd = loopEnd;
+ newState.mLoopStart = (uint32_t) loopStart;
+ newState.mLoopEnd = (uint32_t) loopEnd;
newState.mLoopCount = loopCount;
mBufferPosition = loopStart;
(void) mMutator.push(newState);
@@ -487,7 +492,7 @@ size_t StaticAudioTrackClientProxy::getBufferPosition()
{
size_t bufferPosition;
if (mMutator.ack()) {
- bufferPosition = mCblk->u.mStatic.mBufferPosition;
+ bufferPosition = (size_t) mCblk->u.mStatic.mBufferPosition;
if (bufferPosition > mFrameCount) {
bufferPosition = mFrameCount;
}
@@ -530,7 +535,7 @@ status_t ServerProxy::obtainBuffer(Buffer* buffer, bool ackFlush)
if (front != rear) {
int32_t old = android_atomic_or(CBLK_FUTEX_WAKE, &cblk->mFutex);
if (!(old & CBLK_FUTEX_WAKE)) {
- (void) __futex_syscall3(&cblk->mFutex,
+ (void) syscall(__NR_futex, &cblk->mFutex,
mClientInServer ? FUTEX_WAKE_PRIVATE : FUTEX_WAKE, 1);
}
}
@@ -622,7 +627,7 @@ void ServerProxy::releaseBuffer(Buffer* buffer)
if (half == 0) {
half = 1;
}
- size_t minimum = cblk->mMinimum;
+ size_t minimum = (size_t) cblk->mMinimum;
if (minimum == 0) {
minimum = mIsOut ? half : 1;
} else if (minimum > half) {
@@ -633,7 +638,7 @@ void ServerProxy::releaseBuffer(Buffer* buffer)
ALOGV("mAvailToClient=%u stepCount=%u minimum=%u", mAvailToClient, stepCount, minimum);
int32_t old = android_atomic_or(CBLK_FUTEX_WAKE, &cblk->mFutex);
if (!(old & CBLK_FUTEX_WAKE)) {
- (void) __futex_syscall3(&cblk->mFutex,
+ (void) syscall(__NR_futex, &cblk->mFutex,
mClientInServer ? FUTEX_WAKE_PRIVATE : FUTEX_WAKE, 1);
}
}
@@ -677,7 +682,7 @@ bool AudioTrackServerProxy::setStreamEndDone() {
bool old =
(android_atomic_or(CBLK_STREAM_END_DONE, &mCblk->mFlags) & CBLK_STREAM_END_DONE) != 0;
if (!old) {
- (void) __futex_syscall3(&mCblk->mFutex, mClientInServer ? FUTEX_WAKE_PRIVATE : FUTEX_WAKE,
+ (void) syscall(__NR_futex, &mCblk->mFutex, mClientInServer ? FUTEX_WAKE_PRIVATE : FUTEX_WAKE,
1);
}
return old;
@@ -760,7 +765,8 @@ ssize_t StaticAudioTrackServerProxy::pollPosition()
mIsShutdown = true;
return (ssize_t) NO_INIT;
}
- mCblk->u.mStatic.mBufferPosition = position;
+ // This may overflow, but client is not supposed to rely on it
+ mCblk->u.mStatic.mBufferPosition = (uint32_t) position;
}
return (ssize_t) position;
}
@@ -836,7 +842,8 @@ void StaticAudioTrackServerProxy::releaseBuffer(Buffer* buffer)
mPosition = newPosition;
cblk->mServer += stepCount;
- cblk->u.mStatic.mBufferPosition = newPosition;
+ // This may overflow, but client is not supposed to rely on it
+ cblk->u.mStatic.mBufferPosition = (uint32_t) newPosition;
if (setFlags != 0) {
(void) android_atomic_or(setFlags, &cblk->mFlags);
// this would be a good place to wake a futex
diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp
index acfaea0..e02107f 100644
--- a/media/libmedia/IAudioFlinger.cpp
+++ b/media/libmedia/IAudioFlinger.cpp
@@ -106,7 +106,7 @@ public:
data.writeInt32(sampleRate);
data.writeInt32(format);
data.writeInt32(channelMask);
- data.writeInt32(frameCount);
+ data.writeInt64(frameCount);
track_flags_t lFlags = flags != NULL ? *flags : (track_flags_t) TRACK_DEFAULT;
data.writeInt32(lFlags);
if (sharedBuffer != 0) {
@@ -163,7 +163,7 @@ public:
data.writeInt32(sampleRate);
data.writeInt32(format);
data.writeInt32(channelMask);
- data.writeInt32(frameCount);
+ data.writeInt64(frameCount);
track_flags_t lFlags = flags != NULL ? *flags : (track_flags_t) TRACK_DEFAULT;
data.writeInt32(lFlags);
data.writeInt32((int32_t) tid);
@@ -228,7 +228,7 @@ public:
data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
data.writeInt32((int32_t) output);
remote()->transact(FRAME_COUNT, data, &reply);
- return reply.readInt32();
+ return reply.readInt64();
}
virtual uint32_t latency(audio_io_handle_t output) const
@@ -378,7 +378,7 @@ public:
data.writeInt32(format);
data.writeInt32(channelMask);
remote()->transact(GET_INPUTBUFFERSIZE, data, &reply);
- return reply.readInt32();
+ return reply.readInt64();
}
virtual audio_io_handle_t openOutput(audio_module_handle_t module,
@@ -525,7 +525,7 @@ public:
return reply.readInt32();
}
- virtual status_t getRenderPosition(size_t *halFrames, size_t *dspFrames,
+ virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames,
audio_io_handle_t output) const
{
Parcel data, reply;
@@ -546,7 +546,7 @@ public:
return status;
}
- virtual size_t getInputFramesLost(audio_io_handle_t ioHandle) const
+ virtual uint32_t getInputFramesLost(audio_io_handle_t ioHandle) const
{
Parcel data, reply;
data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
@@ -726,7 +726,7 @@ public:
Parcel data, reply;
data.writeInterfaceToken(IAudioFlinger::getInterfaceDescriptor());
remote()->transact(GET_PRIMARY_OUTPUT_FRAME_COUNT, data, &reply);
- return reply.readInt32();
+ return reply.readInt64();
}
virtual status_t setLowRamDevice(bool isLowRamDevice)
@@ -754,7 +754,7 @@ status_t BnAudioFlinger::onTransact(
uint32_t sampleRate = data.readInt32();
audio_format_t format = (audio_format_t) data.readInt32();
audio_channel_mask_t channelMask = data.readInt32();
- size_t frameCount = data.readInt32();
+ size_t frameCount = data.readInt64();
track_flags_t flags = (track_flags_t) data.readInt32();
bool haveSharedBuffer = data.readInt32() != 0;
sp<IMemory> buffer;
@@ -791,7 +791,7 @@ status_t BnAudioFlinger::onTransact(
uint32_t sampleRate = data.readInt32();
audio_format_t format = (audio_format_t) data.readInt32();
audio_channel_mask_t channelMask = data.readInt32();
- size_t frameCount = data.readInt32();
+ size_t frameCount = data.readInt64();
track_flags_t flags = (track_flags_t) data.readInt32();
pid_t tid = (pid_t) data.readInt32();
int sessionId = data.readInt32();
@@ -817,7 +817,7 @@ status_t BnAudioFlinger::onTransact(
} break;
case FRAME_COUNT: {
CHECK_INTERFACE(IAudioFlinger, data, reply);
- reply->writeInt32( frameCount((audio_io_handle_t) data.readInt32()) );
+ reply->writeInt64( frameCount((audio_io_handle_t) data.readInt32()) );
return NO_ERROR;
} break;
case LATENCY: {
@@ -916,7 +916,7 @@ status_t BnAudioFlinger::onTransact(
uint32_t sampleRate = data.readInt32();
audio_format_t format = (audio_format_t) data.readInt32();
audio_channel_mask_t channelMask = data.readInt32();
- reply->writeInt32( getInputBufferSize(sampleRate, format, channelMask) );
+ reply->writeInt64( getInputBufferSize(sampleRate, format, channelMask) );
return NO_ERROR;
} break;
case OPEN_OUTPUT: {
@@ -1013,8 +1013,8 @@ status_t BnAudioFlinger::onTransact(
case GET_RENDER_POSITION: {
CHECK_INTERFACE(IAudioFlinger, data, reply);
audio_io_handle_t output = (audio_io_handle_t) data.readInt32();
- size_t halFrames;
- size_t dspFrames;
+ uint32_t halFrames;
+ uint32_t dspFrames;
status_t status = getRenderPosition(&halFrames, &dspFrames, output);
reply->writeInt32(status);
if (status == NO_ERROR) {
@@ -1119,7 +1119,7 @@ status_t BnAudioFlinger::onTransact(
} break;
case GET_PRIMARY_OUTPUT_FRAME_COUNT: {
CHECK_INTERFACE(IAudioFlinger, data, reply);
- reply->writeInt32(getPrimaryOutputFrameCount());
+ reply->writeInt64(getPrimaryOutputFrameCount());
return NO_ERROR;
} break;
case SET_LOW_RAM_DEVICE: {
diff --git a/media/libmedia/IAudioFlingerClient.cpp b/media/libmedia/IAudioFlingerClient.cpp
index 3c0d4cf..1c299f7 100644
--- a/media/libmedia/IAudioFlingerClient.cpp
+++ b/media/libmedia/IAudioFlingerClient.cpp
@@ -55,7 +55,7 @@ public:
data.writeInt32(desc->samplingRate);
data.writeInt32(desc->format);
data.writeInt32(desc->channelMask);
- data.writeInt32(desc->frameCount);
+ data.writeInt64(desc->frameCount);
data.writeInt32(desc->latency);
}
remote()->transact(IO_CONFIG_CHANGED, data, &reply, IBinder::FLAG_ONEWAY);
@@ -85,7 +85,7 @@ status_t BnAudioFlingerClient::onTransact(
desc.samplingRate = data.readInt32();
desc.format = (audio_format_t) data.readInt32();
desc.channelMask = (audio_channel_mask_t) data.readInt32();
- desc.frameCount = data.readInt32();
+ desc.frameCount = data.readInt64();
desc.latency = data.readInt32();
param2 = &desc;
}
diff --git a/media/libmedia/IAudioTrack.cpp b/media/libmedia/IAudioTrack.cpp
index 3cd9cfd..e9df704 100644
--- a/media/libmedia/IAudioTrack.cpp
+++ b/media/libmedia/IAudioTrack.cpp
@@ -115,7 +115,7 @@ public:
virtual status_t allocateTimedBuffer(size_t size, sp<IMemory>* buffer) {
Parcel data, reply;
data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
- data.writeInt32(size);
+ data.writeInt64(size);
status_t status = remote()->transact(ALLOCATE_TIMED_BUFFER,
data, &reply);
if (status == NO_ERROR) {
@@ -232,7 +232,7 @@ status_t BnAudioTrack::onTransact(
case ALLOCATE_TIMED_BUFFER: {
CHECK_INTERFACE(IAudioTrack, data, reply);
sp<IMemory> buffer;
- status_t status = allocateTimedBuffer(data.readInt32(), &buffer);
+ status_t status = allocateTimedBuffer(data.readInt64(), &buffer);
reply->writeInt32(status);
if (status == NO_ERROR) {
reply->writeStrongBinder(buffer->asBinder());
diff --git a/media/libmedia/ICrypto.cpp b/media/libmedia/ICrypto.cpp
index 98b183a..0d5f990 100644
--- a/media/libmedia/ICrypto.cpp
+++ b/media/libmedia/ICrypto.cpp
@@ -131,7 +131,7 @@ struct BpCrypto : public BpInterface<ICrypto> {
data.write(subSamples, sizeof(CryptoPlugin::SubSample) * numSubSamples);
if (secure) {
- data.writeIntPtr((intptr_t)dstPtr);
+ data.writeInt64(static_cast<uint64_t>(reinterpret_cast<uintptr_t>(dstPtr)));
}
remote()->transact(DECRYPT, data, &reply);
@@ -249,7 +249,7 @@ status_t BnCrypto::onTransact(
void *dstPtr;
if (secure) {
- dstPtr = (void *)data.readIntPtr();
+ dstPtr = reinterpret_cast<void *>(static_cast<uintptr_t>(data.readInt64()));
} else {
dstPtr = malloc(totalSize);
}
diff --git a/media/libmedia/IMediaLogService.cpp b/media/libmedia/IMediaLogService.cpp
index 33239a7..8a66c7c 100644
--- a/media/libmedia/IMediaLogService.cpp
+++ b/media/libmedia/IMediaLogService.cpp
@@ -43,7 +43,7 @@ public:
Parcel data, reply;
data.writeInterfaceToken(IMediaLogService::getInterfaceDescriptor());
data.writeStrongBinder(shared->asBinder());
- data.writeInt32((int32_t) size);
+ data.writeInt64((int64_t) size);
data.writeCString(name);
status_t status = remote()->transact(REGISTER_WRITER, data, &reply);
// FIXME ignores status
@@ -71,7 +71,7 @@ status_t BnMediaLogService::onTransact(
case REGISTER_WRITER: {
CHECK_INTERFACE(IMediaLogService, data, reply);
sp<IMemory> shared = interface_cast<IMemory>(data.readStrongBinder());
- size_t size = (size_t) data.readInt32();
+ size_t size = (size_t) data.readInt64();
const char *name = data.readCString();
registerWriter(shared, size, name);
return NO_ERROR;
diff --git a/media/libmedia/IMediaMetadataRetriever.cpp b/media/libmedia/IMediaMetadataRetriever.cpp
index bb066a0..a91ad49 100644
--- a/media/libmedia/IMediaMetadataRetriever.cpp
+++ b/media/libmedia/IMediaMetadataRetriever.cpp
@@ -94,7 +94,7 @@ public:
data.writeInt32(0);
} else {
// serialize the headers
- data.writeInt32(headers->size());
+ data.writeInt64(headers->size());
for (size_t i = 0; i < headers->size(); ++i) {
data.writeString8(headers->keyAt(i));
data.writeString8(headers->valueAt(i));
@@ -198,8 +198,8 @@ status_t BnMediaMetadataRetriever::onTransact(
const char* srcUrl = data.readCString();
KeyedVector<String8, String8> headers;
- int32_t numHeaders = data.readInt32();
- for (int i = 0; i < numHeaders; ++i) {
+ size_t numHeaders = (size_t) data.readInt64();
+ for (size_t i = 0; i < numHeaders; ++i) {
String8 key = data.readString8();
String8 value = data.readString8();
headers.add(key, value);
diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp
index 71ce320..5df232f 100644
--- a/media/libmedia/IOMX.cpp
+++ b/media/libmedia/IOMX.cpp
@@ -65,7 +65,7 @@ public:
virtual bool livesLocally(node_id node, pid_t pid) {
Parcel data, reply;
data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
- data.writeIntPtr((intptr_t)node);
+ data.writeInt32((int32_t)node);
data.writeInt32(pid);
remote()->transact(LIVES_LOCALLY, data, &reply);
@@ -104,7 +104,7 @@ public:
status_t err = reply.readInt32();
if (err == OK) {
- *node = (void*)reply.readIntPtr();
+ *node = (node_id)reply.readInt32();
} else {
*node = 0;
}
@@ -115,7 +115,7 @@ public:
virtual status_t freeNode(node_id node) {
Parcel data, reply;
data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
- data.writeIntPtr((intptr_t)node);
+ data.writeInt32((int32_t)node);
remote()->transact(FREE_NODE, data, &reply);
return reply.readInt32();
@@ -125,7 +125,7 @@ public:
node_id node, OMX_COMMANDTYPE cmd, OMX_S32 param) {
Parcel data, reply;
data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
- data.writeIntPtr((intptr_t)node);
+ data.writeInt32((int32_t)node);
data.writeInt32(cmd);
data.writeInt32(param);
remote()->transact(SEND_COMMAND, data, &reply);
@@ -138,9 +138,9 @@ public:
void *params, size_t size) {
Parcel data, reply;
data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
- data.writeIntPtr((intptr_t)node);
+ data.writeInt32((int32_t)node);
data.writeInt32(index);
- data.writeInt32(size);
+ data.writeInt64(size);
data.write(params, size);
remote()->transact(GET_PARAMETER, data, &reply);
@@ -159,9 +159,9 @@ public:
const void *params, size_t size) {
Parcel data, reply;
data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
- data.writeIntPtr((intptr_t)node);
+ data.writeInt32((int32_t)node);
data.writeInt32(index);
- data.writeInt32(size);
+ data.writeInt64(size);
data.write(params, size);
remote()->transact(SET_PARAMETER, data, &reply);
@@ -173,9 +173,9 @@ public:
void *params, size_t size) {
Parcel data, reply;
data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
- data.writeIntPtr((intptr_t)node);
+ data.writeInt32((int32_t)node);
data.writeInt32(index);
- data.writeInt32(size);
+ data.writeInt64(size);
data.write(params, size);
remote()->transact(GET_CONFIG, data, &reply);
@@ -194,9 +194,9 @@ public:
const void *params, size_t size) {
Parcel data, reply;
data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
- data.writeIntPtr((intptr_t)node);
+ data.writeInt32((int32_t)node);
data.writeInt32(index);
- data.writeInt32(size);
+ data.writeInt64(size);
data.write(params, size);
remote()->transact(SET_CONFIG, data, &reply);
@@ -207,7 +207,7 @@ public:
node_id node, OMX_STATETYPE* state) {
Parcel data, reply;
data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
- data.writeIntPtr((intptr_t)node);
+ data.writeInt32((int32_t)node);
remote()->transact(GET_STATE, data, &reply);
*state = static_cast<OMX_STATETYPE>(reply.readInt32());
@@ -218,7 +218,7 @@ public:
node_id node, OMX_U32 port_index, OMX_BOOL enable) {
Parcel data, reply;
data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
- data.writeIntPtr((intptr_t)node);
+ data.writeInt32((int32_t)node);
data.writeInt32(port_index);
data.writeInt32((uint32_t)enable);
remote()->transact(ENABLE_GRAPHIC_BUFFERS, data, &reply);
@@ -231,7 +231,7 @@ public:
node_id node, OMX_U32 port_index, OMX_U32* usage) {
Parcel data, reply;
data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
- data.writeIntPtr((intptr_t)node);
+ data.writeInt32((int32_t)node);
data.writeInt32(port_index);
remote()->transact(GET_GRAPHIC_BUFFER_USAGE, data, &reply);
@@ -245,7 +245,7 @@ public:
buffer_id *buffer) {
Parcel data, reply;
data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
- data.writeIntPtr((intptr_t)node);
+ data.writeInt32((int32_t)node);
data.writeInt32(port_index);
data.writeStrongBinder(params->asBinder());
remote()->transact(USE_BUFFER, data, &reply);
@@ -257,7 +257,7 @@ public:
return err;
}
- *buffer = (void*)reply.readIntPtr();
+ *buffer = (buffer_id)reply.readInt32();
return err;
}
@@ -268,7 +268,7 @@ public:
const sp<GraphicBuffer> &graphicBuffer, buffer_id *buffer) {
Parcel data, reply;
data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
- data.writeIntPtr((intptr_t)node);
+ data.writeInt32((int32_t)node);
data.writeInt32(port_index);
data.write(*graphicBuffer);
remote()->transact(USE_GRAPHIC_BUFFER, data, &reply);
@@ -280,7 +280,7 @@ public:
return err;
}
- *buffer = (void*)reply.readIntPtr();
+ *buffer = (buffer_id)reply.readInt32();
return err;
}
@@ -290,10 +290,10 @@ public:
const sp<GraphicBuffer> &graphicBuffer, buffer_id buffer) {
Parcel data, reply;
data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
- data.writeIntPtr((intptr_t)node);
+ data.writeInt32((int32_t)node);
data.writeInt32(port_index);
data.write(*graphicBuffer);
- data.writeIntPtr((intptr_t)buffer);
+ data.writeInt32((int32_t)buffer);
remote()->transact(UPDATE_GRAPHIC_BUFFER_IN_META, data, &reply);
status_t err = reply.readInt32();
@@ -306,7 +306,7 @@ public:
Parcel data, reply;
status_t err;
data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
- data.writeIntPtr((intptr_t)node);
+ data.writeInt32((int32_t)node);
data.writeInt32(port_index);
err = remote()->transact(CREATE_INPUT_SURFACE, data, &reply);
if (err != OK) {
@@ -329,7 +329,7 @@ public:
Parcel data, reply;
status_t err;
data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
- data.writeIntPtr((intptr_t)node);
+ data.writeInt32((int32_t)node);
err = remote()->transact(SIGNAL_END_OF_INPUT_STREAM, data, &reply);
if (err != OK) {
ALOGW("binder transaction failed: %d", err);
@@ -343,7 +343,7 @@ public:
node_id node, OMX_U32 port_index, OMX_BOOL enable) {
Parcel data, reply;
data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
- data.writeIntPtr((intptr_t)node);
+ data.writeInt32((int32_t)node);
data.writeInt32(port_index);
data.writeInt32((uint32_t)enable);
remote()->transact(STORE_META_DATA_IN_BUFFERS, data, &reply);
@@ -357,7 +357,7 @@ public:
OMX_U32 max_width, OMX_U32 max_height) {
Parcel data, reply;
data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
- data.writeIntPtr((intptr_t)node);
+ data.writeInt32((int32_t)node);
data.writeInt32(port_index);
data.writeInt32((int32_t)enable);
data.writeInt32(max_width);
@@ -373,9 +373,9 @@ public:
buffer_id *buffer, void **buffer_data) {
Parcel data, reply;
data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
- data.writeIntPtr((intptr_t)node);
+ data.writeInt32((int32_t)node);
data.writeInt32(port_index);
- data.writeInt32(size);
+ data.writeInt64(size);
remote()->transact(ALLOC_BUFFER, data, &reply);
status_t err = reply.readInt32();
@@ -385,8 +385,8 @@ public:
return err;
}
- *buffer = (void *)reply.readIntPtr();
- *buffer_data = (void *)reply.readIntPtr();
+ *buffer = (buffer_id)reply.readInt32();
+ *buffer_data = (void *)reply.readInt64();
return err;
}
@@ -396,7 +396,7 @@ public:
buffer_id *buffer) {
Parcel data, reply;
data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
- data.writeIntPtr((intptr_t)node);
+ data.writeInt32((int32_t)node);
data.writeInt32(port_index);
data.writeStrongBinder(params->asBinder());
remote()->transact(ALLOC_BUFFER_WITH_BACKUP, data, &reply);
@@ -408,7 +408,7 @@ public:
return err;
}
- *buffer = (void*)reply.readIntPtr();
+ *buffer = (buffer_id)reply.readInt32();
return err;
}
@@ -417,9 +417,9 @@ public:
node_id node, OMX_U32 port_index, buffer_id buffer) {
Parcel data, reply;
data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
- data.writeIntPtr((intptr_t)node);
+ data.writeInt32((int32_t)node);
data.writeInt32(port_index);
- data.writeIntPtr((intptr_t)buffer);
+ data.writeInt32((int32_t)buffer);
remote()->transact(FREE_BUFFER, data, &reply);
return reply.readInt32();
@@ -428,8 +428,8 @@ public:
virtual status_t fillBuffer(node_id node, buffer_id buffer) {
Parcel data, reply;
data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
- data.writeIntPtr((intptr_t)node);
- data.writeIntPtr((intptr_t)buffer);
+ data.writeInt32((int32_t)node);
+ data.writeInt32((int32_t)buffer);
remote()->transact(FILL_BUFFER, data, &reply);
return reply.readInt32();
@@ -442,8 +442,8 @@ public:
OMX_U32 flags, OMX_TICKS timestamp) {
Parcel data, reply;
data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
- data.writeIntPtr((intptr_t)node);
- data.writeIntPtr((intptr_t)buffer);
+ data.writeInt32((int32_t)node);
+ data.writeInt32((int32_t)buffer);
data.writeInt32(range_offset);
data.writeInt32(range_length);
data.writeInt32(flags);
@@ -459,7 +459,7 @@ public:
OMX_INDEXTYPE *index) {
Parcel data, reply;
data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
- data.writeIntPtr((intptr_t)node);
+ data.writeInt32((int32_t)node);
data.writeCString(parameter_name);
remote()->transact(GET_EXTENSION_INDEX, data, &reply);
@@ -482,9 +482,9 @@ public:
size_t size) {
Parcel data, reply;
data.writeInterfaceToken(IOMX::getInterfaceDescriptor());
- data.writeIntPtr((intptr_t)node);
+ data.writeInt32((int32_t)node);
data.writeInt32(port_index);
- data.writeInt32(size);
+ data.writeInt64(size);
data.write(optionData, size);
data.writeInt32(type);
remote()->transact(SET_INTERNAL_OPTION, data, &reply);
@@ -509,7 +509,7 @@ status_t BnOMX::onTransact(
case LIVES_LOCALLY:
{
CHECK_OMX_INTERFACE(IOMX, data, reply);
- node_id node = (void *)data.readIntPtr();
+ node_id node = (node_id)data.readInt32();
pid_t pid = (pid_t)data.readInt32();
reply->writeInt32(livesLocally(node, pid));
@@ -553,7 +553,7 @@ status_t BnOMX::onTransact(
status_t err = allocateNode(name, observer, &node);
reply->writeInt32(err);
if (err == OK) {
- reply->writeIntPtr((intptr_t)node);
+ reply->writeInt32((int32_t)node);
}
return NO_ERROR;
@@ -563,7 +563,7 @@ status_t BnOMX::onTransact(
{
CHECK_OMX_INTERFACE(IOMX, data, reply);
- node_id node = (void*)data.readIntPtr();
+ node_id node = (node_id)data.readInt32();
reply->writeInt32(freeNode(node));
@@ -574,7 +574,7 @@ status_t BnOMX::onTransact(
{
CHECK_OMX_INTERFACE(IOMX, data, reply);
- node_id node = (void*)data.readIntPtr();
+ node_id node = (node_id)data.readInt32();
OMX_COMMANDTYPE cmd =
static_cast<OMX_COMMANDTYPE>(data.readInt32());
@@ -593,10 +593,10 @@ status_t BnOMX::onTransact(
{
CHECK_OMX_INTERFACE(IOMX, data, reply);
- node_id node = (void*)data.readIntPtr();
+ node_id node = (node_id)data.readInt32();
OMX_INDEXTYPE index = static_cast<OMX_INDEXTYPE>(data.readInt32());
- size_t size = data.readInt32();
+ size_t size = data.readInt64();
void *params = malloc(size);
data.read(params, size);
@@ -644,7 +644,7 @@ status_t BnOMX::onTransact(
{
CHECK_OMX_INTERFACE(IOMX, data, reply);
- node_id node = (void*)data.readIntPtr();
+ node_id node = (node_id)data.readInt32();
OMX_STATETYPE state = OMX_StateInvalid;
status_t err = getState(node, &state);
@@ -658,7 +658,7 @@ status_t BnOMX::onTransact(
{
CHECK_OMX_INTERFACE(IOMX, data, reply);
- node_id node = (void*)data.readIntPtr();
+ node_id node = (node_id)data.readInt32();
OMX_U32 port_index = data.readInt32();
OMX_BOOL enable = (OMX_BOOL)data.readInt32();
@@ -672,7 +672,7 @@ status_t BnOMX::onTransact(
{
CHECK_OMX_INTERFACE(IOMX, data, reply);
- node_id node = (void*)data.readIntPtr();
+ node_id node = (node_id)data.readInt32();
OMX_U32 port_index = data.readInt32();
OMX_U32 usage = 0;
@@ -687,7 +687,7 @@ status_t BnOMX::onTransact(
{
CHECK_OMX_INTERFACE(IOMX, data, reply);
- node_id node = (void*)data.readIntPtr();
+ node_id node = (node_id)data.readInt32();
OMX_U32 port_index = data.readInt32();
sp<IMemory> params =
interface_cast<IMemory>(data.readStrongBinder());
@@ -697,7 +697,7 @@ status_t BnOMX::onTransact(
reply->writeInt32(err);
if (err == OK) {
- reply->writeIntPtr((intptr_t)buffer);
+ reply->writeInt32((int32_t)buffer);
}
return NO_ERROR;
@@ -707,7 +707,7 @@ status_t BnOMX::onTransact(
{
CHECK_OMX_INTERFACE(IOMX, data, reply);
- node_id node = (void*)data.readIntPtr();
+ node_id node = (node_id)data.readInt32();
OMX_U32 port_index = data.readInt32();
sp<GraphicBuffer> graphicBuffer = new GraphicBuffer();
data.read(*graphicBuffer);
@@ -718,7 +718,7 @@ status_t BnOMX::onTransact(
reply->writeInt32(err);
if (err == OK) {
- reply->writeIntPtr((intptr_t)buffer);
+ reply->writeInt32((int32_t)buffer);
}
return NO_ERROR;
@@ -728,11 +728,11 @@ status_t BnOMX::onTransact(
{
CHECK_OMX_INTERFACE(IOMX, data, reply);
- node_id node = (void*)data.readIntPtr();
+ node_id node = (node_id)data.readInt32();
OMX_U32 port_index = data.readInt32();
sp<GraphicBuffer> graphicBuffer = new GraphicBuffer();
data.read(*graphicBuffer);
- buffer_id buffer = (void*)data.readIntPtr();
+ buffer_id buffer = (buffer_id)data.readInt32();
status_t err = updateGraphicBufferInMeta(
node, port_index, graphicBuffer, buffer);
@@ -745,7 +745,7 @@ status_t BnOMX::onTransact(
{
CHECK_OMX_INTERFACE(IOMX, data, reply);
- node_id node = (void*)data.readIntPtr();
+ node_id node = (node_id)data.readInt32();
OMX_U32 port_index = data.readInt32();
sp<IGraphicBufferProducer> bufferProducer;
@@ -765,7 +765,7 @@ status_t BnOMX::onTransact(
{
CHECK_OMX_INTERFACE(IOMX, data, reply);
- node_id node = (void*)data.readIntPtr();
+ node_id node = (node_id)data.readInt32();
status_t err = signalEndOfInputStream(node);
reply->writeInt32(err);
@@ -777,7 +777,7 @@ status_t BnOMX::onTransact(
{
CHECK_OMX_INTERFACE(IOMX, data, reply);
- node_id node = (void*)data.readIntPtr();
+ node_id node = (node_id)data.readInt32();
OMX_U32 port_index = data.readInt32();
OMX_BOOL enable = (OMX_BOOL)data.readInt32();
@@ -791,7 +791,7 @@ status_t BnOMX::onTransact(
{
CHECK_OMX_INTERFACE(IOMX, data, reply);
- node_id node = (void*)data.readIntPtr();
+ node_id node = (node_id)data.readInt32();
OMX_U32 port_index = data.readInt32();
OMX_BOOL enable = (OMX_BOOL)data.readInt32();
OMX_U32 max_width = data.readInt32();
@@ -808,9 +808,9 @@ status_t BnOMX::onTransact(
{
CHECK_OMX_INTERFACE(IOMX, data, reply);
- node_id node = (void*)data.readIntPtr();
+ node_id node = (node_id)data.readInt32();
OMX_U32 port_index = data.readInt32();
- size_t size = data.readInt32();
+ size_t size = data.readInt64();
buffer_id buffer;
void *buffer_data;
@@ -819,8 +819,8 @@ status_t BnOMX::onTransact(
reply->writeInt32(err);
if (err == OK) {
- reply->writeIntPtr((intptr_t)buffer);
- reply->writeIntPtr((intptr_t)buffer_data);
+ reply->writeInt32((int32_t)buffer);
+ reply->writeInt64((uintptr_t)buffer_data);
}
return NO_ERROR;
@@ -830,7 +830,7 @@ status_t BnOMX::onTransact(
{
CHECK_OMX_INTERFACE(IOMX, data, reply);
- node_id node = (void*)data.readIntPtr();
+ node_id node = (node_id)data.readInt32();
OMX_U32 port_index = data.readInt32();
sp<IMemory> params =
interface_cast<IMemory>(data.readStrongBinder());
@@ -842,7 +842,7 @@ status_t BnOMX::onTransact(
reply->writeInt32(err);
if (err == OK) {
- reply->writeIntPtr((intptr_t)buffer);
+ reply->writeInt32((int32_t)buffer);
}
return NO_ERROR;
@@ -852,9 +852,9 @@ status_t BnOMX::onTransact(
{
CHECK_OMX_INTERFACE(IOMX, data, reply);
- node_id node = (void*)data.readIntPtr();
+ node_id node = (node_id)data.readInt32();
OMX_U32 port_index = data.readInt32();
- buffer_id buffer = (void*)data.readIntPtr();
+ buffer_id buffer = (buffer_id)data.readInt32();
reply->writeInt32(freeBuffer(node, port_index, buffer));
return NO_ERROR;
@@ -864,8 +864,8 @@ status_t BnOMX::onTransact(
{
CHECK_OMX_INTERFACE(IOMX, data, reply);
- node_id node = (void*)data.readIntPtr();
- buffer_id buffer = (void*)data.readIntPtr();
+ node_id node = (node_id)data.readInt32();
+ buffer_id buffer = (buffer_id)data.readInt32();
reply->writeInt32(fillBuffer(node, buffer));
return NO_ERROR;
@@ -875,8 +875,8 @@ status_t BnOMX::onTransact(
{
CHECK_OMX_INTERFACE(IOMX, data, reply);
- node_id node = (void*)data.readIntPtr();
- buffer_id buffer = (void*)data.readIntPtr();
+ node_id node = (node_id)data.readInt32();
+ buffer_id buffer = (buffer_id)data.readInt32();
OMX_U32 range_offset = data.readInt32();
OMX_U32 range_length = data.readInt32();
OMX_U32 flags = data.readInt32();
@@ -894,7 +894,7 @@ status_t BnOMX::onTransact(
{
CHECK_OMX_INTERFACE(IOMX, data, reply);
- node_id node = (void*)data.readIntPtr();
+ node_id node = (node_id)data.readInt32();
const char *parameter_name = data.readCString();
OMX_INDEXTYPE index;
@@ -927,6 +927,8 @@ public:
data.writeInterfaceToken(IOMXObserver::getInterfaceDescriptor());
data.write(&msg, sizeof(msg));
+ ALOGV("onMessage writing message %d, size %zu", msg.type, sizeof(msg));
+
remote()->transact(OBSERVER_ON_MSG, data, &reply, IBinder::FLAG_ONEWAY);
}
};
@@ -943,6 +945,8 @@ status_t BnOMXObserver::onTransact(
omx_message msg;
data.read(&msg, sizeof(msg));
+ ALOGV("onTransact reading message %d, size %zu", msg.type, sizeof(msg));
+
// XXX Could use readInplace maybe?
onMessage(msg);
diff --git a/media/libmedia/IStreamSource.cpp b/media/libmedia/IStreamSource.cpp
index 68ffca8..fe2cc61 100644
--- a/media/libmedia/IStreamSource.cpp
+++ b/media/libmedia/IStreamSource.cpp
@@ -62,7 +62,7 @@ struct BpStreamSource : public BpInterface<IStreamSource> {
virtual void setBuffers(const Vector<sp<IMemory> > &buffers) {
Parcel data, reply;
data.writeInterfaceToken(IStreamSource::getInterfaceDescriptor());
- data.writeInt32(static_cast<int32_t>(buffers.size()));
+ data.writeInt64(static_cast<int64_t>(buffers.size()));
for (size_t i = 0; i < buffers.size(); ++i) {
data.writeStrongBinder(buffers.itemAt(i)->asBinder());
}
@@ -72,7 +72,7 @@ struct BpStreamSource : public BpInterface<IStreamSource> {
virtual void onBufferAvailable(size_t index) {
Parcel data, reply;
data.writeInterfaceToken(IStreamSource::getInterfaceDescriptor());
- data.writeInt32(static_cast<int32_t>(index));
+ data.writeInt64(static_cast<int64_t>(index));
remote()->transact(
ON_BUFFER_AVAILABLE, data, &reply, IBinder::FLAG_ONEWAY);
}
@@ -102,7 +102,7 @@ status_t BnStreamSource::onTransact(
case SET_BUFFERS:
{
CHECK_INTERFACE(IStreamSource, data, reply);
- size_t n = static_cast<size_t>(data.readInt32());
+ size_t n = static_cast<size_t>(data.readInt64());
Vector<sp<IMemory> > buffers;
for (size_t i = 0; i < n; ++i) {
sp<IMemory> mem =
@@ -117,7 +117,7 @@ status_t BnStreamSource::onTransact(
case ON_BUFFER_AVAILABLE:
{
CHECK_INTERFACE(IStreamSource, data, reply);
- onBufferAvailable(static_cast<size_t>(data.readInt32()));
+ onBufferAvailable(static_cast<size_t>(data.readInt64()));
break;
}
@@ -145,8 +145,8 @@ struct BpStreamListener : public BpInterface<IStreamListener> {
virtual void queueBuffer(size_t index, size_t size) {
Parcel data, reply;
data.writeInterfaceToken(IStreamListener::getInterfaceDescriptor());
- data.writeInt32(static_cast<int32_t>(index));
- data.writeInt32(static_cast<int32_t>(size));
+ data.writeInt64(static_cast<int64_t>(index));
+ data.writeInt64(static_cast<int64_t>(size));
remote()->transact(QUEUE_BUFFER, data, &reply, IBinder::FLAG_ONEWAY);
}
@@ -177,8 +177,8 @@ status_t BnStreamListener::onTransact(
case QUEUE_BUFFER:
{
CHECK_INTERFACE(IStreamListener, data, reply);
- size_t index = static_cast<size_t>(data.readInt32());
- size_t size = static_cast<size_t>(data.readInt32());
+ size_t index = static_cast<size_t>(data.readInt64());
+ size_t size = static_cast<size_t>(data.readInt64());
queueBuffer(index, size);
break;
diff --git a/media/libmedia/MediaScanner.cpp b/media/libmedia/MediaScanner.cpp
index 28b5aa7..dcbb769 100644
--- a/media/libmedia/MediaScanner.cpp
+++ b/media/libmedia/MediaScanner.cpp
@@ -237,4 +237,24 @@ MediaScanResult MediaScanner::doProcessDirectoryEntry(
return MEDIA_SCAN_RESULT_OK;
}
+MediaAlbumArt *MediaAlbumArt::clone() {
+ size_t byte_size = this->size() + sizeof(MediaAlbumArt);
+ MediaAlbumArt *result = reinterpret_cast<MediaAlbumArt *>(malloc(byte_size));
+ result->mSize = this->size();
+ memcpy(&result->mData[0], &this->mData[0], this->size());
+ return result;
+}
+
+void MediaAlbumArt::init(MediaAlbumArt *instance, int32_t dataSize, const void *data) {
+ instance->mSize = dataSize;
+ memcpy(&instance->mData[0], data, dataSize);
+}
+
+MediaAlbumArt *MediaAlbumArt::fromData(int32_t dataSize, const void* data) {
+ size_t byte_size = sizeof(MediaAlbumArt) + dataSize;
+ MediaAlbumArt *result = reinterpret_cast<MediaAlbumArt *>(malloc(byte_size));
+ init(result, dataSize, data);
+ return result;
+}
+
} // namespace android
diff --git a/media/libmedia/MemoryLeakTrackUtil.cpp b/media/libmedia/MemoryLeakTrackUtil.cpp
index 6a108ae..66f7161 100644
--- a/media/libmedia/MemoryLeakTrackUtil.cpp
+++ b/media/libmedia/MemoryLeakTrackUtil.cpp
@@ -17,6 +17,7 @@
#include <media/MemoryLeakTrackUtil.h>
#include <stdio.h>
+#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
@@ -49,7 +50,7 @@ struct MyString8 {
}
void append(const char *s) {
- strcat(mPtr, s);
+ strncat(mPtr, s, MAX_SIZE - size() - 1);
}
const char *string() const {
@@ -60,6 +61,10 @@ struct MyString8 {
return strlen(mPtr);
}
+ void clear() {
+ *mPtr = '\0';
+ }
+
private:
char *mPtr;
@@ -139,6 +144,9 @@ void dumpMemoryAddresses(int fd)
}
} while (moved);
+ write(fd, result.string(), result.size());
+ result.clear();
+
for (size_t i = 0; i < count; i++) {
AllocEntry *e = &entries[i];
@@ -152,13 +160,14 @@ void dumpMemoryAddresses(int fd)
result.append(buffer);
}
result.append("\n");
+
+ write(fd, result.string(), result.size());
+ result.clear();
}
delete[] entries;
free_malloc_leak_info(info);
}
-
- write(fd, result.string(), result.size());
}
#else
diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp
index 0f6d897..7a6f31d 100644
--- a/media/libmedia/mediaplayer.cpp
+++ b/media/libmedia/mediaplayer.cpp
@@ -654,7 +654,7 @@ status_t MediaPlayer::setRetransmitEndpoint(const char* addrString,
return BAD_VALUE;
}
- memset(&mRetransmitEndpoint, 0, sizeof(&mRetransmitEndpoint));
+ memset(&mRetransmitEndpoint, 0, sizeof(mRetransmitEndpoint));
mRetransmitEndpoint.sin_family = AF_INET;
mRetransmitEndpoint.sin_addr = saddr;
mRetransmitEndpoint.sin_port = htons(port);
diff --git a/media/libmediaplayerservice/Android.mk b/media/libmediaplayerservice/Android.mk
index 8f21632..a645f13 100644
--- a/media/libmediaplayerservice/Android.mk
+++ b/media/libmediaplayerservice/Android.mk
@@ -26,6 +26,7 @@ LOCAL_SRC_FILES:= \
LOCAL_SHARED_LIBRARIES := \
libbinder \
libcamera_client \
+ libcrypto \
libcutils \
liblog \
libdl \
@@ -54,6 +55,8 @@ LOCAL_C_INCLUDES := \
LOCAL_MODULE:= libmediaplayerservice
+LOCAL_32_BIT_ONLY := true
+
include $(BUILD_SHARED_LIBRARY)
include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/media/libmediaplayerservice/MediaPlayerFactory.cpp b/media/libmediaplayerservice/MediaPlayerFactory.cpp
index 90aed39..09e6976 100644
--- a/media/libmediaplayerservice/MediaPlayerFactory.cpp
+++ b/media/libmediaplayerservice/MediaPlayerFactory.cpp
@@ -170,11 +170,11 @@ sp<MediaPlayerBase> MediaPlayerFactory::createPlayer(
class StagefrightPlayerFactory :
public MediaPlayerFactory::IFactory {
public:
- virtual float scoreFactory(const sp<IMediaPlayer>& client,
+ virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/,
int fd,
int64_t offset,
- int64_t length,
- float curScore) {
+ int64_t /*length*/,
+ float /*curScore*/) {
char buf[20];
lseek(fd, offset, SEEK_SET);
read(fd, buf, sizeof(buf));
@@ -197,7 +197,7 @@ class StagefrightPlayerFactory :
class NuPlayerFactory : public MediaPlayerFactory::IFactory {
public:
- virtual float scoreFactory(const sp<IMediaPlayer>& client,
+ virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/,
const char* url,
float curScore) {
static const float kOurScore = 0.8;
@@ -229,9 +229,9 @@ class NuPlayerFactory : public MediaPlayerFactory::IFactory {
return 0.0;
}
- virtual float scoreFactory(const sp<IMediaPlayer>& client,
- const sp<IStreamSource> &source,
- float curScore) {
+ virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/,
+ const sp<IStreamSource>& /*source*/,
+ float /*curScore*/) {
return 1.0;
}
@@ -243,7 +243,7 @@ class NuPlayerFactory : public MediaPlayerFactory::IFactory {
class SonivoxPlayerFactory : public MediaPlayerFactory::IFactory {
public:
- virtual float scoreFactory(const sp<IMediaPlayer>& client,
+ virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/,
const char* url,
float curScore) {
static const float kOurScore = 0.4;
@@ -274,7 +274,7 @@ class SonivoxPlayerFactory : public MediaPlayerFactory::IFactory {
return 0.0;
}
- virtual float scoreFactory(const sp<IMediaPlayer>& client,
+ virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/,
int fd,
int64_t offset,
int64_t length,
@@ -312,9 +312,9 @@ class SonivoxPlayerFactory : public MediaPlayerFactory::IFactory {
class TestPlayerFactory : public MediaPlayerFactory::IFactory {
public:
- virtual float scoreFactory(const sp<IMediaPlayer>& client,
+ virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/,
const char* url,
- float curScore) {
+ float /*curScore*/) {
if (TestPlayerStub::canBeUsed(url)) {
return 1.0;
}
diff --git a/media/libmediaplayerservice/MediaPlayerFactory.h b/media/libmediaplayerservice/MediaPlayerFactory.h
index fe8972b..5ddde19 100644
--- a/media/libmediaplayerservice/MediaPlayerFactory.h
+++ b/media/libmediaplayerservice/MediaPlayerFactory.h
@@ -29,19 +29,19 @@ class MediaPlayerFactory {
public:
virtual ~IFactory() { }
- virtual float scoreFactory(const sp<IMediaPlayer>& client,
- const char* url,
- float curScore) { return 0.0; }
-
- virtual float scoreFactory(const sp<IMediaPlayer>& client,
- int fd,
- int64_t offset,
- int64_t length,
- float curScore) { return 0.0; }
-
- virtual float scoreFactory(const sp<IMediaPlayer>& client,
- const sp<IStreamSource> &source,
- float curScore) { return 0.0; }
+ virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/,
+ const char* /*url*/,
+ float /*curScore*/) { return 0.0; }
+
+ virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/,
+ int /*fd*/,
+ int64_t /*offset*/,
+ int64_t /*length*/,
+ float /*curScore*/) { return 0.0; }
+
+ virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/,
+ const sp<IStreamSource> &/*source*/,
+ float /*curScore*/) { return 0.0; }
virtual sp<MediaPlayerBase> createPlayer() = 0;
};
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index cd052e6..a392b76 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -319,7 +319,7 @@ status_t MediaPlayerService::AudioCache::dump(int fd, const Vector<String16>& ar
result.append(" AudioCache\n");
if (mHeap != 0) {
- snprintf(buffer, 255, " heap base(%p), size(%d), flags(%d)\n",
+ snprintf(buffer, 255, " heap base(%p), size(%zu), flags(%d)\n",
mHeap->getBase(), mHeap->getSize(), mHeap->getFlags());
result.append(buffer);
}
@@ -1813,6 +1813,12 @@ int MediaPlayerService::AudioOutput::getSessionId() const
return mSessionId;
}
+uint32_t MediaPlayerService::AudioOutput::getSampleRate() const
+{
+ if (mTrack == 0) return 0;
+ return mTrack->getSampleRate();
+}
+
#undef LOG_TAG
#define LOG_TAG "AudioCache"
MediaPlayerService::AudioCache::AudioCache(const sp<IMemoryHeap>& heap) :
@@ -2015,6 +2021,14 @@ int MediaPlayerService::AudioCache::getSessionId() const
return 0;
}
+uint32_t MediaPlayerService::AudioCache::getSampleRate() const
+{
+ if (mMsecsPerFrame == 0) {
+ return 0;
+ }
+ return (uint32_t)(1.e3 / mMsecsPerFrame);
+}
+
void MediaPlayerService::addBatteryData(uint32_t params)
{
Mutex::Autolock lock(mLock);
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index a486cb5..9c084e1 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -86,6 +86,7 @@ class MediaPlayerService : public BnMediaPlayerService
virtual status_t getPosition(uint32_t *position) const;
virtual status_t getFramesWritten(uint32_t *frameswritten) const;
virtual int getSessionId() const;
+ virtual uint32_t getSampleRate() const;
virtual status_t open(
uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask,
@@ -195,6 +196,7 @@ class MediaPlayerService : public BnMediaPlayerService
virtual status_t getPosition(uint32_t *position) const;
virtual status_t getFramesWritten(uint32_t *frameswritten) const;
virtual int getSessionId() const;
+ virtual uint32_t getSampleRate() const;
virtual status_t open(
uint32_t sampleRate, int channelCount, audio_channel_mask_t channelMask,
diff --git a/media/libmediaplayerservice/MetadataRetrieverClient.cpp b/media/libmediaplayerservice/MetadataRetrieverClient.cpp
index 348957f..063eb94 100644
--- a/media/libmediaplayerservice/MetadataRetrieverClient.cpp
+++ b/media/libmediaplayerservice/MetadataRetrieverClient.cpp
@@ -56,7 +56,7 @@ MetadataRetrieverClient::~MetadataRetrieverClient()
disconnect();
}
-status_t MetadataRetrieverClient::dump(int fd, const Vector<String16>& args) const
+status_t MetadataRetrieverClient::dump(int fd, const Vector<String16>& /*args*/) const
{
const size_t SIZE = 256;
char buffer[SIZE];
@@ -230,7 +230,7 @@ sp<IMemory> MetadataRetrieverClient::extractAlbumArt()
ALOGE("failed to extract an album art");
return NULL;
}
- size_t size = sizeof(MediaAlbumArt) + albumArt->mSize;
+ size_t size = sizeof(MediaAlbumArt) + albumArt->size();
sp<MemoryHeapBase> heap = new MemoryHeapBase(size, 0, "MetadataRetrieverClient");
if (heap == NULL) {
ALOGE("failed to create MemoryDealer object");
@@ -243,11 +243,9 @@ sp<IMemory> MetadataRetrieverClient::extractAlbumArt()
delete albumArt;
return NULL;
}
- MediaAlbumArt *albumArtCopy = static_cast<MediaAlbumArt *>(mAlbumArt->pointer());
- albumArtCopy->mSize = albumArt->mSize;
- albumArtCopy->mData = (uint8_t *)albumArtCopy + sizeof(MediaAlbumArt);
- memcpy(albumArtCopy->mData, albumArt->mData, albumArt->mSize);
- delete albumArt; // Fix memory leakage
+ MediaAlbumArt::init((MediaAlbumArt *) mAlbumArt->pointer(),
+ albumArt->size(), albumArt->data());
+ delete albumArt; // We've taken our copy.
return mAlbumArt;
}
diff --git a/media/libmediaplayerservice/MidiFile.h b/media/libmediaplayerservice/MidiFile.h
index 24d59b4..16792ab 100644
--- a/media/libmediaplayerservice/MidiFile.h
+++ b/media/libmediaplayerservice/MidiFile.h
@@ -36,7 +36,7 @@ public:
virtual status_t setDataSource(int fd, int64_t offset, int64_t length);
virtual status_t setVideoSurfaceTexture(
- const sp<IGraphicBufferProducer>& bufferProducer)
+ const sp<IGraphicBufferProducer>& /*bufferProducer*/)
{ return UNKNOWN_ERROR; }
virtual status_t prepare();
virtual status_t prepareAsync();
@@ -51,13 +51,13 @@ public:
virtual status_t reset();
virtual status_t setLooping(int loop);
virtual player_type playerType() { return SONIVOX_PLAYER; }
- virtual status_t invoke(const Parcel& request, Parcel *reply) {
+ virtual status_t invoke(const Parcel& /*request*/, Parcel* /*reply*/) {
return INVALID_OPERATION;
}
- virtual status_t setParameter(int key, const Parcel &request) {
+ virtual status_t setParameter(int /*key*/, const Parcel &/*request*/) {
return INVALID_OPERATION;
}
- virtual status_t getParameter(int key, Parcel *reply) {
+ virtual status_t getParameter(int /*key*/, Parcel* /*reply*/) {
return INVALID_OPERATION;
}
diff --git a/media/libmediaplayerservice/StagefrightPlayer.cpp b/media/libmediaplayerservice/StagefrightPlayer.cpp
index de61d9b..42b7766 100644
--- a/media/libmediaplayerservice/StagefrightPlayer.cpp
+++ b/media/libmediaplayerservice/StagefrightPlayer.cpp
@@ -187,7 +187,7 @@ status_t StagefrightPlayer::getParameter(int key, Parcel *reply) {
}
status_t StagefrightPlayer::getMetadata(
- const media::Metadata::Filter& ids, Parcel *records) {
+ const media::Metadata::Filter& /* ids */, Parcel *records) {
using media::Metadata;
uint32_t flags = mPlayer->flags();
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index f9d9020..4da74e1 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -16,6 +16,7 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "StagefrightRecorder"
+#include <inttypes.h>
#include <utils/Log.h>
#include "StagefrightRecorder.h"
@@ -1747,15 +1748,15 @@ status_t StagefrightRecorder::dump(
result.append(buffer);
snprintf(buffer, SIZE, " File format: %d\n", mOutputFormat);
result.append(buffer);
- snprintf(buffer, SIZE, " Max file size (bytes): %lld\n", mMaxFileSizeBytes);
+ snprintf(buffer, SIZE, " Max file size (bytes): %" PRId64 "\n", mMaxFileSizeBytes);
result.append(buffer);
- snprintf(buffer, SIZE, " Max file duration (us): %lld\n", mMaxFileDurationUs);
+ snprintf(buffer, SIZE, " Max file duration (us): %" PRId64 "\n", mMaxFileDurationUs);
result.append(buffer);
snprintf(buffer, SIZE, " File offset length (bits): %d\n", mUse64BitFileOffset? 64: 32);
result.append(buffer);
snprintf(buffer, SIZE, " Interleave duration (us): %d\n", mInterleaveDurationUs);
result.append(buffer);
- snprintf(buffer, SIZE, " Progress notification: %lld us\n", mTrackEveryTimeDurationUs);
+ snprintf(buffer, SIZE, " Progress notification: %" PRId64 " us\n", mTrackEveryTimeDurationUs);
result.append(buffer);
snprintf(buffer, SIZE, " Audio\n");
result.append(buffer);
diff --git a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp
index f1782cc..510dcc9 100644
--- a/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/HTTPLiveSource.cpp
@@ -140,7 +140,7 @@ status_t NuPlayer::HTTPLiveSource::selectTrack(size_t trackIndex, bool select) {
// LiveSession::selectTrack returns BAD_VALUE when selecting the currently
// selected track, or unselecting a non-selected track. In this case it's an
// no-op so we return OK.
- return (err == OK || err == BAD_VALUE) ? OK : err;
+ return (err == OK || err == BAD_VALUE) ? (status_t)OK : err;
}
status_t NuPlayer::HTTPLiveSource::seekTo(int64_t seekTimeUs) {
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 3669a5b..25d55a3 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -1011,7 +1011,14 @@ status_t NuPlayer::feedDecoderInputData(bool audio, const sp<AMessage> &msg) {
&NuPlayer::performScanSources));
}
- flushDecoder(audio, formatChange);
+ sp<AMessage> newFormat = mSource->getFormat(audio);
+ sp<Decoder> &decoder = audio ? mAudioDecoder : mVideoDecoder;
+ if (formatChange && !decoder->supportsSeamlessFormatChange(newFormat)) {
+ flushDecoder(audio, /* needShutdown = */ true);
+ } else {
+ flushDecoder(audio, /* needShutdown = */ false);
+ err = OK;
+ }
} else {
// This stream is unaffected by the discontinuity
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
index 22f699e..2423fd5 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
@@ -67,6 +67,7 @@ void NuPlayer::Decoder::configure(const sp<AMessage> &format) {
// queue.
bool needDedicatedLooper = !strncasecmp(mime.c_str(), "video/", 6);
+ mFormat = format;
mCodec = new ACodec;
if (needDedicatedLooper && mCodecLooper == NULL) {
@@ -147,5 +148,65 @@ void NuPlayer::Decoder::initiateShutdown() {
}
}
+bool NuPlayer::Decoder::supportsSeamlessAudioFormatChange(const sp<AMessage> &targetFormat) const {
+ if (targetFormat == NULL) {
+ return true;
+ }
+
+ AString mime;
+ if (!targetFormat->findString("mime", &mime)) {
+ return false;
+ }
+
+ if (!strcasecmp(mime.c_str(), MEDIA_MIMETYPE_AUDIO_AAC)) {
+ // field-by-field comparison
+ const char * keys[] = { "channel-count", "sample-rate", "is-adts" };
+ for (unsigned int i = 0; i < sizeof(keys) / sizeof(keys[0]); i++) {
+ int32_t oldVal, newVal;
+ if (!mFormat->findInt32(keys[i], &oldVal) || !targetFormat->findInt32(keys[i], &newVal)
+ || oldVal != newVal) {
+ return false;
+ }
+ }
+
+ sp<ABuffer> oldBuf, newBuf;
+ if (mFormat->findBuffer("csd-0", &oldBuf) && targetFormat->findBuffer("csd-0", &newBuf)) {
+ if (oldBuf->size() != newBuf->size()) {
+ return false;
+ }
+ return !memcmp(oldBuf->data(), newBuf->data(), oldBuf->size());
+ }
+ }
+ return false;
+}
+
+bool NuPlayer::Decoder::supportsSeamlessFormatChange(const sp<AMessage> &targetFormat) const {
+ if (mFormat == NULL) {
+ return false;
+ }
+
+ if (targetFormat == NULL) {
+ return true;
+ }
+
+ AString oldMime, newMime;
+ if (!mFormat->findString("mime", &oldMime)
+ || !targetFormat->findString("mime", &newMime)
+ || !(oldMime == newMime)) {
+ return false;
+ }
+
+ bool audio = !strncasecmp(oldMime.c_str(), "audio/", strlen("audio/"));
+ bool seamless;
+ if (audio) {
+ seamless = supportsSeamlessAudioFormatChange(targetFormat);
+ } else {
+ seamless = mCodec != NULL && mCodec->isConfiguredForAdaptivePlayback();
+ }
+
+ ALOGV("%s seamless support for %s", seamless ? "yes" : "no", oldMime.c_str());
+ return seamless;
+}
+
} // namespace android
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h
index a876148..78ea74a 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h
@@ -36,6 +36,8 @@ struct NuPlayer::Decoder : public AHandler {
void signalResume();
void initiateShutdown();
+ bool supportsSeamlessFormatChange(const sp<AMessage> &to) const;
+
protected:
virtual ~Decoder();
@@ -49,6 +51,7 @@ private:
sp<AMessage> mNotify;
sp<NativeWindowWrapper> mNativeWindow;
+ sp<AMessage> mFormat;
sp<ACodec> mCodec;
sp<ALooper> mCodecLooper;
@@ -59,6 +62,8 @@ private:
void onFillThisBuffer(const sp<AMessage> &msg);
+ bool supportsSeamlessAudioFormatChange(const sp<AMessage> &targetFormat) const;
+
DISALLOW_EVIL_CONSTRUCTORS(Decoder);
};
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
index 47834fd..b9651a1 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
@@ -16,6 +16,7 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "NuPlayerDriver"
+#include <inttypes.h>
#include <utils/Log.h>
#include "NuPlayerDriver.h"
@@ -364,7 +365,7 @@ status_t NuPlayerDriver::reset() {
return OK;
}
-status_t NuPlayerDriver::setLooping(int loop) {
+status_t NuPlayerDriver::setLooping(int /* loop */) {
return INVALID_OPERATION;
}
@@ -420,16 +421,17 @@ void NuPlayerDriver::setAudioSink(const sp<AudioSink> &audioSink) {
mPlayer->setAudioSink(audioSink);
}
-status_t NuPlayerDriver::setParameter(int key, const Parcel &request) {
+status_t NuPlayerDriver::setParameter(
+ int /* key */, const Parcel & /* request */) {
return INVALID_OPERATION;
}
-status_t NuPlayerDriver::getParameter(int key, Parcel *reply) {
+status_t NuPlayerDriver::getParameter(int /* key */, Parcel * /* reply */) {
return INVALID_OPERATION;
}
status_t NuPlayerDriver::getMetadata(
- const media::Metadata::Filter& ids, Parcel *records) {
+ const media::Metadata::Filter& /* ids */, Parcel *records) {
Mutex::Autolock autoLock(mLock);
using media::Metadata;
@@ -493,13 +495,14 @@ void NuPlayerDriver::notifyFrameStats(
mNumFramesDropped = numFramesDropped;
}
-status_t NuPlayerDriver::dump(int fd, const Vector<String16> &args) const {
+status_t NuPlayerDriver::dump(
+ int fd, const Vector<String16> & /* args */) const {
Mutex::Autolock autoLock(mLock);
FILE *out = fdopen(dup(fd), "w");
fprintf(out, " NuPlayer\n");
- fprintf(out, " numFramesTotal(%lld), numFramesDropped(%lld), "
+ fprintf(out, " numFramesTotal(%" PRId64 "), numFramesDropped(%" PRId64 "), "
"percentageDropped(%.2f)\n",
mNumFramesTotal,
mNumFramesDropped,
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index 92b9a92..bf5271e 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -422,7 +422,9 @@ void NuPlayer::Renderer::onDrainVideoQueue() {
ALOGV("video late by %lld us (%.2f secs)",
mVideoLateByUs, mVideoLateByUs / 1E6);
} else {
- ALOGV("rendering video at media time %.2f secs", mediaTimeUs / 1E6);
+ ALOGV("rendering video at media time %.2f secs",
+ (mFlags & FLAG_REAL_TIME ? realTimeUs :
+ (realTimeUs + mAnchorTimeMediaUs - mAnchorTimeRealUs)) / 1E6);
if (mSoftRenderer != NULL) {
mSoftRenderer->render(entry->mBuffer->data(), entry->mBuffer->size(), NULL);
}
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
index e50533a..11279fc 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerSource.h
@@ -68,19 +68,19 @@ struct NuPlayer::Source : public AHandler {
virtual status_t dequeueAccessUnit(
bool audio, sp<ABuffer> *accessUnit) = 0;
- virtual status_t getDuration(int64_t *durationUs) {
+ virtual status_t getDuration(int64_t * /* durationUs */) {
return INVALID_OPERATION;
}
- virtual status_t getTrackInfo(Parcel* reply) const {
+ virtual status_t getTrackInfo(Parcel* /* reply */) const {
return INVALID_OPERATION;
}
- virtual status_t selectTrack(size_t trackIndex, bool select) {
+ virtual status_t selectTrack(size_t /* trackIndex */, bool /* select */) {
return INVALID_OPERATION;
}
- virtual status_t seekTo(int64_t seekTimeUs) {
+ virtual status_t seekTo(int64_t /* seekTimeUs */) {
return INVALID_OPERATION;
}
@@ -93,7 +93,7 @@ protected:
virtual void onMessageReceived(const sp<AMessage> &msg);
- virtual sp<MetaData> getFormatMeta(bool audio) { return NULL; }
+ virtual sp<MetaData> getFormatMeta(bool /* audio */) { return NULL; }
sp<AMessage> dupNotify() const { return mNotify->dup(); }
diff --git a/media/libmediaplayerservice/nuplayer/mp4/MP4Source.cpp b/media/libmediaplayerservice/nuplayer/mp4/MP4Source.cpp
index d31d947..2aae4dd 100644
--- a/media/libmediaplayerservice/nuplayer/mp4/MP4Source.cpp
+++ b/media/libmediaplayerservice/nuplayer/mp4/MP4Source.cpp
@@ -86,7 +86,7 @@ struct StreamSource : public FragmentedMP4Parser::Source {
total += n;
}
- ALOGV("read %ld bytes at offset %lld", n, mPosition);
+ ALOGV("read %ld bytes at offset %lld", total, mPosition);
mPosition += total;
diff --git a/media/libnbaio/MonoPipe.cpp b/media/libnbaio/MonoPipe.cpp
index de0ad28..3c61b60 100644
--- a/media/libnbaio/MonoPipe.cpp
+++ b/media/libnbaio/MonoPipe.cpp
@@ -183,7 +183,7 @@ ssize_t MonoPipe::write(const void *buffer, size_t count)
}
}
if (ns > 0) {
- const struct timespec req = {0, ns};
+ const struct timespec req = {0, static_cast<long>(ns)};
nanosleep(&req, NULL);
}
// record the time that this write() completed
diff --git a/media/libnbaio/NBLog.cpp b/media/libnbaio/NBLog.cpp
index 045bf64..4f5762f 100644
--- a/media/libnbaio/NBLog.cpp
+++ b/media/libnbaio/NBLog.cpp
@@ -26,6 +26,7 @@
#include <cutils/atomic.h>
#include <media/nbaio/NBLog.h>
#include <utils/Log.h>
+#include <utils/String8.h>
namespace android {
@@ -337,25 +338,25 @@ void NBLog::Reader::dump(int fd, size_t indent)
}
i -= length + 3;
}
+ mFd = fd;
+ mIndent = indent;
+ String8 timestamp, body;
if (i > 0) {
lost += i;
- if (fd >= 0) {
- fdprintf(fd, "%*swarning: lost %u bytes worth of events\n", indent, "", lost);
- } else {
- ALOGI("%*swarning: lost %u bytes worth of events\n", indent, "", lost);
- }
+ body.appendFormat("warning: lost %zu bytes worth of events", lost);
+ // TODO timestamp empty here, only other choice to wait for the first timestamp event in the
+ // log to push it out. Consider keeping the timestamp/body between calls to readAt().
+ dumpLine(timestamp, body);
}
size_t width = 1;
while (maxSec >= 10) {
++width;
maxSec /= 10;
}
- char prefix[32];
if (maxSec >= 0) {
- snprintf(prefix, sizeof(prefix), "[%*s] ", width + 4, "");
- } else {
- prefix[0] = '\0';
+ timestamp.appendFormat("[%*s]", (int) width + 4, "");
}
+ bool deferredTimestamp = false;
while (i < avail) {
event = (Event) copy[i];
length = copy[i + 1];
@@ -363,11 +364,8 @@ void NBLog::Reader::dump(int fd, size_t indent)
size_t advance = length + 3;
switch (event) {
case EVENT_STRING:
- if (fd >= 0) {
- fdprintf(fd, "%*s%s%.*s\n", indent, "", prefix, length, (const char *) data);
- } else {
- ALOGI("%*s%s%.*s", indent, "", prefix, length, (const char *) data);
- } break;
+ body.appendFormat("%.*s", (int) length, (const char *) data);
+ break;
case EVENT_TIMESTAMP: {
// already checked that length == sizeof(struct timespec);
memcpy(&ts, data, sizeof(struct timespec));
@@ -400,45 +398,53 @@ void NBLog::Reader::dump(int fd, size_t indent)
prevNsec = tsNext.tv_nsec;
}
size_t n = (j - i) / (sizeof(struct timespec) + 3);
+ if (deferredTimestamp) {
+ dumpLine(timestamp, body);
+ deferredTimestamp = false;
+ }
+ timestamp.clear();
if (n >= kSquashTimestamp) {
- if (fd >= 0) {
- fdprintf(fd, "%*s[%d.%03d to .%.03d by .%.03d to .%.03d]\n", indent, "",
- (int) ts.tv_sec, (int) (ts.tv_nsec / 1000000),
- (int) ((ts.tv_nsec + deltaTotal) / 1000000),
- (int) (deltaMin / 1000000), (int) (deltaMax / 1000000));
- } else {
- ALOGI("%*s[%d.%03d to .%.03d by .%.03d to .%.03d]\n", indent, "",
- (int) ts.tv_sec, (int) (ts.tv_nsec / 1000000),
- (int) ((ts.tv_nsec + deltaTotal) / 1000000),
- (int) (deltaMin / 1000000), (int) (deltaMax / 1000000));
- }
+ timestamp.appendFormat("[%d.%03d to .%.03d by .%.03d to .%.03d]",
+ (int) ts.tv_sec, (int) (ts.tv_nsec / 1000000),
+ (int) ((ts.tv_nsec + deltaTotal) / 1000000),
+ (int) (deltaMin / 1000000), (int) (deltaMax / 1000000));
i = j;
advance = 0;
break;
}
- if (fd >= 0) {
- fdprintf(fd, "%*s[%d.%03d]\n", indent, "", (int) ts.tv_sec,
- (int) (ts.tv_nsec / 1000000));
- } else {
- ALOGI("%*s[%d.%03d]", indent, "", (int) ts.tv_sec,
- (int) (ts.tv_nsec / 1000000));
- }
+ timestamp.appendFormat("[%d.%03d]", (int) ts.tv_sec,
+ (int) (ts.tv_nsec / 1000000));
+ deferredTimestamp = true;
} break;
case EVENT_RESERVED:
default:
- if (fd >= 0) {
- fdprintf(fd, "%*s%swarning: unknown event %d\n", indent, "", prefix, event);
- } else {
- ALOGI("%*s%swarning: unknown event %d", indent, "", prefix, event);
- }
+ body.appendFormat("warning: unknown event %d", event);
break;
}
i += advance;
+
+ if (!body.isEmpty()) {
+ dumpLine(timestamp, body);
+ deferredTimestamp = false;
+ }
+ }
+ if (deferredTimestamp) {
+ dumpLine(timestamp, body);
}
// FIXME it would be more efficient to put a char mCopy[256] as a member variable of the dumper
delete[] copy;
}
+void NBLog::Reader::dumpLine(const String8& timestamp, String8& body)
+{
+ if (mFd >= 0) {
+ dprintf(mFd, "%.*s%s %s\n", mIndent, "", timestamp.string(), body.string());
+ } else {
+ ALOGI("%.*s%s %s", mIndent, "", timestamp.string(), body.string());
+ }
+ body.clear();
+}
+
bool NBLog::Reader::isIMemory(const sp<IMemory>& iMemory) const
{
return iMemory.get() == mIMemory.get();
diff --git a/media/libstagefright/AACExtractor.cpp b/media/libstagefright/AACExtractor.cpp
index 4d1072f..196f6ee 100644
--- a/media/libstagefright/AACExtractor.cpp
+++ b/media/libstagefright/AACExtractor.cpp
@@ -219,7 +219,7 @@ sp<MediaSource> AACExtractor::getTrack(size_t index) {
return new AACSource(mDataSource, mMeta, mOffsetVector, mFrameDurationUs);
}
-sp<MetaData> AACExtractor::getTrackMetaData(size_t index, uint32_t flags) {
+sp<MetaData> AACExtractor::getTrackMetaData(size_t index, uint32_t /* flags */) {
if (mInitCheck != OK || index != 0) {
return NULL;
}
@@ -252,7 +252,7 @@ AACSource::~AACSource() {
}
}
-status_t AACSource::start(MetaData *params) {
+status_t AACSource::start(MetaData * /* params */) {
CHECK(!mStarted);
if (mOffsetVector.empty()) {
diff --git a/media/libstagefright/AACWriter.cpp b/media/libstagefright/AACWriter.cpp
index a6f7cfb..deee8e7 100644
--- a/media/libstagefright/AACWriter.cpp
+++ b/media/libstagefright/AACWriter.cpp
@@ -111,7 +111,7 @@ status_t AACWriter::addSource(const sp<MediaSource> &source) {
return OK;
}
-status_t AACWriter::start(MetaData *params) {
+status_t AACWriter::start(MetaData * /* params */) {
if (mInitCheck != OK) {
return mInitCheck;
}
@@ -171,7 +171,7 @@ status_t AACWriter::reset() {
void *dummy;
pthread_join(mThread, &dummy);
- status_t err = (status_t) dummy;
+ status_t err = static_cast<status_t>(reinterpret_cast<uintptr_t>(dummy));
{
status_t status = mSource->stop();
if (err == OK &&
@@ -200,7 +200,7 @@ bool AACWriter::exceedsFileDurationLimit() {
// static
void *AACWriter::ThreadWrapper(void *me) {
- return (void *) static_cast<AACWriter *>(me)->threadFunc();
+ return (void *)(uintptr_t)static_cast<AACWriter *>(me)->threadFunc();
}
/*
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 528fdb9..1a87e9c 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -17,6 +17,9 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "ACodec"
+#include <inttypes.h>
+#include <utils/Trace.h>
+
#include <media/stagefright/ACodec.h>
#include <binder/MemoryDealer.h>
@@ -62,7 +65,7 @@ struct CodecObserver : public BnOMXObserver {
sp<AMessage> msg = mNotify->dup();
msg->setInt32("type", omx_msg.type);
- msg->setPointer("node", omx_msg.node);
+ msg->setInt32("node", omx_msg.node);
switch (omx_msg.type) {
case omx_message::EVENT:
@@ -75,13 +78,13 @@ struct CodecObserver : public BnOMXObserver {
case omx_message::EMPTY_BUFFER_DONE:
{
- msg->setPointer("buffer", omx_msg.u.buffer_data.buffer);
+ msg->setInt32("buffer", omx_msg.u.buffer_data.buffer);
break;
}
case omx_message::FILL_BUFFER_DONE:
{
- msg->setPointer(
+ msg->setInt32(
"buffer", omx_msg.u.extended_buffer_data.buffer);
msg->setInt32(
"range_offset",
@@ -358,11 +361,12 @@ private:
ACodec::ACodec()
: mQuirks(0),
- mNode(NULL),
+ mNode(0),
mSentFormat(false),
mIsEncoder(false),
mUseMetadataOnEncoderOutput(false),
mShutdownInProgress(false),
+ mIsConfiguredForAdaptivePlayback(false),
mEncoderDelay(0),
mEncoderPadding(0),
mChannelMaskPresent(false),
@@ -370,7 +374,8 @@ ACodec::ACodec()
mDequeueCounter(0),
mStoreMetaDataInOutputBuffers(false),
mMetaDataBuffersToSubmit(0),
- mRepeatFrameDelayUs(-1ll) {
+ mRepeatFrameDelayUs(-1ll),
+ mMaxPtsGapUs(-1ll) {
mUninitializedState = new UninitializedState(this);
mLoadedState = new LoadedState(this);
mLoadedToIdleState = new LoadedToIdleState(this);
@@ -452,6 +457,18 @@ void ACodec::signalRequestIDRFrame() {
(new AMessage(kWhatRequestIDRFrame, id()))->post();
}
+// *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
+// Some codecs may return input buffers before having them processed.
+// This causes a halt if we already signaled an EOS on the input
+// port. For now keep submitting an output buffer if there was an
+// EOS on the input port, but not yet on the output port.
+void ACodec::signalSubmitOutputMetaDataBufferIfEOS_workaround() {
+ if (mPortEOS[kPortIndexInput] && !mPortEOS[kPortIndexOutput] &&
+ mMetaDataBuffersToSubmit > 0) {
+ (new AMessage(kWhatSubmitOutputMetaDataBufferIfEOS, id()))->post();
+ }
+}
+
status_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
@@ -474,7 +491,7 @@ status_t ACodec::allocateBuffersOnPort(OMX_U32 portIndex) {
mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
if (err == OK) {
- ALOGV("[%s] Allocating %lu buffers of size %lu on %s port",
+ ALOGV("[%s] Allocating %u buffers of size %u on %s port",
mComponentName.c_str(),
def.nBufferCountActual, def.nBufferSize,
portIndex == kPortIndexInput ? "input" : "output");
@@ -624,18 +641,34 @@ status_t ACodec::configureOutputBuffersFromNativeWindow(
return err;
}
- // XXX: Is this the right logic to use? It's not clear to me what the OMX
- // buffer counts refer to - how do they account for the renderer holding on
- // to buffers?
- if (def.nBufferCountActual < def.nBufferCountMin + *minUndequeuedBuffers) {
- OMX_U32 newBufferCount = def.nBufferCountMin + *minUndequeuedBuffers;
+ // FIXME: assume that surface is controlled by app (native window
+ // returns the number for the case when surface is not controlled by app)
+ // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported
+ // For now, try to allocate 1 more buffer, but don't fail if unsuccessful
+
+ // Use conservative allocation while also trying to reduce starvation
+ //
+ // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the
+ // minimum needed for the consumer to be able to work
+ // 2. try to allocate two (2) additional buffers to reduce starvation from
+ // the consumer
+ // plus an extra buffer to account for incorrect minUndequeuedBufs
+ for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) {
+ OMX_U32 newBufferCount =
+ def.nBufferCountMin + *minUndequeuedBuffers + extraBuffers;
def.nBufferCountActual = newBufferCount;
err = mOMX->setParameter(
mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
- if (err != OK) {
- ALOGE("[%s] setting nBufferCountActual to %lu failed: %d",
- mComponentName.c_str(), newBufferCount, err);
+ if (err == OK) {
+ *minUndequeuedBuffers += extraBuffers;
+ break;
+ }
+
+ ALOGW("[%s] setting nBufferCountActual to %u failed: %d",
+ mComponentName.c_str(), newBufferCount, err);
+ /* exit condition */
+ if (extraBuffers == 0) {
return err;
}
}
@@ -660,8 +693,9 @@ status_t ACodec::allocateOutputBuffersFromNativeWindow() {
&bufferCount, &bufferSize, &minUndequeuedBuffers);
if (err != 0)
return err;
+ mNumUndequeuedBuffers = minUndequeuedBuffers;
- ALOGV("[%s] Allocating %lu buffers from a native window of size %lu on "
+ ALOGV("[%s] Allocating %u buffers from a native window of size %u on "
"output port",
mComponentName.c_str(), bufferCount, bufferSize);
@@ -685,14 +719,14 @@ status_t ACodec::allocateOutputBuffersFromNativeWindow() {
err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer,
&bufferId);
if (err != 0) {
- ALOGE("registering GraphicBuffer %lu with OMX IL component failed: "
+ ALOGE("registering GraphicBuffer %u with OMX IL component failed: "
"%d", i, err);
break;
}
mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId;
- ALOGV("[%s] Registered graphic buffer with ID %p (pointer = %p)",
+ ALOGV("[%s] Registered graphic buffer with ID %u (pointer = %p)",
mComponentName.c_str(),
bufferId, graphicBuffer.get());
}
@@ -725,8 +759,9 @@ status_t ACodec::allocateOutputMetaDataBuffers() {
&bufferCount, &bufferSize, &minUndequeuedBuffers);
if (err != 0)
return err;
+ mNumUndequeuedBuffers = minUndequeuedBuffers;
- ALOGV("[%s] Allocating %lu meta buffers on output port",
+ ALOGV("[%s] Allocating %u meta buffers on output port",
mComponentName.c_str(), bufferCount);
size_t totalSize = bufferCount * 8;
@@ -750,7 +785,7 @@ status_t ACodec::allocateOutputMetaDataBuffers() {
mBuffers[kPortIndexOutput].push(info);
- ALOGV("[%s] allocated meta buffer with ID %p (pointer = %p)",
+ ALOGV("[%s] allocated meta buffer with ID %u (pointer = %p)",
mComponentName.c_str(), info.mBufferID, mem->pointer());
}
@@ -767,7 +802,7 @@ status_t ACodec::submitOutputMetaDataBuffer() {
if (info == NULL)
return ERROR_IO;
- ALOGV("[%s] submitting output meta buffer ID %p for graphic buffer %p",
+ ALOGV("[%s] submitting output meta buffer ID %u for graphic buffer %p",
mComponentName.c_str(), info->mBufferID, info->mGraphicBuffer.get());
--mMetaDataBuffersToSubmit;
@@ -781,7 +816,7 @@ status_t ACodec::submitOutputMetaDataBuffer() {
status_t ACodec::cancelBufferToNativeWindow(BufferInfo *info) {
CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
- ALOGV("[%s] Calling cancelBuffer on buffer %p",
+ ALOGV("[%s] Calling cancelBuffer on buffer %u",
mComponentName.c_str(), info->mBufferID);
int err = mNativeWindow->cancelBuffer(
@@ -1096,6 +1131,10 @@ status_t ACodec::configureCodec(
&mRepeatFrameDelayUs)) {
mRepeatFrameDelayUs = -1ll;
}
+
+ if (!msg->findInt64("max-pts-gap-to-encoder", &mMaxPtsGapUs)) {
+ mMaxPtsGapUs = -1l;
+ }
}
// Always try to enable dynamic output buffers on native surface
@@ -1103,6 +1142,7 @@ status_t ACodec::configureCodec(
int32_t haveNativeWindow = msg->findObject("native-window", &obj) &&
obj != NULL;
mStoreMetaDataInOutputBuffers = false;
+ mIsConfiguredForAdaptivePlayback = false;
if (!encoder && video && haveNativeWindow) {
err = mOMX->storeMetaDataInBuffers(mNode, kPortIndexOutput, OMX_TRUE);
if (err != OK) {
@@ -1139,7 +1179,7 @@ status_t ACodec::configureCodec(
if (canDoAdaptivePlayback &&
msg->findInt32("max-width", &maxWidth) &&
msg->findInt32("max-height", &maxHeight)) {
- ALOGV("[%s] prepareForAdaptivePlayback(%ldx%ld)",
+ ALOGV("[%s] prepareForAdaptivePlayback(%dx%d)",
mComponentName.c_str(), maxWidth, maxHeight);
err = mOMX->prepareForAdaptivePlayback(
@@ -1147,12 +1187,14 @@ status_t ACodec::configureCodec(
ALOGW_IF(err != OK,
"[%s] prepareForAdaptivePlayback failed w/ err %d",
mComponentName.c_str(), err);
+ mIsConfiguredForAdaptivePlayback = (err == OK);
}
// allow failure
err = OK;
} else {
ALOGV("[%s] storeMetaDataInBuffers succeeded", mComponentName.c_str());
mStoreMetaDataInOutputBuffers = true;
+ mIsConfiguredForAdaptivePlayback = true;
}
int32_t push;
@@ -2408,19 +2450,7 @@ void ACodec::waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs() {
return;
}
- int minUndequeuedBufs = 0;
- status_t err = mNativeWindow->query(
- mNativeWindow.get(), NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS,
- &minUndequeuedBufs);
-
- if (err != OK) {
- ALOGE("[%s] NATIVE_WINDOW_MIN_UNDEQUEUED_BUFFERS query failed: %s (%d)",
- mComponentName.c_str(), strerror(-err), -err);
-
- minUndequeuedBufs = 0;
- }
-
- while (countBuffersOwnedByNativeWindow() > (size_t)minUndequeuedBufs
+ while (countBuffersOwnedByNativeWindow() > mNumUndequeuedBuffers
&& dequeueBufferFromNativeWindow() != NULL) {
// these buffers will be submitted as regular buffers; account for this
if (mStoreMetaDataInOutputBuffers && mMetaDataBuffersToSubmit > 0) {
@@ -2436,7 +2466,7 @@ bool ACodec::allYourBuffersAreBelongToUs(
if (info->mStatus != BufferInfo::OWNED_BY_US
&& info->mStatus != BufferInfo::OWNED_BY_NATIVE_WINDOW) {
- ALOGV("[%s] Buffer %p on port %ld still has status %d",
+ ALOGV("[%s] Buffer %u on port %u still has status %d",
mComponentName.c_str(),
info->mBufferID, portIndex, info->mStatus);
return false;
@@ -2918,7 +2948,7 @@ bool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
CHECK(msg->findInt32("type", &type));
IOMX::node_id nodeID;
- CHECK(msg->findPointer("node", &nodeID));
+ CHECK(msg->findInt32("node", (int32_t*)&nodeID));
CHECK_EQ(nodeID, mCodec->mNode);
switch (type) {
@@ -2949,7 +2979,7 @@ bool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
case omx_message::EMPTY_BUFFER_DONE:
{
IOMX::buffer_id bufferID;
- CHECK(msg->findPointer("buffer", &bufferID));
+ CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
return onOMXEmptyBufferDone(bufferID);
}
@@ -2957,7 +2987,7 @@ bool ACodec::BaseState::onOMXMessage(const sp<AMessage> &msg) {
case omx_message::FILL_BUFFER_DONE:
{
IOMX::buffer_id bufferID;
- CHECK(msg->findPointer("buffer", &bufferID));
+ CHECK(msg->findInt32("buffer", (int32_t*)&bufferID));
int32_t rangeOffset, rangeLength, flags;
int64_t timeUs;
@@ -3060,13 +3090,13 @@ void ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
sp<AMessage> notify = mCodec->mNotify->dup();
notify->setInt32("what", ACodec::kWhatFillThisBuffer);
- notify->setPointer("buffer-id", info->mBufferID);
+ notify->setInt32("buffer-id", info->mBufferID);
info->mData->meta()->clear();
notify->setBuffer("buffer", info->mData);
sp<AMessage> reply = new AMessage(kWhatInputBufferFilled, mCodec->id());
- reply->setPointer("buffer-id", info->mBufferID);
+ reply->setInt32("buffer-id", info->mBufferID);
notify->setMessage("reply", reply);
@@ -3077,8 +3107,7 @@ void ACodec::BaseState::postFillThisBuffer(BufferInfo *info) {
void ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
IOMX::buffer_id bufferID;
- CHECK(msg->findPointer("buffer-id", &bufferID));
-
+ CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
sp<ABuffer> buffer;
int32_t err = OK;
bool eos = false;
@@ -3235,11 +3264,11 @@ void ACodec::BaseState::onInputBufferFilled(const sp<AMessage> &msg) {
mCodec->mInputEOSResult = err;
}
break;
-
- default:
- CHECK_EQ((int)mode, (int)FREE_BUFFERS);
- break;
}
+
+ default:
+ CHECK_EQ((int)mode, (int)FREE_BUFFERS);
+ break;
}
}
@@ -3316,7 +3345,7 @@ bool ACodec::BaseState::onOMXFillBufferDone(
case RESUBMIT_BUFFERS:
{
if (rangeLength == 0 && !(flags & OMX_BUFFERFLAG_EOS)) {
- ALOGV("[%s] calling fillBuffer %p",
+ ALOGV("[%s] calling fillBuffer %u",
mCodec->mComponentName.c_str(), info->mBufferID);
CHECK_EQ(mCodec->mOMX->fillBuffer(
@@ -3358,11 +3387,11 @@ bool ACodec::BaseState::onOMXFillBufferDone(
sp<AMessage> notify = mCodec->mNotify->dup();
notify->setInt32("what", ACodec::kWhatDrainThisBuffer);
- notify->setPointer("buffer-id", info->mBufferID);
+ notify->setInt32("buffer-id", info->mBufferID);
notify->setBuffer("buffer", info->mData);
notify->setInt32("flags", flags);
- reply->setPointer("buffer-id", info->mBufferID);
+ reply->setInt32("buffer-id", info->mBufferID);
notify->setMessage("reply", reply);
@@ -3398,8 +3427,7 @@ bool ACodec::BaseState::onOMXFillBufferDone(
void ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
IOMX::buffer_id bufferID;
- CHECK(msg->findPointer("buffer-id", &bufferID));
-
+ CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
ssize_t index;
BufferInfo *info =
mCodec->findBufferByID(kPortIndexOutput, bufferID, &index);
@@ -3415,7 +3443,8 @@ void ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
int32_t render;
if (mCodec->mNativeWindow != NULL
&& msg->findInt32("render", &render) && render != 0
- && (info->mData == NULL || info->mData->size() != 0)) {
+ && info->mData != NULL && info->mData->size() != 0) {
+ ATRACE_NAME("render");
// The client wants this buffer to be rendered.
status_t err;
@@ -3428,6 +3457,10 @@ void ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
info->mStatus = BufferInfo::OWNED_BY_US;
}
} else {
+ if (mCodec->mNativeWindow != NULL &&
+ (info->mData == NULL || info->mData->size() != 0)) {
+ ATRACE_NAME("frame-drop");
+ }
info->mStatus = BufferInfo::OWNED_BY_US;
}
@@ -3458,7 +3491,7 @@ void ACodec::BaseState::onOutputBufferDrained(const sp<AMessage> &msg) {
}
if (info != NULL) {
- ALOGV("[%s] calling fillBuffer %p",
+ ALOGV("[%s] calling fillBuffer %u",
mCodec->mComponentName.c_str(), info->mBufferID);
CHECK_EQ(mCodec->mOMX->fillBuffer(mCodec->mNode, info->mBufferID),
@@ -3621,7 +3654,7 @@ bool ACodec::UninitializedState::onAllocateComponent(const sp<AMessage> &msg) {
componentName = matchingCodecs.itemAt(matchIndex).mName.string();
quirks = matchingCodecs.itemAt(matchIndex).mQuirks;
- pid_t tid = androidGetTid();
+ pid_t tid = gettid();
int prevPriority = androidGetThreadPriority(tid);
androidSetThreadPriority(tid, ANDROID_PRIORITY_FOREGROUND);
status_t err = omx->allocateNode(componentName.c_str(), observer, &node);
@@ -3690,6 +3723,7 @@ void ACodec::LoadedState::stateEntered() {
mCodec->mDequeueCounter = 0;
mCodec->mMetaDataBuffersToSubmit = 0;
mCodec->mRepeatFrameDelayUs = -1ll;
+ mCodec->mIsConfiguredForAdaptivePlayback = false;
if (mCodec->mShutdownInProgress) {
bool keepComponentAllocated = mCodec->mKeepComponentAllocated;
@@ -3838,6 +3872,21 @@ void ACodec::LoadedState::onCreateInputSurface(
}
}
+ if (err == OK && mCodec->mMaxPtsGapUs > 0l) {
+ err = mCodec->mOMX->setInternalOption(
+ mCodec->mNode,
+ kPortIndexInput,
+ IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP,
+ &mCodec->mMaxPtsGapUs,
+ sizeof(mCodec->mMaxPtsGapUs));
+
+ if (err != OK) {
+ ALOGE("[%s] Unable to configure max timestamp gap (err %d)",
+ mCodec->mComponentName.c_str(),
+ err);
+ }
+ }
+
if (err == OK) {
notify->setObject("input-surface",
new BufferProducerWrapper(bufferProducer));
@@ -4036,6 +4085,9 @@ void ACodec::ExecutingState::submitOutputMetaBuffers() {
break;
}
}
+
+ // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
+ mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
}
void ACodec::ExecutingState::submitRegularOutputBuffers() {
@@ -4184,6 +4236,19 @@ bool ACodec::ExecutingState::onMessageReceived(const sp<AMessage> &msg) {
break;
}
+ // *** NOTE: THE FOLLOWING WORKAROUND WILL BE REMOVED ***
+ case kWhatSubmitOutputMetaDataBufferIfEOS:
+ {
+ if (mCodec->mPortEOS[kPortIndexInput] &&
+ !mCodec->mPortEOS[kPortIndexOutput]) {
+ status_t err = mCodec->submitOutputMetaDataBuffer();
+ if (err == OK) {
+ mCodec->signalSubmitOutputMetaDataBufferIfEOS_workaround();
+ }
+ }
+ return true;
+ }
+
default:
handled = BaseState::onMessageReceived(msg);
break;
@@ -4636,7 +4701,7 @@ bool ACodec::FlushingState::onOMXEvent(
{
sp<AMessage> msg = new AMessage(kWhatOMXMessage, mCodec->id());
msg->setInt32("type", omx_message::EVENT);
- msg->setPointer("node", mCodec->mNode);
+ msg->setInt32("node", mCodec->mNode);
msg->setInt32("event", event);
msg->setInt32("data1", data1);
msg->setInt32("data2", data2);
diff --git a/media/libstagefright/AMRExtractor.cpp b/media/libstagefright/AMRExtractor.cpp
index 03dcbf9..a6fb3d8 100644
--- a/media/libstagefright/AMRExtractor.cpp
+++ b/media/libstagefright/AMRExtractor.cpp
@@ -189,7 +189,7 @@ sp<MediaSource> AMRExtractor::getTrack(size_t index) {
mOffsetTable, mOffsetTableLength);
}
-sp<MetaData> AMRExtractor::getTrackMetaData(size_t index, uint32_t flags) {
+sp<MetaData> AMRExtractor::getTrackMetaData(size_t index, uint32_t /* flags */) {
if (mInitCheck != OK || index != 0) {
return NULL;
}
@@ -221,7 +221,7 @@ AMRSource::~AMRSource() {
}
}
-status_t AMRSource::start(MetaData *params) {
+status_t AMRSource::start(MetaData * /* params */) {
CHECK(!mStarted);
mOffset = mIsWide ? 9 : 6;
@@ -258,14 +258,14 @@ status_t AMRSource::read(
int64_t seekFrame = seekTimeUs / 20000ll; // 20ms per frame.
mCurrentTimeUs = seekFrame * 20000ll;
- int index = seekFrame / 50;
+ size_t index = seekFrame < 0 ? 0 : seekFrame / 50;
if (index >= mOffsetTableLength) {
index = mOffsetTableLength - 1;
}
mOffset = mOffsetTable[index] + (mIsWide ? 9 : 6);
- for (int i = 0; i< seekFrame - index * 50; i++) {
+ for (size_t i = 0; i< seekFrame - index * 50; i++) {
status_t err;
if ((err = getFrameSizeByOffset(mDataSource, mOffset,
mIsWide, &size)) != OK) {
diff --git a/media/libstagefright/AMRWriter.cpp b/media/libstagefright/AMRWriter.cpp
index 8d5eec8..653ca36 100644
--- a/media/libstagefright/AMRWriter.cpp
+++ b/media/libstagefright/AMRWriter.cpp
@@ -105,7 +105,7 @@ status_t AMRWriter::addSource(const sp<MediaSource> &source) {
return OK;
}
-status_t AMRWriter::start(MetaData *params) {
+status_t AMRWriter::start(MetaData * /* params */) {
if (mInitCheck != OK) {
return mInitCheck;
}
@@ -162,7 +162,7 @@ status_t AMRWriter::reset() {
void *dummy;
pthread_join(mThread, &dummy);
- status_t err = (status_t) dummy;
+ status_t err = static_cast<status_t>(reinterpret_cast<uintptr_t>(dummy));
{
status_t status = mSource->stop();
if (err == OK &&
@@ -191,7 +191,7 @@ bool AMRWriter::exceedsFileDurationLimit() {
// static
void *AMRWriter::ThreadWrapper(void *me) {
- return (void *) static_cast<AMRWriter *>(me)->threadFunc();
+ return (void *)(uintptr_t) static_cast<AMRWriter *>(me)->threadFunc();
}
status_t AMRWriter::threadFunc() {
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index 6a2a696..3619821 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -14,6 +14,7 @@ LOCAL_SRC_FILES:= \
AwesomePlayer.cpp \
CameraSource.cpp \
CameraSourceTimeLapse.cpp \
+ ClockEstimator.cpp \
DataSource.cpp \
DRMExtractor.cpp \
ESDS.cpp \
diff --git a/media/libstagefright/AudioPlayer.cpp b/media/libstagefright/AudioPlayer.cpp
index a8a8786..8623100 100644
--- a/media/libstagefright/AudioPlayer.cpp
+++ b/media/libstagefright/AudioPlayer.cpp
@@ -410,7 +410,7 @@ status_t AudioPlayer::setPlaybackRatePermille(int32_t ratePermille) {
// static
size_t AudioPlayer::AudioSinkCallback(
- MediaPlayerBase::AudioSink *audioSink,
+ MediaPlayerBase::AudioSink * /* audioSink */,
void *buffer, size_t size, void *cookie,
MediaPlayerBase::AudioSink::cb_event_t event) {
AudioPlayer *me = (AudioPlayer *)cookie;
@@ -721,16 +721,27 @@ int64_t AudioPlayer::getRealTimeUsLocked() const {
return result + diffUs;
}
-int64_t AudioPlayer::getOutputPlayPositionUs_l() const
+int64_t AudioPlayer::getOutputPlayPositionUs_l()
{
uint32_t playedSamples = 0;
+ uint32_t sampleRate;
if (mAudioSink != NULL) {
mAudioSink->getPosition(&playedSamples);
+ sampleRate = mAudioSink->getSampleRate();
} else {
mAudioTrack->getPosition(&playedSamples);
+ sampleRate = mAudioTrack->getSampleRate();
+ }
+ if (sampleRate != 0) {
+ mSampleRate = sampleRate;
}
- const int64_t playedUs = (static_cast<int64_t>(playedSamples) * 1000000 ) / mSampleRate;
+ int64_t playedUs;
+ if (mSampleRate != 0) {
+ playedUs = (static_cast<int64_t>(playedSamples) * 1000000 ) / mSampleRate;
+ } else {
+ playedUs = 0;
+ }
// HAL position is relative to the first buffer we sent at mStartPosUs
const int64_t renderedDuration = mStartPosUs + playedUs;
diff --git a/media/libstagefright/AudioSource.cpp b/media/libstagefright/AudioSource.cpp
index d7223d9..e68a710 100644
--- a/media/libstagefright/AudioSource.cpp
+++ b/media/libstagefright/AudioSource.cpp
@@ -68,7 +68,7 @@ AudioSource::AudioSource(
int frameCount = kMaxBufferSize / sizeof(int16_t) / channelCount;
// make sure that the AudioRecord total buffer size is large enough
- int bufCount = 2;
+ size_t bufCount = 2;
while ((bufCount * frameCount) < minFrameCount) {
bufCount++;
}
@@ -208,7 +208,7 @@ void AudioSource::rampVolume(
}
status_t AudioSource::read(
- MediaBuffer **out, const ReadOptions *options) {
+ MediaBuffer **out, const ReadOptions * /* options */) {
Mutex::Autolock autoLock(mLock);
*out = NULL;
@@ -308,7 +308,7 @@ status_t AudioSource::dataCallback(const AudioRecord::Buffer& audioBuffer) {
if (numLostBytes > 0) {
// Loss of audio frames should happen rarely; thus the LOGW should
// not cause a logging spam
- ALOGW("Lost audio record data: %d bytes", numLostBytes);
+ ALOGW("Lost audio record data: %zu bytes", numLostBytes);
}
while (numLostBytes > 0) {
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 130207d..ea6c15b 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -19,6 +19,7 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "AwesomePlayer"
#define ATRACE_TAG ATRACE_TAG_VIDEO
+#include <inttypes.h>
#include <utils/Log.h>
#include <utils/Trace.h>
@@ -39,6 +40,7 @@
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/timedtext/TimedTextDriver.h>
#include <media/stagefright/AudioPlayer.h>
+#include <media/stagefright/ClockEstimator.h>
#include <media/stagefright/DataSource.h>
#include <media/stagefright/FileSource.h>
#include <media/stagefright/MediaBuffer.h>
@@ -82,7 +84,7 @@ struct AwesomeEvent : public TimedEventQueue::Event {
protected:
virtual ~AwesomeEvent() {}
- virtual void fire(TimedEventQueue *queue, int64_t /* now_us */) {
+ virtual void fire(TimedEventQueue * /* queue */, int64_t /* now_us */) {
(mPlayer->*mMethod)();
}
@@ -227,6 +229,8 @@ AwesomePlayer::AwesomePlayer()
&AwesomePlayer::onAudioTearDownEvent);
mAudioTearDownEventPending = false;
+ mClockEstimator = new WindowedLinearFitEstimator();
+
reset();
}
@@ -725,7 +729,7 @@ void AwesomePlayer::onBufferingUpdate() {
if ((mFlags & PLAYING) && !eos
&& (cachedDataRemaining < kLowWaterMarkBytes)) {
- ALOGI("cache is running low (< %d) , pausing.",
+ ALOGI("cache is running low (< %zu) , pausing.",
kLowWaterMarkBytes);
modifyFlags(CACHE_UNDERRUN, SET);
pause_l();
@@ -734,12 +738,12 @@ void AwesomePlayer::onBufferingUpdate() {
notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_START);
} else if (eos || cachedDataRemaining > kHighWaterMarkBytes) {
if (mFlags & CACHE_UNDERRUN) {
- ALOGI("cache has filled up (> %d), resuming.",
+ ALOGI("cache has filled up (> %zu), resuming.",
kHighWaterMarkBytes);
modifyFlags(CACHE_UNDERRUN, CLEAR);
play_l();
} else if (mFlags & PREPARING) {
- ALOGV("cache has filled up (> %d), prepare is done",
+ ALOGV("cache has filled up (> %zu), prepare is done",
kHighWaterMarkBytes);
finishAsyncPrepare_l();
}
@@ -1858,21 +1862,28 @@ void AwesomePlayer::onVideoEvent() {
TimeSource *ts =
((mFlags & AUDIO_AT_EOS) || !(mFlags & AUDIOPLAYER_STARTED))
? &mSystemTimeSource : mTimeSource;
+ int64_t systemTimeUs = mSystemTimeSource.getRealTimeUs();
+ int64_t looperTimeUs = ALooper::GetNowUs();
if (mFlags & FIRST_FRAME) {
modifyFlags(FIRST_FRAME, CLEAR);
mSinceLastDropped = 0;
- mTimeSourceDeltaUs = ts->getRealTimeUs() - timeUs;
+ mClockEstimator->reset();
+ mTimeSourceDeltaUs = estimateRealTimeUs(ts, systemTimeUs) - timeUs;
}
int64_t realTimeUs, mediaTimeUs;
if (!(mFlags & AUDIO_AT_EOS) && mAudioPlayer != NULL
&& mAudioPlayer->getMediaTimeMapping(&realTimeUs, &mediaTimeUs)) {
+ ALOGV("updating TSdelta (%" PRId64 " => %" PRId64 " change %" PRId64 ")",
+ mTimeSourceDeltaUs, realTimeUs - mediaTimeUs,
+ mTimeSourceDeltaUs - (realTimeUs - mediaTimeUs));
+ ATRACE_INT("TS delta change (ms)", (mTimeSourceDeltaUs - (realTimeUs - mediaTimeUs)) / 1E3);
mTimeSourceDeltaUs = realTimeUs - mediaTimeUs;
}
if (wasSeeking == SEEK_VIDEO_ONLY) {
- int64_t nowUs = ts->getRealTimeUs() - mTimeSourceDeltaUs;
+ int64_t nowUs = estimateRealTimeUs(ts, systemTimeUs) - mTimeSourceDeltaUs;
int64_t latenessUs = nowUs - timeUs;
@@ -1883,12 +1894,13 @@ void AwesomePlayer::onVideoEvent() {
}
}
+ int64_t latenessUs = 0;
if (wasSeeking == NO_SEEK) {
// Let's display the first frame after seeking right away.
- int64_t nowUs = ts->getRealTimeUs() - mTimeSourceDeltaUs;
+ int64_t nowUs = estimateRealTimeUs(ts, systemTimeUs) - mTimeSourceDeltaUs;
- int64_t latenessUs = nowUs - timeUs;
+ latenessUs = nowUs - timeUs;
ATRACE_INT("Video Lateness (ms)", latenessUs / 1E3);
@@ -1942,9 +1954,9 @@ void AwesomePlayer::onVideoEvent() {
}
}
- if (latenessUs < -10000) {
- // We're more than 10ms early.
- postVideoEvent_l(10000);
+ if (latenessUs < -30000) {
+ // We're more than 30ms early, schedule at most 20 ms before time due
+ postVideoEvent_l(latenessUs < -60000 ? 30000 : -latenessUs - 20000);
return;
}
}
@@ -1958,6 +1970,8 @@ void AwesomePlayer::onVideoEvent() {
if (mVideoRenderer != NULL) {
mSinceLastDropped++;
+ mVideoBuffer->meta_data()->setInt64(kKeyTime, looperTimeUs - latenessUs);
+
mVideoRenderer->render(mVideoBuffer);
if (!mVideoRenderingStarted) {
mVideoRenderingStarted = true;
@@ -2007,14 +2021,26 @@ void AwesomePlayer::onVideoEvent() {
int64_t nextTimeUs;
CHECK(mVideoBuffer->meta_data()->findInt64(kKeyTime, &nextTimeUs));
- int64_t delayUs = nextTimeUs - ts->getRealTimeUs() + mTimeSourceDeltaUs;
- postVideoEvent_l(delayUs > 10000 ? 10000 : delayUs < 0 ? 0 : delayUs);
+ systemTimeUs = mSystemTimeSource.getRealTimeUs();
+ int64_t delayUs = nextTimeUs - estimateRealTimeUs(ts, systemTimeUs) + mTimeSourceDeltaUs;
+ ATRACE_INT("Frame delta (ms)", (nextTimeUs - timeUs) / 1E3);
+ ALOGV("next frame in %" PRId64, delayUs);
+ // try to schedule 30ms before time due
+ postVideoEvent_l(delayUs > 60000 ? 30000 : (delayUs < 30000 ? 0 : delayUs - 30000));
return;
}
postVideoEvent_l();
}
+int64_t AwesomePlayer::estimateRealTimeUs(TimeSource *ts, int64_t systemTimeUs) {
+ if (ts == &mSystemTimeSource) {
+ return systemTimeUs;
+ } else {
+ return (int64_t)mClockEstimator->estimate(systemTimeUs, ts->getRealTimeUs());
+ }
+}
+
void AwesomePlayer::postVideoEvent_l(int64_t delayUs) {
ATRACE_CALL();
@@ -2096,7 +2122,10 @@ void AwesomePlayer::onCheckAudioStatus() {
mSeekNotificationSent = true;
}
- mSeeking = NO_SEEK;
+ if (mVideoSource == NULL) {
+ // For video the mSeeking flag is always reset in finishSeekIfNecessary
+ mSeeking = NO_SEEK;
+ }
notifyIfMediaStarted_l();
}
@@ -2292,8 +2321,8 @@ status_t AwesomePlayer::finishSetDataSource_l() {
sniffedMIME = tmp.string();
if (meta == NULL
- || !meta->findInt64(
- "meta-data-size", &metaDataSize)) {
+ || !meta->findInt64("meta-data-size",
+ reinterpret_cast<int64_t*>(&metaDataSize))) {
metaDataSize = kHighWaterMarkBytes;
}
@@ -2580,12 +2609,12 @@ status_t AwesomePlayer::getTrackInfo(Parcel *reply) const {
status_t AwesomePlayer::selectAudioTrack_l(
const sp<MediaSource>& source, size_t trackIndex) {
- ALOGI("selectAudioTrack_l: trackIndex=%d, mFlags=0x%x", trackIndex, mFlags);
+ ALOGI("selectAudioTrack_l: trackIndex=%zu, mFlags=0x%x", trackIndex, mFlags);
{
Mutex::Autolock autoLock(mStatsLock);
if ((ssize_t)trackIndex == mActiveAudioTrackIndex) {
- ALOGI("Track %d is active. Does nothing.", trackIndex);
+ ALOGI("Track %zu is active. Does nothing.", trackIndex);
return OK;
}
//mStats.mFlags = mFlags;
@@ -2658,7 +2687,7 @@ status_t AwesomePlayer::selectTrack(size_t trackIndex, bool select) {
trackCount += mTextDriver->countExternalTracks();
}
if (trackIndex >= trackCount) {
- ALOGE("Track index (%d) is out of range [0, %d)", trackIndex, trackCount);
+ ALOGE("Track index (%zu) is out of range [0, %zu)", trackIndex, trackCount);
return ERROR_OUT_OF_RANGE;
}
@@ -2670,14 +2699,14 @@ status_t AwesomePlayer::selectTrack(size_t trackIndex, bool select) {
isAudioTrack = !strncasecmp(mime, "audio/", 6);
if (!isAudioTrack && strcasecmp(mime, MEDIA_MIMETYPE_TEXT_3GPP) != 0) {
- ALOGE("Track %d is not either audio or timed text", trackIndex);
+ ALOGE("Track %zu is not either audio or timed text", trackIndex);
return ERROR_UNSUPPORTED;
}
}
if (isAudioTrack) {
if (!select) {
- ALOGE("Deselect an audio track (%d) is not supported", trackIndex);
+ ALOGE("Deselect an audio track (%zu) is not supported", trackIndex);
return ERROR_UNSUPPORTED;
}
return selectAudioTrack_l(mExtractor->getTrack(trackIndex), trackIndex);
@@ -2800,7 +2829,8 @@ bool AwesomePlayer::isStreamingHTTP() const {
return mCachedSource != NULL || mWVMExtractor != NULL;
}
-status_t AwesomePlayer::dump(int fd, const Vector<String16> &args) const {
+status_t AwesomePlayer::dump(
+ int fd, const Vector<String16> & /* args */) const {
Mutex::Autolock autoLock(mStatsLock);
FILE *out = fdopen(dup(fd), "w");
@@ -2815,7 +2845,7 @@ status_t AwesomePlayer::dump(int fd, const Vector<String16> &args) const {
fprintf(out, ", flags(0x%08x)", mStats.mFlags);
if (mStats.mBitrate >= 0) {
- fprintf(out, ", bitrate(%lld bps)", mStats.mBitrate);
+ fprintf(out, ", bitrate(%" PRId64 " bps)", mStats.mBitrate);
}
fprintf(out, "\n");
@@ -2823,7 +2853,7 @@ status_t AwesomePlayer::dump(int fd, const Vector<String16> &args) const {
for (size_t i = 0; i < mStats.mTracks.size(); ++i) {
const TrackStat &stat = mStats.mTracks.itemAt(i);
- fprintf(out, " Track %d\n", i + 1);
+ fprintf(out, " Track %zu\n", i + 1);
fprintf(out, " MIME(%s)", stat.mMIME.string());
if (!stat.mDecoderName.isEmpty()) {
@@ -2835,8 +2865,8 @@ status_t AwesomePlayer::dump(int fd, const Vector<String16> &args) const {
if ((ssize_t)i == mStats.mVideoTrackIndex) {
fprintf(out,
" videoDimensions(%d x %d), "
- "numVideoFramesDecoded(%lld), "
- "numVideoFramesDropped(%lld)\n",
+ "numVideoFramesDecoded(%" PRId64 "), "
+ "numVideoFramesDropped(%" PRId64 ")\n",
mStats.mVideoWidth,
mStats.mVideoHeight,
mStats.mNumVideoFramesDecoded,
diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp
index 3017fe7..5b41f30 100644
--- a/media/libstagefright/CameraSource.cpp
+++ b/media/libstagefright/CameraSource.cpp
@@ -67,7 +67,7 @@ void CameraSourceListener::notify(int32_t msgType, int32_t ext1, int32_t ext2) {
}
void CameraSourceListener::postData(int32_t msgType, const sp<IMemory> &dataPtr,
- camera_frame_metadata_t *metadata) {
+ camera_frame_metadata_t * /* metadata */) {
ALOGV("postData(%d, ptr:%p, size:%d)",
msgType, dataPtr->pointer(), dataPtr->size());
diff --git a/media/libstagefright/CameraSourceTimeLapse.cpp b/media/libstagefright/CameraSourceTimeLapse.cpp
index 5772316..591daac 100644
--- a/media/libstagefright/CameraSourceTimeLapse.cpp
+++ b/media/libstagefright/CameraSourceTimeLapse.cpp
@@ -134,7 +134,7 @@ bool CameraSourceTimeLapse::trySettingVideoSize(
}
bool videoSizeSupported = false;
- for (uint32_t i = 0; i < supportedSizes.size(); ++i) {
+ for (size_t i = 0; i < supportedSizes.size(); ++i) {
int32_t pictureWidth = supportedSizes[i].width;
int32_t pictureHeight = supportedSizes[i].height;
@@ -231,7 +231,7 @@ sp<IMemory> CameraSourceTimeLapse::createIMemoryCopy(
return newMemory;
}
-bool CameraSourceTimeLapse::skipCurrentFrame(int64_t timestampUs) {
+bool CameraSourceTimeLapse::skipCurrentFrame(int64_t /* timestampUs */) {
ALOGV("skipCurrentFrame");
if (mSkipCurrentFrame) {
mSkipCurrentFrame = false;
diff --git a/media/libstagefright/ClockEstimator.cpp b/media/libstagefright/ClockEstimator.cpp
new file mode 100644
index 0000000..34d1e42
--- /dev/null
+++ b/media/libstagefright/ClockEstimator.cpp
@@ -0,0 +1,177 @@
+/*
+**
+** Copyright 2014, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "ClockEstimator"
+#include <utils/Log.h>
+
+#include <math.h>
+#include <media/stagefright/ClockEstimator.h>
+
+#include <media/stagefright/foundation/ADebug.h>
+
+namespace android {
+
+WindowedLinearFitEstimator::WindowedLinearFitEstimator(
+ size_t headLength, double headFactor, size_t mainLength, double tailFactor)
+ : mHeadFactorInv(1. / headFactor),
+ mTailFactor(tailFactor),
+ mHistoryLength(mainLength + headLength),
+ mHeadLength(headLength) {
+ reset();
+ mXHistory.resize(mHistoryLength);
+ mYHistory.resize(mHistoryLength);
+ mFirstWeight = pow(headFactor, mHeadLength);
+}
+
+WindowedLinearFitEstimator::LinearFit::LinearFit() {
+ reset();
+}
+
+void WindowedLinearFitEstimator::LinearFit::reset() {
+ mX = mXX = mY = mYY = mXY = mW = 0.;
+}
+
+double WindowedLinearFitEstimator::LinearFit::size() const {
+ double s = mW * mW + mX * mX + mY * mY + mXX * mXX + mXY * mXY + mYY * mYY;
+ if (s > 1e72) {
+ // 1e72 corresponds to clock monotonic time of about 8 years
+ ALOGW("estimator is overflowing: w=%g x=%g y=%g xx=%g xy=%g yy=%g",
+ mW, mX, mY, mXX, mXY, mYY);
+ }
+ return s;
+}
+
+void WindowedLinearFitEstimator::LinearFit::add(double x, double y, double w) {
+ mW += w;
+ mX += w * x;
+ mY += w * y;
+ mXX += w * x * x;
+ mXY += w * x * y;
+ mYY += w * y * y;
+}
+
+void WindowedLinearFitEstimator::LinearFit::combine(const LinearFit &lf) {
+ mW += lf.mW;
+ mX += lf.mX;
+ mY += lf.mY;
+ mXX += lf.mXX;
+ mXY += lf.mXY;
+ mYY += lf.mYY;
+}
+
+void WindowedLinearFitEstimator::LinearFit::scale(double w) {
+ mW *= w;
+ mX *= w;
+ mY *= w;
+ mXX *= w;
+ mXY *= w;
+ mYY *= w;
+}
+
+double WindowedLinearFitEstimator::LinearFit::interpolate(double x) {
+ double div = mW * mXX - mX * mX;
+ if (fabs(div) < 1e-5 * mW * mW) {
+ // this only should happen on the first value
+ return x;
+ // assuming a = 1, we could also return x + (mY - mX) / mW;
+ }
+ double a_div = (mW * mXY - mX * mY);
+ double b_div = (mXX * mY - mX * mXY);
+ ALOGV("a=%.4g b=%.4g in=%g out=%g",
+ a_div / div, b_div / div, x, (a_div * x + b_div) / div);
+ return (a_div * x + b_div) / div;
+}
+
+double WindowedLinearFitEstimator::estimate(double x, double y) {
+ /*
+ * TODO: We could update the head by adding the new sample to it
+ * and amplifying it, but this approach can lead to unbounded
+ * error. Instead, we recalculate the head at each step, which
+ * is computationally more expensive. We could balance the two
+ * methods by recalculating just before the error becomes
+ * significant.
+ */
+ const bool update_head = false;
+ if (update_head) {
+ // add new sample to the head
+ mHead.scale(mHeadFactorInv); // amplify head
+ mHead.add(x, y, mFirstWeight);
+ }
+
+ /*
+ * TRICKY: place elements into the circular buffer at decreasing
+ * indices, so that we can access past elements by addition
+ * (thereby avoiding potentially negative indices.)
+ */
+ if (mNumSamples >= mHeadLength) {
+ // move last head sample from head to the main window
+ size_t lastHeadIx = (mSampleIx + mHeadLength) % mHistoryLength;
+ if (update_head) {
+ mHead.add(mXHistory[lastHeadIx], mYHistory[lastHeadIx], -1.); // remove
+ }
+ mMain.add(mXHistory[lastHeadIx], mYHistory[lastHeadIx], 1.);
+ if (mNumSamples >= mHistoryLength) {
+ // move last main sample from main window to tail
+ mMain.add(mXHistory[mSampleIx], mYHistory[mSampleIx], -1.); // remove
+ mTail.add(mXHistory[mSampleIx], mYHistory[mSampleIx], 1.);
+ mTail.scale(mTailFactor); // attenuate tail
+ }
+ }
+
+ mXHistory.editItemAt(mSampleIx) = x;
+ mYHistory.editItemAt(mSampleIx) = y;
+ if (mNumSamples < mHistoryLength) {
+ ++mNumSamples;
+ }
+
+ // recalculate head unless we were using the update method
+ if (!update_head) {
+ mHead.reset();
+ double w = mFirstWeight;
+ for (size_t headIx = 0; headIx < mHeadLength && headIx < mNumSamples; ++headIx) {
+ size_t ix = (mSampleIx + headIx) % mHistoryLength;
+ mHead.add(mXHistory[ix], mYHistory[ix], w);
+ w *= mHeadFactorInv;
+ }
+ }
+
+ if (mSampleIx > 0) {
+ --mSampleIx;
+ } else {
+ mSampleIx = mHistoryLength - 1;
+ }
+
+ // return estimation result
+ LinearFit total;
+ total.combine(mHead);
+ total.combine(mMain);
+ total.combine(mTail);
+ return total.interpolate(x);
+}
+
+void WindowedLinearFitEstimator::reset() {
+ mHead.reset();
+ mMain.reset();
+ mTail.reset();
+ mNumSamples = 0;
+ mSampleIx = mHistoryLength - 1;
+}
+
+}; // namespace android
+
+
diff --git a/media/libstagefright/FLACExtractor.cpp b/media/libstagefright/FLACExtractor.cpp
index 098fcf9..fa7251c 100644
--- a/media/libstagefright/FLACExtractor.cpp
+++ b/media/libstagefright/FLACExtractor.cpp
@@ -208,55 +208,55 @@ private:
// with the same parameter list, but discard redundant information.
FLAC__StreamDecoderReadStatus FLACParser::read_callback(
- const FLAC__StreamDecoder *decoder, FLAC__byte buffer[],
+ const FLAC__StreamDecoder * /* decoder */, FLAC__byte buffer[],
size_t *bytes, void *client_data)
{
return ((FLACParser *) client_data)->readCallback(buffer, bytes);
}
FLAC__StreamDecoderSeekStatus FLACParser::seek_callback(
- const FLAC__StreamDecoder *decoder,
+ const FLAC__StreamDecoder * /* decoder */,
FLAC__uint64 absolute_byte_offset, void *client_data)
{
return ((FLACParser *) client_data)->seekCallback(absolute_byte_offset);
}
FLAC__StreamDecoderTellStatus FLACParser::tell_callback(
- const FLAC__StreamDecoder *decoder,
+ const FLAC__StreamDecoder * /* decoder */,
FLAC__uint64 *absolute_byte_offset, void *client_data)
{
return ((FLACParser *) client_data)->tellCallback(absolute_byte_offset);
}
FLAC__StreamDecoderLengthStatus FLACParser::length_callback(
- const FLAC__StreamDecoder *decoder,
+ const FLAC__StreamDecoder * /* decoder */,
FLAC__uint64 *stream_length, void *client_data)
{
return ((FLACParser *) client_data)->lengthCallback(stream_length);
}
FLAC__bool FLACParser::eof_callback(
- const FLAC__StreamDecoder *decoder, void *client_data)
+ const FLAC__StreamDecoder * /* decoder */, void *client_data)
{
return ((FLACParser *) client_data)->eofCallback();
}
FLAC__StreamDecoderWriteStatus FLACParser::write_callback(
- const FLAC__StreamDecoder *decoder, const FLAC__Frame *frame,
+ const FLAC__StreamDecoder * /* decoder */, const FLAC__Frame *frame,
const FLAC__int32 * const buffer[], void *client_data)
{
return ((FLACParser *) client_data)->writeCallback(frame, buffer);
}
void FLACParser::metadata_callback(
- const FLAC__StreamDecoder *decoder,
+ const FLAC__StreamDecoder * /* decoder */,
const FLAC__StreamMetadata *metadata, void *client_data)
{
((FLACParser *) client_data)->metadataCallback(metadata);
}
void FLACParser::error_callback(
- const FLAC__StreamDecoder *decoder,
+ const FLAC__StreamDecoder * /* decoder */,
FLAC__StreamDecoderErrorStatus status, void *client_data)
{
((FLACParser *) client_data)->errorCallback(status);
@@ -380,15 +380,21 @@ void FLACParser::errorCallback(FLAC__StreamDecoderErrorStatus status)
// Copy samples from FLAC native 32-bit non-interleaved to 16-bit interleaved.
// These are candidates for optimization if needed.
-static void copyMono8(short *dst, const int *const *src, unsigned nSamples, unsigned nChannels)
-{
+static void copyMono8(
+ short *dst,
+ const int *const *src,
+ unsigned nSamples,
+ unsigned /* nChannels */) {
for (unsigned i = 0; i < nSamples; ++i) {
*dst++ = src[0][i] << 8;
}
}
-static void copyStereo8(short *dst, const int *const *src, unsigned nSamples, unsigned nChannels)
-{
+static void copyStereo8(
+ short *dst,
+ const int *const *src,
+ unsigned nSamples,
+ unsigned /* nChannels */) {
for (unsigned i = 0; i < nSamples; ++i) {
*dst++ = src[0][i] << 8;
*dst++ = src[1][i] << 8;
@@ -404,15 +410,21 @@ static void copyMultiCh8(short *dst, const int *const *src, unsigned nSamples, u
}
}
-static void copyMono16(short *dst, const int *const *src, unsigned nSamples, unsigned nChannels)
-{
+static void copyMono16(
+ short *dst,
+ const int *const *src,
+ unsigned nSamples,
+ unsigned /* nChannels */) {
for (unsigned i = 0; i < nSamples; ++i) {
*dst++ = src[0][i];
}
}
-static void copyStereo16(short *dst, const int *const *src, unsigned nSamples, unsigned nChannels)
-{
+static void copyStereo16(
+ short *dst,
+ const int *const *src,
+ unsigned nSamples,
+ unsigned /* nChannels */) {
for (unsigned i = 0; i < nSamples; ++i) {
*dst++ = src[0][i];
*dst++ = src[1][i];
@@ -430,15 +442,21 @@ static void copyMultiCh16(short *dst, const int *const *src, unsigned nSamples,
// 24-bit versions should do dithering or noise-shaping, here or in AudioFlinger
-static void copyMono24(short *dst, const int *const *src, unsigned nSamples, unsigned nChannels)
-{
+static void copyMono24(
+ short *dst,
+ const int *const *src,
+ unsigned nSamples,
+ unsigned /* nChannels */) {
for (unsigned i = 0; i < nSamples; ++i) {
*dst++ = src[0][i] >> 8;
}
}
-static void copyStereo24(short *dst, const int *const *src, unsigned nSamples, unsigned nChannels)
-{
+static void copyStereo24(
+ short *dst,
+ const int *const *src,
+ unsigned nSamples,
+ unsigned /* nChannels */) {
for (unsigned i = 0; i < nSamples; ++i) {
*dst++ = src[0][i] >> 8;
*dst++ = src[1][i] >> 8;
@@ -454,8 +472,11 @@ static void copyMultiCh24(short *dst, const int *const *src, unsigned nSamples,
}
}
-static void copyTrespass(short *dst, const int *const *src, unsigned nSamples, unsigned nChannels)
-{
+static void copyTrespass(
+ short * /* dst */,
+ const int *const * /* src */,
+ unsigned /* nSamples */,
+ unsigned /* nChannels */) {
TRESPASS();
}
@@ -700,7 +721,7 @@ FLACSource::~FLACSource()
}
}
-status_t FLACSource::start(MetaData *params)
+status_t FLACSource::start(MetaData * /* params */)
{
ALOGV("FLACSource::start");
@@ -792,8 +813,7 @@ sp<MediaSource> FLACExtractor::getTrack(size_t index)
}
sp<MetaData> FLACExtractor::getTrackMetaData(
- size_t index, uint32_t flags)
-{
+ size_t index, uint32_t /* flags */) {
if (mInitCheck != OK || index > 0) {
return NULL;
}
diff --git a/media/libstagefright/MP3Extractor.cpp b/media/libstagefright/MP3Extractor.cpp
index 380dab4..4a63152 100644
--- a/media/libstagefright/MP3Extractor.cpp
+++ b/media/libstagefright/MP3Extractor.cpp
@@ -398,7 +398,8 @@ sp<MediaSource> MP3Extractor::getTrack(size_t index) {
mSeeker);
}
-sp<MetaData> MP3Extractor::getTrackMetaData(size_t index, uint32_t flags) {
+sp<MetaData> MP3Extractor::getTrackMetaData(
+ size_t index, uint32_t /* flags */) {
if (mInitCheck != OK || index != 0) {
return NULL;
}
diff --git a/media/libstagefright/MPEG2TSWriter.cpp b/media/libstagefright/MPEG2TSWriter.cpp
index c9ed5bb..78c12e1 100644
--- a/media/libstagefright/MPEG2TSWriter.cpp
+++ b/media/libstagefright/MPEG2TSWriter.cpp
@@ -555,7 +555,7 @@ status_t MPEG2TSWriter::addSource(const sp<MediaSource> &source) {
return OK;
}
-status_t MPEG2TSWriter::start(MetaData *param) {
+status_t MPEG2TSWriter::start(MetaData * /* param */) {
CHECK(!mStarted);
mStarted = true;
@@ -596,7 +596,8 @@ bool MPEG2TSWriter::reachedEOS() {
return !mStarted || (mNumSourcesDone == mSources.size() ? true : false);
}
-status_t MPEG2TSWriter::dump(int fd, const Vector<String16> &args) {
+status_t MPEG2TSWriter::dump(
+ int /* fd */, const Vector<String16> & /* args */) {
return OK;
}
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index 9b36b6a..7d3a838 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -39,6 +39,7 @@
#include <utils/String8.h>
#include <byteswap.h>
+#include "include/ID3.h"
namespace android {
@@ -259,7 +260,7 @@ static void hexdump(const void *_data, size_t size) {
const uint8_t *data = (const uint8_t *)_data;
size_t offset = 0;
while (offset < size) {
- printf("0x%04x ", offset);
+ printf("0x%04zx ", offset);
size_t n = size - offset;
if (n > 16) {
@@ -570,7 +571,8 @@ static int32_t readSize(off64_t offset,
return size;
}
-status_t MPEG4Extractor::parseDrmSINF(off64_t *offset, off64_t data_offset) {
+status_t MPEG4Extractor::parseDrmSINF(
+ off64_t * /* offset */, off64_t data_offset) {
uint8_t updateIdTag;
if (mDataSource->readAt(data_offset, &updateIdTag, 1) < 1) {
return ERROR_IO;
@@ -1787,6 +1789,18 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
break;
}
+ case FOURCC('I', 'D', '3', '2'):
+ {
+ if (chunk_data_size < 6) {
+ return ERROR_MALFORMED;
+ }
+
+ parseID3v2MetaData(data_offset + 6);
+
+ *offset += chunk_size;
+ break;
+ }
+
case FOURCC('-', '-', '-', '-'):
{
mLastCommentMean.clear();
@@ -2167,7 +2181,7 @@ status_t MPEG4Extractor::parseITunesMetaData(off64_t offset, size_t size) {
break;
}
- if (size >= 8 && metadataKey) {
+ if (size >= 8 && metadataKey && !mFileMetaData->hasData(metadataKey)) {
if (metadataKey == kKeyAlbumArt) {
mFileMetaData->setData(
kKeyAlbumArt, MetaData::TYPE_NONE,
@@ -2316,6 +2330,62 @@ status_t MPEG4Extractor::parse3GPPMetaData(off64_t offset, size_t size, int dept
return OK;
}
+void MPEG4Extractor::parseID3v2MetaData(off64_t offset) {
+ ID3 id3(mDataSource, true /* ignorev1 */, offset);
+
+ if (id3.isValid()) {
+ struct Map {
+ int key;
+ const char *tag1;
+ const char *tag2;
+ };
+ static const Map kMap[] = {
+ { kKeyAlbum, "TALB", "TAL" },
+ { kKeyArtist, "TPE1", "TP1" },
+ { kKeyAlbumArtist, "TPE2", "TP2" },
+ { kKeyComposer, "TCOM", "TCM" },
+ { kKeyGenre, "TCON", "TCO" },
+ { kKeyTitle, "TIT2", "TT2" },
+ { kKeyYear, "TYE", "TYER" },
+ { kKeyAuthor, "TXT", "TEXT" },
+ { kKeyCDTrackNumber, "TRK", "TRCK" },
+ { kKeyDiscNumber, "TPA", "TPOS" },
+ { kKeyCompilation, "TCP", "TCMP" },
+ };
+ static const size_t kNumMapEntries = sizeof(kMap) / sizeof(kMap[0]);
+
+ for (size_t i = 0; i < kNumMapEntries; ++i) {
+ if (!mFileMetaData->hasData(kMap[i].key)) {
+ ID3::Iterator *it = new ID3::Iterator(id3, kMap[i].tag1);
+ if (it->done()) {
+ delete it;
+ it = new ID3::Iterator(id3, kMap[i].tag2);
+ }
+
+ if (it->done()) {
+ delete it;
+ continue;
+ }
+
+ String8 s;
+ it->getString(&s);
+ delete it;
+
+ mFileMetaData->setCString(kMap[i].key, s);
+ }
+ }
+
+ size_t dataSize;
+ String8 mime;
+ const void *data = id3.getAlbumArt(&dataSize, &mime);
+
+ if (data) {
+ mFileMetaData->setData(kKeyAlbumArt, MetaData::TYPE_NONE, data, dataSize);
+ mFileMetaData->setCString(kKeyAlbumArtMIME, mime.string());
+ }
+ }
+}
+
sp<MediaSource> MPEG4Extractor::getTrack(size_t index) {
status_t err;
if ((err = readMetaData()) != OK) {
@@ -2419,6 +2489,11 @@ status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio(
return ERROR_MALFORMED;
}
+ static uint32_t kSamplingRate[] = {
+ 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
+ 16000, 12000, 11025, 8000, 7350
+ };
+
ABitReader br(csd, csd_size);
uint32_t objectType = br.getBits(5);
@@ -2426,6 +2501,9 @@ status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio(
objectType = 32 + br.getBits(6);
}
+ //keep AOT type
+ mLastTrack->meta->setInt32(kKeyAACAOT, objectType);
+
uint32_t freqIndex = br.getBits(4);
int32_t sampleRate = 0;
@@ -2438,29 +2516,30 @@ status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio(
numChannels = br.getBits(4);
} else {
numChannels = br.getBits(4);
- if (objectType == 5) {
- // SBR specific config per 14496-3 table 1.13
- freqIndex = br.getBits(4);
- if (freqIndex == 15) {
- if (csd_size < 8) {
- return ERROR_MALFORMED;
- }
- sampleRate = br.getBits(24);
- }
+
+ if (freqIndex == 13 || freqIndex == 14) {
+ return ERROR_MALFORMED;
}
- if (sampleRate == 0) {
- static uint32_t kSamplingRate[] = {
- 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050,
- 16000, 12000, 11025, 8000, 7350
- };
+ sampleRate = kSamplingRate[freqIndex];
+ }
- if (freqIndex == 13 || freqIndex == 14) {
+ if (objectType == 5 || objectType == 29) { // SBR specific config per 14496-3 table 1.13
+ uint32_t extFreqIndex = br.getBits(4);
+ int32_t extSampleRate;
+ if (extFreqIndex == 15) {
+ if (csd_size < 8) {
return ERROR_MALFORMED;
}
-
- sampleRate = kSamplingRate[freqIndex];
+ extSampleRate = br.getBits(24);
+ } else {
+ if (extFreqIndex == 13 || extFreqIndex == 14) {
+ return ERROR_MALFORMED;
+ }
+ extSampleRate = kSamplingRate[extFreqIndex];
}
+ //TODO: save the extension sampling rate value in meta data =>
+ // mLastTrack->meta->setInt32(kKeyExtSampleRate, extSampleRate);
}
if (numChannels == 0) {
@@ -2724,7 +2803,8 @@ status_t MPEG4Source::parseChunk(off64_t *offset) {
return OK;
}
-status_t MPEG4Source::parseSampleAuxiliaryInformationSizes(off64_t offset, off64_t size) {
+status_t MPEG4Source::parseSampleAuxiliaryInformationSizes(
+ off64_t offset, off64_t /* size */) {
ALOGV("parseSampleAuxiliaryInformationSizes");
// 14496-12 8.7.12
uint8_t version;
@@ -2786,7 +2866,8 @@ status_t MPEG4Source::parseSampleAuxiliaryInformationSizes(off64_t offset, off64
return OK;
}
-status_t MPEG4Source::parseSampleAuxiliaryInformationOffsets(off64_t offset, off64_t size) {
+status_t MPEG4Source::parseSampleAuxiliaryInformationOffsets(
+ off64_t offset, off64_t /* size */) {
ALOGV("parseSampleAuxiliaryInformationOffsets");
// 14496-12 8.7.13
uint8_t version;
@@ -3203,7 +3284,7 @@ status_t MPEG4Source::read(
uint32_t sampleIndex;
status_t err = mSampleTable->findSampleAtTime(
- seekTimeUs * mTimescale / 1000000,
+ seekTimeUs, 1000000, mTimescale,
&sampleIndex, findFlags);
if (mode == ReadOptions::SEEK_CLOSEST) {
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index a0f17b5..58a4487 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -16,6 +16,7 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "MPEG4Writer"
+#include <inttypes.h>
#include <utils/Log.h>
#include <arpa/inet.h>
@@ -43,7 +44,9 @@
namespace android {
static const int64_t kMinStreamableFileSizeInBytes = 5 * 1024 * 1024;
-static const int64_t kMax32BitFileSize = 0x007fffffffLL;
+static const int64_t kMax32BitFileSize = 0x00ffffffffLL; // 2^32-1 : max FAT32
+ // filesystem file size
+ // used by most SD cards
static const uint8_t kNalUnitTypeSeqParamSet = 0x07;
static const uint8_t kNalUnitTypePicParamSet = 0x08;
static const int64_t kInitialDelayTimeUs = 700000LL;
@@ -406,7 +409,7 @@ status_t MPEG4Writer::dump(
}
status_t MPEG4Writer::Track::dump(
- int fd, const Vector<String16>& args) const {
+ int fd, const Vector<String16>& /* args */) const {
const size_t SIZE = 256;
char buffer[SIZE];
String8 result;
@@ -417,7 +420,7 @@ status_t MPEG4Writer::Track::dump(
result.append(buffer);
snprintf(buffer, SIZE, " frames encoded : %d\n", mStszTableEntries->count());
result.append(buffer);
- snprintf(buffer, SIZE, " duration encoded : %lld us\n", mTrackDurationUs);
+ snprintf(buffer, SIZE, " duration encoded : %" PRId64 " us\n", mTrackDurationUs);
result.append(buffer);
::write(fd, result.string(), result.size());
return OK;
@@ -860,11 +863,11 @@ status_t MPEG4Writer::reset() {
// Fix up the size of the 'mdat' chunk.
if (mUse32BitOffset) {
lseek64(mFd, mMdatOffset, SEEK_SET);
- int32_t size = htonl(static_cast<int32_t>(mOffset - mMdatOffset));
+ uint32_t size = htonl(static_cast<uint32_t>(mOffset - mMdatOffset));
::write(mFd, &size, 4);
} else {
lseek64(mFd, mMdatOffset + 8, SEEK_SET);
- int64_t size = mOffset - mMdatOffset;
+ uint64_t size = mOffset - mMdatOffset;
size = hton64(size);
::write(mFd, &size, 8);
}
@@ -1404,7 +1407,7 @@ void MPEG4Writer::Track::addOneSttsTableEntry(
size_t sampleCount, int32_t duration) {
if (duration == 0) {
- ALOGW("0-duration samples found: %d", sampleCount);
+ ALOGW("0-duration samples found: %zu", sampleCount);
}
mSttsTableEntries->add(htonl(sampleCount));
mSttsTableEntries->add(htonl(duration));
@@ -1584,7 +1587,7 @@ void MPEG4Writer::writeAllChunks() {
sendSessionSummary();
mChunkInfos.clear();
- ALOGD("%d chunks are written in the last batch", outstandingChunks);
+ ALOGD("%zu chunks are written in the last batch", outstandingChunks);
}
bool MPEG4Writer::findChunkToWrite(Chunk *chunk) {
@@ -1774,7 +1777,7 @@ status_t MPEG4Writer::Track::stop() {
void *dummy;
pthread_join(mThread, &dummy);
- status_t err = (status_t) dummy;
+ status_t err = static_cast<status_t>(reinterpret_cast<uintptr_t>(dummy));
ALOGD("Stopping %s track source", mIsAudio? "Audio": "Video");
{
@@ -1797,7 +1800,7 @@ void *MPEG4Writer::Track::ThreadWrapper(void *me) {
Track *track = static_cast<Track *>(me);
status_t err = track->threadEntry();
- return (void *) err;
+ return (void *)(uintptr_t)err;
}
static void getNalUnitType(uint8_t byte, uint8_t* type) {
@@ -1869,7 +1872,7 @@ status_t MPEG4Writer::Track::copyAVCCodecSpecificData(
// 2 bytes for each of the parameter set length field
// plus the 7 bytes for the header
if (size < 4 + 7) {
- ALOGE("Codec specific data length too short: %d", size);
+ ALOGE("Codec specific data length too short: %zu", size);
return ERROR_MALFORMED;
}
@@ -1938,7 +1941,7 @@ status_t MPEG4Writer::Track::parseAVCCodecSpecificData(
}
if (nSeqParamSets > 0x1F) {
- ALOGE("Too many seq parameter sets (%d) found", nSeqParamSets);
+ ALOGE("Too many seq parameter sets (%zu) found", nSeqParamSets);
return ERROR_MALFORMED;
}
}
@@ -1951,7 +1954,7 @@ status_t MPEG4Writer::Track::parseAVCCodecSpecificData(
return ERROR_MALFORMED;
}
if (nPicParamSets > 0xFF) {
- ALOGE("Too many pic parameter sets (%d) found", nPicParamSets);
+ ALOGE("Too many pic parameter sets (%zd) found", nPicParamSets);
return ERROR_MALFORMED;
}
}
@@ -1981,7 +1984,7 @@ status_t MPEG4Writer::Track::makeAVCCodecSpecificData(
}
if (size < 4) {
- ALOGE("Codec specific data length too short: %d", size);
+ ALOGE("Codec specific data length too short: %zu", size);
return ERROR_MALFORMED;
}
diff --git a/media/libstagefright/MediaAdapter.cpp b/media/libstagefright/MediaAdapter.cpp
index 2484212..d680e0c 100644
--- a/media/libstagefright/MediaAdapter.cpp
+++ b/media/libstagefright/MediaAdapter.cpp
@@ -36,7 +36,7 @@ MediaAdapter::~MediaAdapter() {
CHECK(mCurrentMediaBuffer == NULL);
}
-status_t MediaAdapter::start(MetaData *params) {
+status_t MediaAdapter::start(MetaData * /* params */) {
Mutex::Autolock autoLock(mAdapterLock);
if (!mStarted) {
mStarted = true;
@@ -75,7 +75,7 @@ void MediaAdapter::signalBufferReturned(MediaBuffer *buffer) {
}
status_t MediaAdapter::read(
- MediaBuffer **buffer, const ReadOptions *options) {
+ MediaBuffer **buffer, const ReadOptions * /* options */) {
Mutex::Autolock autoLock(mAdapterLock);
if (!mStarted) {
ALOGV("Read before even started!");
diff --git a/media/libstagefright/MediaBuffer.cpp b/media/libstagefright/MediaBuffer.cpp
index 11b80bf..8af0880 100644
--- a/media/libstagefright/MediaBuffer.cpp
+++ b/media/libstagefright/MediaBuffer.cpp
@@ -27,7 +27,6 @@
#include <media/stagefright/MetaData.h>
#include <ui/GraphicBuffer.h>
-#include <sys/atomics.h>
namespace android {
@@ -92,7 +91,7 @@ void MediaBuffer::release() {
return;
}
- int prevCount = __atomic_dec(&mRefCount);
+ int prevCount = __sync_fetch_and_sub(&mRefCount, 1);
if (prevCount == 1) {
if (mObserver == NULL) {
delete this;
@@ -112,7 +111,7 @@ void MediaBuffer::claim() {
}
void MediaBuffer::add_ref() {
- (void) __atomic_inc(&mRefCount);
+ (void) __sync_fetch_and_add(&mRefCount, 1);
}
void *MediaBuffer::data() const {
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 8af1aaf..3cb4217 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -115,7 +115,7 @@ status_t MediaCodec::init(const char *name, bool nameIsType, bool encoder) {
if (codecIdx >= 0) {
Vector<AString> types;
if (mcl->getSupportedTypes(codecIdx, &types) == OK) {
- for (int i = 0; i < types.size(); i++) {
+ for (size_t i = 0; i < types.size(); i++) {
if (types[i].startsWith("video/")) {
needDedicatedLooper = true;
break;
@@ -1520,8 +1520,8 @@ size_t MediaCodec::updateBuffers(
int32_t portIndex, const sp<AMessage> &msg) {
CHECK(portIndex == kPortIndexInput || portIndex == kPortIndexOutput);
- void *bufferID;
- CHECK(msg->findPointer("buffer-id", &bufferID));
+ uint32_t bufferID;
+ CHECK(msg->findInt32("buffer-id", (int32_t*)&bufferID));
Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
@@ -1680,7 +1680,7 @@ status_t MediaCodec::onReleaseOutputBuffer(const sp<AMessage> &msg) {
return -EACCES;
}
- if (render && (info->mData == NULL || info->mData->size() != 0)) {
+ if (render && info->mData != NULL && info->mData->size() != 0) {
info->mNotify->setInt32("render", true);
if (mSoftRenderer != NULL) {
diff --git a/media/libstagefright/MetaData.cpp b/media/libstagefright/MetaData.cpp
index 7b60afc..74234a6 100644
--- a/media/libstagefright/MetaData.cpp
+++ b/media/libstagefright/MetaData.cpp
@@ -16,6 +16,7 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "MetaData"
+#include <inttypes.h>
#include <utils/Log.h>
#include <stdlib.h>
@@ -221,6 +222,16 @@ bool MetaData::findData(uint32_t key, uint32_t *type,
return true;
}
+bool MetaData::hasData(uint32_t key) const {
+ ssize_t i = mItems.indexOfKey(key);
+
+ if (i < 0) {
+ return false;
+ }
+
+ return true;
+}
+
MetaData::typed_data::typed_data()
: mType(0),
mSize(0) {
@@ -297,7 +308,7 @@ String8 MetaData::typed_data::asString() const {
const void *data = storage();
switch(mType) {
case TYPE_NONE:
- out = String8::format("no type, size %d)", mSize);
+ out = String8::format("no type, size %zu)", mSize);
break;
case TYPE_C_STRING:
out = String8::format("(char*) %s", (const char *)data);
@@ -306,7 +317,7 @@ String8 MetaData::typed_data::asString() const {
out = String8::format("(int32_t) %d", *(int32_t *)data);
break;
case TYPE_INT64:
- out = String8::format("(int64_t) %lld", *(int64_t *)data);
+ out = String8::format("(int64_t) %" PRId64, *(int64_t *)data);
break;
case TYPE_FLOAT:
out = String8::format("(float) %f", *(float *)data);
@@ -323,7 +334,7 @@ String8 MetaData::typed_data::asString() const {
}
default:
- out = String8::format("(unknown type %d, size %d)", mType, mSize);
+ out = String8::format("(unknown type %d, size %zu)", mType, mSize);
if (mSize <= 48) { // if it's less than three lines of hex data, dump it
AString foo;
hexdump(data, mSize, 0, &foo);
diff --git a/media/libstagefright/NuCachedSource2.cpp b/media/libstagefright/NuCachedSource2.cpp
index 05e599b..06e2d43 100644
--- a/media/libstagefright/NuCachedSource2.cpp
+++ b/media/libstagefright/NuCachedSource2.cpp
@@ -326,7 +326,7 @@ void NuCachedSource2::fetchInternal() {
mNumRetriesLeft = 0;
}
- ALOGE("source returned error %ld, %d retries left", n, mNumRetriesLeft);
+ ALOGE("source returned error %d, %d retries left", n, mNumRetriesLeft);
mCache->releasePage(page);
} else if (n == 0) {
ALOGI("ERROR_END_OF_STREAM");
@@ -641,7 +641,7 @@ void NuCachedSource2::updateCacheParamsFromString(const char *s) {
ssize_t lowwaterMarkKb, highwaterMarkKb;
int keepAliveSecs;
- if (sscanf(s, "%ld/%ld/%d",
+ if (sscanf(s, "%zd/%zd/%d",
&lowwaterMarkKb, &highwaterMarkKb, &keepAliveSecs) != 3) {
ALOGE("Failed to parse cache parameters from '%s'.", s);
return;
diff --git a/media/libstagefright/OMXClient.cpp b/media/libstagefright/OMXClient.cpp
index 9f9352d..72f2306 100644
--- a/media/libstagefright/OMXClient.cpp
+++ b/media/libstagefright/OMXClient.cpp
@@ -141,7 +141,7 @@ private:
const sp<IOMX> &getOMX(node_id node) const;
const sp<IOMX> &getOMX_l(node_id node) const;
- static bool IsSoftwareComponent(const char *name);
+ static bool CanLiveLocally(const char *name);
DISALLOW_EVIL_CONSTRUCTORS(MuxOMX);
};
@@ -164,7 +164,7 @@ bool MuxOMX::isLocalNode_l(node_id node) const {
}
// static
-bool MuxOMX::IsSoftwareComponent(const char *name) {
+bool MuxOMX::CanLiveLocally(const char *name) {
return !strncasecmp(name, "OMX.google.", 11);
}
@@ -197,7 +197,7 @@ status_t MuxOMX::allocateNode(
sp<IOMX> omx;
- if (IsSoftwareComponent(name)) {
+ if (CanLiveLocally(name)) {
if (mLocalOMX == NULL) {
mLocalOMX = new OMX;
}
@@ -382,7 +382,7 @@ status_t OMXClient::connect() {
mOMX = service->getOMX();
CHECK(mOMX.get() != NULL);
- if (!mOMX->livesLocally(NULL /* node */, getpid())) {
+ if (!mOMX->livesLocally(0 /* node */, getpid())) {
ALOGI("Using client-side OMX mux.");
mOMX = new MuxOMX(mOMX);
}
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 43736ad..d5550e8 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include <inttypes.h>
+
//#define LOG_NDEBUG 0
#define LOG_TAG "OMXCodec"
#include <utils/Log.h>
@@ -92,6 +94,7 @@ static sp<MediaSource> InstantiateSoftwareEncoder(
#define CODEC_LOGI(x, ...) ALOGI("[%s] "x, mComponentName, ##__VA_ARGS__)
#define CODEC_LOGV(x, ...) ALOGV("[%s] "x, mComponentName, ##__VA_ARGS__)
+#define CODEC_LOGW(x, ...) ALOGW("[%s] "x, mComponentName, ##__VA_ARGS__)
#define CODEC_LOGE(x, ...) ALOGE("[%s] "x, mComponentName, ##__VA_ARGS__)
struct OMXCodecObserver : public BnOMXObserver {
@@ -666,7 +669,7 @@ status_t OMXCodec::setVideoPortFormatType(
// CHECK_EQ(format.nIndex, index);
#if 1
- CODEC_LOGV("portIndex: %ld, index: %ld, eCompressionFormat=%d eColorFormat=%d",
+ CODEC_LOGV("portIndex: %u, index: %u, eCompressionFormat=%d eColorFormat=%d",
portIndex,
index, format.eCompressionFormat, format.eColorFormat);
#endif
@@ -768,7 +771,7 @@ status_t OMXCodec::isColorFormatSupported(
portFormat.nIndex = index;
if (index >= kMaxColorFormatSupported) {
- CODEC_LOGE("More than %ld color formats are supported???", index);
+ CODEC_LOGE("More than %u color formats are supported???", index);
break;
}
}
@@ -1777,21 +1780,42 @@ status_t OMXCodec::allocateOutputBuffersFromNativeWindow() {
strerror(-err), -err);
return err;
}
-
- // XXX: Is this the right logic to use? It's not clear to me what the OMX
- // buffer counts refer to - how do they account for the renderer holding on
- // to buffers?
- if (def.nBufferCountActual < def.nBufferCountMin + minUndequeuedBufs) {
- OMX_U32 newBufferCount = def.nBufferCountMin + minUndequeuedBufs;
+ // FIXME: assume that surface is controlled by app (native window
+ // returns the number for the case when surface is not controlled by app)
+ // FIXME2: This means that minUndeqeueudBufs can be 1 larger than reported
+ // For now, try to allocate 1 more buffer, but don't fail if unsuccessful
+
+ // Use conservative allocation while also trying to reduce starvation
+ //
+ // 1. allocate at least nBufferCountMin + minUndequeuedBuffers - that is the
+ // minimum needed for the consumer to be able to work
+ // 2. try to allocate two (2) additional buffers to reduce starvation from
+ // the consumer
+ // plus an extra buffer to account for incorrect minUndequeuedBufs
+ CODEC_LOGI("OMX-buffers: min=%u actual=%u undeq=%d+1",
+ def.nBufferCountMin, def.nBufferCountActual, minUndequeuedBufs);
+
+ for (OMX_U32 extraBuffers = 2 + 1; /* condition inside loop */; extraBuffers--) {
+ OMX_U32 newBufferCount =
+ def.nBufferCountMin + minUndequeuedBufs + extraBuffers;
def.nBufferCountActual = newBufferCount;
err = mOMX->setParameter(
mNode, OMX_IndexParamPortDefinition, &def, sizeof(def));
- if (err != OK) {
- CODEC_LOGE("setting nBufferCountActual to %lu failed: %d",
- newBufferCount, err);
+
+ if (err == OK) {
+ minUndequeuedBufs += extraBuffers;
+ break;
+ }
+
+ CODEC_LOGW("setting nBufferCountActual to %u failed: %d",
+ newBufferCount, err);
+ /* exit condition */
+ if (extraBuffers == 0) {
return err;
}
}
+ CODEC_LOGI("OMX-buffers: min=%u actual=%u undeq=%d+1",
+ def.nBufferCountMin, def.nBufferCountActual, minUndequeuedBufs);
err = native_window_set_buffer_count(
mNativeWindow.get(), def.nBufferCountActual);
@@ -1801,7 +1825,7 @@ status_t OMXCodec::allocateOutputBuffersFromNativeWindow() {
return err;
}
- CODEC_LOGV("allocating %lu buffers from a native window of size %lu on "
+ CODEC_LOGV("allocating %u buffers from a native window of size %u on "
"output port", def.nBufferCountActual, def.nBufferSize);
// Dequeue buffers and send them to OMX
@@ -1834,7 +1858,7 @@ status_t OMXCodec::allocateOutputBuffersFromNativeWindow() {
mPortBuffers[kPortIndexOutput].editItemAt(i).mBuffer = bufferId;
- CODEC_LOGV("registered graphic buffer with ID %p (pointer = %p)",
+ CODEC_LOGV("registered graphic buffer with ID %u (pointer = %p)",
bufferId, graphicBuffer.get());
}
@@ -1861,7 +1885,7 @@ status_t OMXCodec::allocateOutputBuffersFromNativeWindow() {
status_t OMXCodec::cancelBufferToNativeWindow(BufferInfo *info) {
CHECK_EQ((int)info->mStatus, (int)OWNED_BY_US);
- CODEC_LOGV("Calling cancelBuffer on buffer %p", info->mBuffer);
+ CODEC_LOGV("Calling cancelBuffer on buffer %u", info->mBuffer);
int err = mNativeWindow->cancelBuffer(
mNativeWindow.get(), info->mMediaBuffer->graphicBuffer().get(), -1);
if (err != 0) {
@@ -2099,7 +2123,7 @@ void OMXCodec::on_message(const omx_message &msg) {
{
IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer;
- CODEC_LOGV("EMPTY_BUFFER_DONE(buffer: %p)", buffer);
+ CODEC_LOGV("EMPTY_BUFFER_DONE(buffer: %u)", buffer);
Vector<BufferInfo> *buffers = &mPortBuffers[kPortIndexInput];
size_t i = 0;
@@ -2109,7 +2133,7 @@ void OMXCodec::on_message(const omx_message &msg) {
CHECK(i < buffers->size());
if ((*buffers)[i].mStatus != OWNED_BY_COMPONENT) {
- ALOGW("We already own input buffer %p, yet received "
+ ALOGW("We already own input buffer %u, yet received "
"an EMPTY_BUFFER_DONE.", buffer);
}
@@ -2123,7 +2147,7 @@ void OMXCodec::on_message(const omx_message &msg) {
}
if (mPortStatus[kPortIndexInput] == DISABLING) {
- CODEC_LOGV("Port is disabled, freeing buffer %p", buffer);
+ CODEC_LOGV("Port is disabled, freeing buffer %u", buffer);
status_t err = freeBuffer(kPortIndexInput, i);
CHECK_EQ(err, (status_t)OK);
@@ -2145,7 +2169,7 @@ void OMXCodec::on_message(const omx_message &msg) {
IOMX::buffer_id buffer = msg.u.extended_buffer_data.buffer;
OMX_U32 flags = msg.u.extended_buffer_data.flags;
- CODEC_LOGV("FILL_BUFFER_DONE(buffer: %p, size: %ld, flags: 0x%08lx, timestamp: %lld us (%.2f secs))",
+ CODEC_LOGV("FILL_BUFFER_DONE(buffer: %u, size: %u, flags: 0x%08x, timestamp: %lld us (%.2f secs))",
buffer,
msg.u.extended_buffer_data.range_length,
flags,
@@ -2162,14 +2186,14 @@ void OMXCodec::on_message(const omx_message &msg) {
BufferInfo *info = &buffers->editItemAt(i);
if (info->mStatus != OWNED_BY_COMPONENT) {
- ALOGW("We already own output buffer %p, yet received "
+ ALOGW("We already own output buffer %u, yet received "
"a FILL_BUFFER_DONE.", buffer);
}
info->mStatus = OWNED_BY_US;
if (mPortStatus[kPortIndexOutput] == DISABLING) {
- CODEC_LOGV("Port is disabled, freeing buffer %p", buffer);
+ CODEC_LOGV("Port is disabled, freeing buffer %u", buffer);
status_t err = freeBuffer(kPortIndexOutput, i);
CHECK_EQ(err, (status_t)OK);
@@ -2238,7 +2262,7 @@ void OMXCodec::on_message(const omx_message &msg) {
kKeyPlatformPrivate,
msg.u.extended_buffer_data.platform_private);
- buffer->meta_data()->setPointer(
+ buffer->meta_data()->setInt32(
kKeyBufferID,
msg.u.extended_buffer_data.buffer);
@@ -2380,7 +2404,7 @@ void OMXCodec::onEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
case OMX_EventError:
{
- CODEC_LOGE("ERROR(0x%08lx, %ld)", data1, data2);
+ CODEC_LOGE("OMX_EventError(0x%08x, %u)", data1, data2);
setState(ERROR);
break;
@@ -2388,7 +2412,7 @@ void OMXCodec::onEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
case OMX_EventPortSettingsChanged:
{
- CODEC_LOGV("OMX_EventPortSettingsChanged(port=%ld, data2=0x%08lx)",
+ CODEC_LOGV("OMX_EventPortSettingsChanged(port=%u, data2=0x%08x)",
data1, data2);
if (data2 == 0 || data2 == OMX_IndexParamPortDefinition) {
@@ -2428,7 +2452,7 @@ void OMXCodec::onEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
// The scale is in 16.16 format.
// scale 1.0 = 0x010000. When there is no
// need to change the display, skip it.
- ALOGV("Get OMX_IndexConfigScale: 0x%lx/0x%lx",
+ ALOGV("Get OMX_IndexConfigScale: 0x%x/0x%x",
scale.xWidth, scale.xHeight);
if (scale.xWidth != 0x010000) {
@@ -2462,7 +2486,7 @@ void OMXCodec::onEvent(OMX_EVENTTYPE event, OMX_U32 data1, OMX_U32 data2) {
default:
{
- CODEC_LOGV("EVENT(%d, %ld, %ld)", event, data1, data2);
+ CODEC_LOGV("EVENT(%d, %u, %u)", event, data1, data2);
break;
}
}
@@ -2479,7 +2503,7 @@ void OMXCodec::onCmdComplete(OMX_COMMANDTYPE cmd, OMX_U32 data) {
case OMX_CommandPortDisable:
{
OMX_U32 portIndex = data;
- CODEC_LOGV("PORT_DISABLED(%ld)", portIndex);
+ CODEC_LOGV("PORT_DISABLED(%u)", portIndex);
CHECK(mState == EXECUTING || mState == RECONFIGURING);
CHECK_EQ((int)mPortStatus[portIndex], (int)DISABLING);
@@ -2503,7 +2527,7 @@ void OMXCodec::onCmdComplete(OMX_COMMANDTYPE cmd, OMX_U32 data) {
status_t err = enablePortAsync(portIndex);
if (err != OK) {
- CODEC_LOGE("enablePortAsync(%ld) failed (err = %d)", portIndex, err);
+ CODEC_LOGE("enablePortAsync(%u) failed (err = %d)", portIndex, err);
setState(ERROR);
} else {
err = allocateBuffersOnPort(portIndex);
@@ -2524,7 +2548,7 @@ void OMXCodec::onCmdComplete(OMX_COMMANDTYPE cmd, OMX_U32 data) {
case OMX_CommandPortEnable:
{
OMX_U32 portIndex = data;
- CODEC_LOGV("PORT_ENABLED(%ld)", portIndex);
+ CODEC_LOGV("PORT_ENABLED(%u)", portIndex);
CHECK(mState == EXECUTING || mState == RECONFIGURING);
CHECK_EQ((int)mPortStatus[portIndex], (int)ENABLING);
@@ -2545,7 +2569,7 @@ void OMXCodec::onCmdComplete(OMX_COMMANDTYPE cmd, OMX_U32 data) {
{
OMX_U32 portIndex = data;
- CODEC_LOGV("FLUSH_DONE(%ld)", portIndex);
+ CODEC_LOGV("FLUSH_DONE(%u)", portIndex);
CHECK_EQ((int)mPortStatus[portIndex], (int)SHUTTING_DOWN);
mPortStatus[portIndex] = ENABLED;
@@ -3838,7 +3862,7 @@ status_t OMXCodec::read(
return UNKNOWN_ERROR;
}
- CODEC_LOGV("seeking to %lld us (%.2f secs)", seekTimeUs, seekTimeUs / 1E6);
+ CODEC_LOGV("seeking to %" PRId64 " us (%.2f secs)", seekTimeUs, seekTimeUs / 1E6);
mSignalledEOS = false;
@@ -4177,9 +4201,9 @@ void OMXCodec::dumpPortStatus(OMX_U32 portIndex) {
CHECK((portIndex == kPortIndexInput && def.eDir == OMX_DirInput)
|| (portIndex == kPortIndexOutput && def.eDir == OMX_DirOutput));
- printf(" nBufferCountActual = %ld\n", def.nBufferCountActual);
- printf(" nBufferCountMin = %ld\n", def.nBufferCountMin);
- printf(" nBufferSize = %ld\n", def.nBufferSize);
+ printf(" nBufferCountActual = %" PRIu32 "\n", def.nBufferCountActual);
+ printf(" nBufferCountMin = %" PRIu32 "\n", def.nBufferCountMin);
+ printf(" nBufferSize = %" PRIu32 "\n", def.nBufferSize);
switch (def.eDomain) {
case OMX_PortDomainImage:
@@ -4188,9 +4212,9 @@ void OMXCodec::dumpPortStatus(OMX_U32 portIndex) {
printf("\n");
printf(" // Image\n");
- printf(" nFrameWidth = %ld\n", imageDef->nFrameWidth);
- printf(" nFrameHeight = %ld\n", imageDef->nFrameHeight);
- printf(" nStride = %ld\n", imageDef->nStride);
+ printf(" nFrameWidth = %" PRIu32 "\n", imageDef->nFrameWidth);
+ printf(" nFrameHeight = %" PRIu32 "\n", imageDef->nFrameHeight);
+ printf(" nStride = %" PRIu32 "\n", imageDef->nStride);
printf(" eCompressionFormat = %s\n",
imageCompressionFormatString(imageDef->eCompressionFormat));
@@ -4207,9 +4231,9 @@ void OMXCodec::dumpPortStatus(OMX_U32 portIndex) {
printf("\n");
printf(" // Video\n");
- printf(" nFrameWidth = %ld\n", videoDef->nFrameWidth);
- printf(" nFrameHeight = %ld\n", videoDef->nFrameHeight);
- printf(" nStride = %ld\n", videoDef->nStride);
+ printf(" nFrameWidth = %" PRIu32 "\n", videoDef->nFrameWidth);
+ printf(" nFrameHeight = %" PRIu32 "\n", videoDef->nFrameHeight);
+ printf(" nStride = %" PRIu32 "\n", videoDef->nStride);
printf(" eCompressionFormat = %s\n",
videoCompressionFormatString(videoDef->eCompressionFormat));
@@ -4238,10 +4262,10 @@ void OMXCodec::dumpPortStatus(OMX_U32 portIndex) {
mNode, OMX_IndexParamAudioPcm, &params, sizeof(params));
CHECK_EQ(err, (status_t)OK);
- printf(" nSamplingRate = %ld\n", params.nSamplingRate);
- printf(" nChannels = %ld\n", params.nChannels);
+ printf(" nSamplingRate = %" PRIu32 "\n", params.nSamplingRate);
+ printf(" nChannels = %" PRIu32 "\n", params.nChannels);
printf(" bInterleaved = %d\n", params.bInterleaved);
- printf(" nBitPerSample = %ld\n", params.nBitPerSample);
+ printf(" nBitPerSample = %" PRIu32 "\n", params.nBitPerSample);
printf(" eNumData = %s\n",
params.eNumData == OMX_NumericalDataSigned
@@ -4257,7 +4281,7 @@ void OMXCodec::dumpPortStatus(OMX_U32 portIndex) {
mNode, OMX_IndexParamAudioAmr, &amr, sizeof(amr));
CHECK_EQ(err, (status_t)OK);
- printf(" nChannels = %ld\n", amr.nChannels);
+ printf(" nChannels = %" PRIu32 "\n", amr.nChannels);
printf(" eAMRBandMode = %s\n",
amrBandModeString(amr.eAMRBandMode));
printf(" eAMRFrameFormat = %s\n",
diff --git a/media/libstagefright/OggExtractor.cpp b/media/libstagefright/OggExtractor.cpp
index 5e79e78..1965ef9 100644
--- a/media/libstagefright/OggExtractor.cpp
+++ b/media/libstagefright/OggExtractor.cpp
@@ -151,7 +151,7 @@ sp<MetaData> OggSource::getFormat() {
return mExtractor->mImpl->getFormat();
}
-status_t OggSource::start(MetaData *params) {
+status_t OggSource::start(MetaData * /* params */) {
if (mStarted) {
return INVALID_OPERATION;
}
@@ -320,22 +320,26 @@ status_t MyVorbisExtractor::seekToTime(int64_t timeUs) {
}
size_t left = 0;
- size_t right = mTableOfContents.size();
- while (left < right) {
- size_t center = left / 2 + right / 2 + (left & right & 1);
+ size_t right_plus_one = mTableOfContents.size();
+ while (left < right_plus_one) {
+ size_t center = left + (right_plus_one - left) / 2;
const TOCEntry &entry = mTableOfContents.itemAt(center);
if (timeUs < entry.mTimeUs) {
- right = center;
+ right_plus_one = center;
} else if (timeUs > entry.mTimeUs) {
left = center + 1;
} else {
- left = right = center;
+ left = center;
break;
}
}
+ if (left == mTableOfContents.size()) {
+ --left;
+ }
+
const TOCEntry &entry = mTableOfContents.itemAt(left);
ALOGV("seeking to entry %d / %d at offset %lld",
@@ -381,7 +385,7 @@ ssize_t MyVorbisExtractor::readPage(off64_t offset, Page *page) {
ssize_t n;
if ((n = mSource->readAt(offset, header, sizeof(header)))
< (ssize_t)sizeof(header)) {
- ALOGV("failed to read %d bytes at offset 0x%016llx, got %ld bytes",
+ ALOGV("failed to read %zu bytes at offset 0x%016llx, got %d bytes",
sizeof(header), offset, n);
if (n < 0) {
@@ -505,7 +509,7 @@ status_t MyVorbisExtractor::readNextPacket(MediaBuffer **out) {
packetSize);
if (n < (ssize_t)packetSize) {
- ALOGV("failed to read %d bytes at 0x%016llx, got %ld bytes",
+ ALOGV("failed to read %zu bytes at 0x%016llx, got %d bytes",
packetSize, dataOffset, n);
return ERROR_IO;
}
@@ -546,7 +550,7 @@ status_t MyVorbisExtractor::readNextPacket(MediaBuffer **out) {
buffer = NULL;
}
- ALOGV("readPage returned %ld", n);
+ ALOGV("readPage returned %d", n);
return n < 0 ? n : (status_t)ERROR_END_OF_STREAM;
}
@@ -998,7 +1002,7 @@ sp<MediaSource> OggExtractor::getTrack(size_t index) {
}
sp<MetaData> OggExtractor::getTrackMetaData(
- size_t index, uint32_t flags) {
+ size_t index, uint32_t /* flags */) {
if (index >= 1) {
return NULL;
}
diff --git a/media/libstagefright/SampleTable.cpp b/media/libstagefright/SampleTable.cpp
index d9858d7..318555e 100644
--- a/media/libstagefright/SampleTable.cpp
+++ b/media/libstagefright/SampleTable.cpp
@@ -520,83 +520,72 @@ void SampleTable::buildSampleEntriesTable() {
}
status_t SampleTable::findSampleAtTime(
- uint32_t req_time, uint32_t *sample_index, uint32_t flags) {
+ uint64_t req_time, uint64_t scale_num, uint64_t scale_den,
+ uint32_t *sample_index, uint32_t flags) {
buildSampleEntriesTable();
uint32_t left = 0;
- uint32_t right = mNumSampleSizes;
- while (left < right) {
- uint32_t center = (left + right) / 2;
- uint32_t centerTime = mSampleTimeEntries[center].mCompositionTime;
+ uint32_t right_plus_one = mNumSampleSizes;
+ while (left < right_plus_one) {
+ uint32_t center = left + (right_plus_one - left) / 2;
+ uint64_t centerTime =
+ getSampleTime(center, scale_num, scale_den);
if (req_time < centerTime) {
- right = center;
+ right_plus_one = center;
} else if (req_time > centerTime) {
left = center + 1;
} else {
- left = center;
- break;
+ *sample_index = mSampleTimeEntries[center].mSampleIndex;
+ return OK;
}
}
- if (left == mNumSampleSizes) {
+ uint32_t closestIndex = left;
+
+ if (closestIndex == mNumSampleSizes) {
if (flags == kFlagAfter) {
return ERROR_OUT_OF_RANGE;
}
-
- --left;
+ flags = kFlagBefore;
+ } else if (closestIndex == 0) {
+ if (flags == kFlagBefore) {
+ // normally we should return out of range, but that is
+ // treated as end-of-stream. instead return first sample
+ //
+ // return ERROR_OUT_OF_RANGE;
+ }
+ flags = kFlagAfter;
}
- uint32_t closestIndex = left;
-
switch (flags) {
case kFlagBefore:
{
- while (closestIndex > 0
- && mSampleTimeEntries[closestIndex].mCompositionTime
- > req_time) {
- --closestIndex;
- }
+ --closestIndex;
break;
}
case kFlagAfter:
{
- while (closestIndex + 1 < mNumSampleSizes
- && mSampleTimeEntries[closestIndex].mCompositionTime
- < req_time) {
- ++closestIndex;
- }
+ // nothing to do
break;
}
default:
{
CHECK(flags == kFlagClosest);
-
- if (closestIndex > 0) {
- // Check left neighbour and pick closest.
- uint32_t absdiff1 =
- abs_difference(
- mSampleTimeEntries[closestIndex].mCompositionTime,
- req_time);
-
- uint32_t absdiff2 =
- abs_difference(
- mSampleTimeEntries[closestIndex - 1].mCompositionTime,
- req_time);
-
- if (absdiff1 > absdiff2) {
- closestIndex = closestIndex - 1;
- }
+ // pick closest based on timestamp. use abs_difference for safety
+ if (abs_difference(
+ getSampleTime(closestIndex, scale_num, scale_den), req_time) >
+ abs_difference(
+ req_time, getSampleTime(closestIndex - 1, scale_num, scale_den))) {
+ --closestIndex;
}
-
break;
}
}
*sample_index = mSampleTimeEntries[closestIndex].mSampleIndex;
-
return OK;
}
@@ -618,109 +607,85 @@ status_t SampleTable::findSyncSampleNear(
}
uint32_t left = 0;
- uint32_t right = mNumSyncSamples;
- while (left < right) {
- uint32_t center = left + (right - left) / 2;
+ uint32_t right_plus_one = mNumSyncSamples;
+ while (left < right_plus_one) {
+ uint32_t center = left + (right_plus_one - left) / 2;
uint32_t x = mSyncSamples[center];
if (start_sample_index < x) {
- right = center;
+ right_plus_one = center;
} else if (start_sample_index > x) {
left = center + 1;
} else {
- left = center;
- break;
+ *sample_index = x;
+ return OK;
}
}
+
if (left == mNumSyncSamples) {
if (flags == kFlagAfter) {
ALOGE("tried to find a sync frame after the last one: %d", left);
return ERROR_OUT_OF_RANGE;
}
- left = left - 1;
+ flags = kFlagBefore;
}
+ else if (left == 0) {
+ if (flags == kFlagBefore) {
+ ALOGE("tried to find a sync frame before the first one: %d", left);
- // Now ssi[left] is the sync sample index just before (or at)
- // start_sample_index.
- // Also start_sample_index < ssi[left + 1], if left + 1 < mNumSyncSamples.
-
- uint32_t x = mSyncSamples[left];
-
- if (left + 1 < mNumSyncSamples) {
- uint32_t y = mSyncSamples[left + 1];
-
- // our sample lies between sync samples x and y.
-
- status_t err = mSampleIterator->seekTo(start_sample_index);
- if (err != OK) {
- return err;
- }
-
- uint32_t sample_time = mSampleIterator->getSampleTime();
-
- err = mSampleIterator->seekTo(x);
- if (err != OK) {
- return err;
- }
- uint32_t x_time = mSampleIterator->getSampleTime();
-
- err = mSampleIterator->seekTo(y);
- if (err != OK) {
- return err;
- }
-
- uint32_t y_time = mSampleIterator->getSampleTime();
-
- if (abs_difference(x_time, sample_time)
- > abs_difference(y_time, sample_time)) {
- // Pick the sync sample closest (timewise) to the start-sample.
- x = y;
- ++left;
+ // normally we should return out of range, but that is
+ // treated as end-of-stream. instead seek to first sync
+ //
+ // return ERROR_OUT_OF_RANGE;
}
+ flags = kFlagAfter;
}
+ // Now ssi[left - 1] <(=) start_sample_index <= ssi[left]
switch (flags) {
case kFlagBefore:
{
- if (x > start_sample_index) {
- CHECK(left > 0);
-
- x = mSyncSamples[left - 1];
-
- if (x > start_sample_index) {
- // The table of sync sample indices was not sorted
- // properly.
- return ERROR_MALFORMED;
- }
- }
+ --left;
break;
}
-
case kFlagAfter:
{
- if (x < start_sample_index) {
- if (left + 1 >= mNumSyncSamples) {
- return ERROR_OUT_OF_RANGE;
- }
-
- x = mSyncSamples[left + 1];
-
- if (x < start_sample_index) {
- // The table of sync sample indices was not sorted
- // properly.
- return ERROR_MALFORMED;
- }
- }
-
+ // nothing to do
break;
}
-
default:
+ {
+ // this route is not used, but implement it nonetheless
+ CHECK(flags == kFlagClosest);
+
+ status_t err = mSampleIterator->seekTo(start_sample_index);
+ if (err != OK) {
+ return err;
+ }
+ uint32_t sample_time = mSampleIterator->getSampleTime();
+
+ err = mSampleIterator->seekTo(mSyncSamples[left]);
+ if (err != OK) {
+ return err;
+ }
+ uint32_t upper_time = mSampleIterator->getSampleTime();
+
+ err = mSampleIterator->seekTo(mSyncSamples[left - 1]);
+ if (err != OK) {
+ return err;
+ }
+ uint32_t lower_time = mSampleIterator->getSampleTime();
+
+ // use abs_difference for safety
+ if (abs_difference(upper_time, sample_time) >
+ abs_difference(sample_time, lower_time)) {
+ --left;
+ }
break;
+ }
}
- *sample_index = x;
-
+ *sample_index = mSyncSamples[left];
return OK;
}
diff --git a/media/libstagefright/StagefrightMediaScanner.cpp b/media/libstagefright/StagefrightMediaScanner.cpp
index af8186c..f3fc3f6 100644
--- a/media/libstagefright/StagefrightMediaScanner.cpp
+++ b/media/libstagefright/StagefrightMediaScanner.cpp
@@ -117,7 +117,7 @@ MediaScanResult StagefrightMediaScanner::processFile(
}
MediaScanResult StagefrightMediaScanner::processFileInternal(
- const char *path, const char *mimeType,
+ const char *path, const char * /* mimeType */,
MediaScannerClient &client) {
const char *extension = strrchr(path, '.');
@@ -202,7 +202,7 @@ MediaScanResult StagefrightMediaScanner::processFileInternal(
return MEDIA_SCAN_RESULT_OK;
}
-char *StagefrightMediaScanner::extractAlbumArt(int fd) {
+MediaAlbumArt *StagefrightMediaScanner::extractAlbumArt(int fd) {
ALOGV("extractAlbumArt %d", fd);
off64_t size = lseek64(fd, 0, SEEK_END);
@@ -214,15 +214,9 @@ char *StagefrightMediaScanner::extractAlbumArt(int fd) {
sp<MediaMetadataRetriever> mRetriever(new MediaMetadataRetriever);
if (mRetriever->setDataSource(fd, 0, size) == OK) {
sp<IMemory> mem = mRetriever->extractAlbumArt();
-
if (mem != NULL) {
MediaAlbumArt *art = static_cast<MediaAlbumArt *>(mem->pointer());
-
- char *data = (char *)malloc(art->mSize + 4);
- *(int32_t *)data = art->mSize;
- memcpy(&data[4], &art[1], art->mSize);
-
- return data;
+ return art->clone();
}
}
diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libstagefright/StagefrightMetadataRetriever.cpp
index 19af4fb..e4d3c79 100644
--- a/media/libstagefright/StagefrightMetadataRetriever.cpp
+++ b/media/libstagefright/StagefrightMetadataRetriever.cpp
@@ -16,6 +16,7 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "StagefrightMetadataRetriever"
+#include <inttypes.h>
#include <utils/Log.h>
#include "include/StagefrightMetadataRetriever.h"
@@ -374,10 +375,7 @@ VideoFrame *StagefrightMetadataRetriever::getFrameAtTime(
size_t dataSize;
if (fileMeta->findData(kKeyAlbumArt, &type, &data, &dataSize)
&& mAlbumArt == NULL) {
- mAlbumArt = new MediaAlbumArt;
- mAlbumArt->mSize = dataSize;
- mAlbumArt->mData = new uint8_t[dataSize];
- memcpy(mAlbumArt->mData, data, dataSize);
+ mAlbumArt = MediaAlbumArt::fromData(dataSize, data);
}
VideoFrame *frame =
@@ -410,7 +408,7 @@ MediaAlbumArt *StagefrightMetadataRetriever::extractAlbumArt() {
}
if (mAlbumArt) {
- return new MediaAlbumArt(*mAlbumArt);
+ return mAlbumArt->clone();
}
return NULL;
@@ -479,16 +477,13 @@ void StagefrightMetadataRetriever::parseMetaData() {
size_t dataSize;
if (meta->findData(kKeyAlbumArt, &type, &data, &dataSize)
&& mAlbumArt == NULL) {
- mAlbumArt = new MediaAlbumArt;
- mAlbumArt->mSize = dataSize;
- mAlbumArt->mData = new uint8_t[dataSize];
- memcpy(mAlbumArt->mData, data, dataSize);
+ mAlbumArt = MediaAlbumArt::fromData(dataSize, data);
}
size_t numTracks = mExtractor->countTracks();
char tmp[32];
- sprintf(tmp, "%d", numTracks);
+ sprintf(tmp, "%zu", numTracks);
mMetaData.add(METADATA_KEY_NUM_TRACKS, String8(tmp));
@@ -545,7 +540,7 @@ void StagefrightMetadataRetriever::parseMetaData() {
}
// The duration value is a string representing the duration in ms.
- sprintf(tmp, "%lld", (maxDurationUs + 500) / 1000);
+ sprintf(tmp, "%" PRId64, (maxDurationUs + 500) / 1000);
mMetaData.add(METADATA_KEY_DURATION, String8(tmp));
if (hasAudio) {
@@ -573,7 +568,7 @@ void StagefrightMetadataRetriever::parseMetaData() {
if (mSource->getSize(&sourceSize) == OK) {
int64_t avgBitRate = (int64_t)(sourceSize * 8E6 / maxDurationUs);
- sprintf(tmp, "%lld", avgBitRate);
+ sprintf(tmp, "%" PRId64, avgBitRate);
mMetaData.add(METADATA_KEY_BITRATE, String8(tmp));
}
}
diff --git a/media/libstagefright/SurfaceMediaSource.cpp b/media/libstagefright/SurfaceMediaSource.cpp
index 6b934d4..686d03a 100644
--- a/media/libstagefright/SurfaceMediaSource.cpp
+++ b/media/libstagefright/SurfaceMediaSource.cpp
@@ -99,8 +99,11 @@ void SurfaceMediaSource::dump(String8& result) const
dump(result, "", buffer, 1024);
}
-void SurfaceMediaSource::dump(String8& result, const char* prefix,
- char* buffer, size_t SIZE) const
+void SurfaceMediaSource::dump(
+ String8& result,
+ const char* /* prefix */,
+ char* buffer,
+ size_t /* SIZE */) const
{
Mutex::Autolock lock(mMutex);
@@ -269,9 +272,8 @@ static void passMetadataBuffer(MediaBuffer **buffer,
bufferHandle, (*buffer)->range_length(), (*buffer)->range_offset());
}
-status_t SurfaceMediaSource::read( MediaBuffer **buffer,
- const ReadOptions *options)
-{
+status_t SurfaceMediaSource::read(
+ MediaBuffer **buffer, const ReadOptions * /* options */) {
ALOGV("read");
Mutex::Autolock lock(mMutex);
diff --git a/media/libstagefright/TimedEventQueue.cpp b/media/libstagefright/TimedEventQueue.cpp
index 1a9a26b..3d2eb1f 100644
--- a/media/libstagefright/TimedEventQueue.cpp
+++ b/media/libstagefright/TimedEventQueue.cpp
@@ -217,6 +217,7 @@ void TimedEventQueue::threadEntry() {
for (;;) {
int64_t now_us = 0;
sp<Event> event;
+ bool wakeLocked = false;
{
Mutex::Autolock autoLock(mLock);
@@ -283,26 +284,28 @@ void TimedEventQueue::threadEntry() {
// removeEventFromQueue_l will return NULL.
// Otherwise, the QueueItem will be removed
// from the queue and the referenced event returned.
- event = removeEventFromQueue_l(eventID);
+ event = removeEventFromQueue_l(eventID, &wakeLocked);
}
if (event != NULL) {
// Fire event with the lock NOT held.
event->fire(this, now_us);
+ if (wakeLocked) {
+ Mutex::Autolock autoLock(mLock);
+ releaseWakeLock_l();
+ }
}
}
}
sp<TimedEventQueue::Event> TimedEventQueue::removeEventFromQueue_l(
- event_id id) {
+ event_id id, bool *wakeLocked) {
for (List<QueueItem>::iterator it = mQueue.begin();
it != mQueue.end(); ++it) {
if ((*it).event->eventID() == id) {
sp<Event> event = (*it).event;
event->setEventID(0);
- if ((*it).has_wakelock) {
- releaseWakeLock_l();
- }
+ *wakeLocked = (*it).has_wakelock;
mQueue.erase(it);
return event;
}
@@ -315,7 +318,7 @@ sp<TimedEventQueue::Event> TimedEventQueue::removeEventFromQueue_l(
void TimedEventQueue::acquireWakeLock_l()
{
- if (mWakeLockCount++ == 0) {
+ if (mWakeLockCount == 0) {
CHECK(mWakeLockToken == 0);
if (mPowerManager == 0) {
// use checkService() to avoid blocking if power service is not up yet
@@ -338,21 +341,23 @@ void TimedEventQueue::acquireWakeLock_l()
IPCThreadState::self()->restoreCallingIdentity(token);
if (status == NO_ERROR) {
mWakeLockToken = binder;
+ mWakeLockCount++;
}
}
+ } else {
+ mWakeLockCount++;
}
}
void TimedEventQueue::releaseWakeLock_l(bool force)
{
+ if (mWakeLockCount == 0) {
+ return;
+ }
if (force) {
- if (mWakeLockCount == 0) {
- return;
- }
// Force wakelock release below by setting reference count to 1.
mWakeLockCount = 1;
}
- CHECK(mWakeLockCount != 0);
if (--mWakeLockCount == 0) {
CHECK(mWakeLockToken != 0);
if (mPowerManager != 0) {
@@ -371,8 +376,8 @@ void TimedEventQueue::clearPowerManager()
mPowerManager.clear();
}
-void TimedEventQueue::PMDeathRecipient::binderDied(const wp<IBinder>& who)
-{
+void TimedEventQueue::PMDeathRecipient::binderDied(
+ const wp<IBinder>& /* who */) {
mQueue->clearPowerManager();
}
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index 9041c21..216a329 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -562,6 +562,17 @@ bool canOffloadStream(const sp<MetaData>& meta, bool hasVideo,
return false;
}
+ // check whether it is ELD/LD content -> no offloading
+ // FIXME: this should depend on audio DSP capabilities. mapMimeToAudioFormat() should use the
+ // metadata to refine the AAC format and the audio HAL should only list supported profiles.
+ int32_t aacaot = -1;
+ if (meta->findInt32(kKeyAACAOT, &aacaot)) {
+ if (aacaot == 23 || aacaot == 39 ) {
+ ALOGV("track of type '%s' is ELD/LD content", mime);
+ return false;
+ }
+ }
+
int32_t srate = -1;
if (!meta->findInt32(kKeySampleRate, &srate)) {
ALOGV("track of type '%s' does not publish sample rate", mime);
diff --git a/media/libstagefright/VBRISeeker.cpp b/media/libstagefright/VBRISeeker.cpp
index a245f2c..af858b9 100644
--- a/media/libstagefright/VBRISeeker.cpp
+++ b/media/libstagefright/VBRISeeker.cpp
@@ -119,7 +119,7 @@ sp<VBRISeeker> VBRISeeker::CreateFromSource(
seeker->mSegments.push(numBytes);
- ALOGV("entry #%d: %d offset 0x%08lx", i, numBytes, offset);
+ ALOGV("entry #%d: %u offset 0x%016llx", i, numBytes, offset);
offset += numBytes;
}
@@ -160,7 +160,7 @@ bool VBRISeeker::getOffsetForTime(int64_t *timeUs, off64_t *pos) {
*pos += mSegments.itemAt(segmentIndex++);
}
- ALOGV("getOffsetForTime %lld us => 0x%08lx", *timeUs, *pos);
+ ALOGV("getOffsetForTime %lld us => 0x%016llx", *timeUs, *pos);
*timeUs = nowUs;
diff --git a/media/libstagefright/WAVExtractor.cpp b/media/libstagefright/WAVExtractor.cpp
index 22af6fb..fe9058b 100644
--- a/media/libstagefright/WAVExtractor.cpp
+++ b/media/libstagefright/WAVExtractor.cpp
@@ -127,7 +127,7 @@ sp<MediaSource> WAVExtractor::getTrack(size_t index) {
}
sp<MetaData> WAVExtractor::getTrackMetaData(
- size_t index, uint32_t flags) {
+ size_t index, uint32_t /* flags */) {
if (mInitCheck != OK || index > 0) {
return NULL;
}
@@ -358,7 +358,7 @@ WAVSource::~WAVSource() {
}
}
-status_t WAVSource::start(MetaData *params) {
+status_t WAVSource::start(MetaData * /* params */) {
ALOGV("WAVSource::start");
CHECK(!mStarted);
diff --git a/media/libstagefright/avc_utils.cpp b/media/libstagefright/avc_utils.cpp
index b822868..c6ac0da 100644
--- a/media/libstagefright/avc_utils.cpp
+++ b/media/libstagefright/avc_utils.cpp
@@ -251,9 +251,7 @@ status_t getNextNALUnit(
return OK;
}
-static sp<ABuffer> FindNAL(
- const uint8_t *data, size_t size, unsigned nalType,
- size_t *stopOffset) {
+static sp<ABuffer> FindNAL(const uint8_t *data, size_t size, unsigned nalType) {
const uint8_t *nalStart;
size_t nalSize;
while (getNextNALUnit(&data, &size, &nalStart, &nalSize, true) == OK) {
@@ -293,7 +291,7 @@ sp<MetaData> MakeAVCCodecSpecificData(const sp<ABuffer> &accessUnit) {
const uint8_t *data = accessUnit->data();
size_t size = accessUnit->size();
- sp<ABuffer> seqParamSet = FindNAL(data, size, 7, NULL);
+ sp<ABuffer> seqParamSet = FindNAL(data, size, 7);
if (seqParamSet == NULL) {
return NULL;
}
@@ -303,8 +301,7 @@ sp<MetaData> MakeAVCCodecSpecificData(const sp<ABuffer> &accessUnit) {
FindAVCDimensions(
seqParamSet, &width, &height, &sarWidth, &sarHeight);
- size_t stopOffset;
- sp<ABuffer> picParamSet = FindNAL(data, size, 8, &stopOffset);
+ sp<ABuffer> picParamSet = FindNAL(data, size, 8);
CHECK(picParamSet != NULL);
size_t csdSize =
diff --git a/media/libstagefright/chromium_http/Android.mk b/media/libstagefright/chromium_http/Android.mk
index f26f386..109e3fe 100644
--- a/media/libstagefright/chromium_http/Android.mk
+++ b/media/libstagefright/chromium_http/Android.mk
@@ -18,9 +18,11 @@ LOCAL_C_INCLUDES:= \
LOCAL_CFLAGS += -Wno-multichar
LOCAL_SHARED_LIBRARIES += \
+ libbinder \
libstlport \
libchromium_net \
libutils \
+ libbinder \
libcutils \
liblog \
libstagefright_foundation \
diff --git a/media/libstagefright/chromium_http/ChromiumHTTPDataSource.cpp b/media/libstagefright/chromium_http/ChromiumHTTPDataSource.cpp
index a862d8b..7e5c280 100644
--- a/media/libstagefright/chromium_http/ChromiumHTTPDataSource.cpp
+++ b/media/libstagefright/chromium_http/ChromiumHTTPDataSource.cpp
@@ -108,6 +108,11 @@ status_t ChromiumHTTPDataSource::connect_l(
return mState == CONNECTED ? OK : mIOResult;
}
+void ChromiumHTTPDataSource::onRedirect(const char *url) {
+ Mutex::Autolock autoLock(mLock);
+ mURI = url;
+}
+
void ChromiumHTTPDataSource::onConnectionEstablished(
int64_t contentSize, const char *contentType) {
Mutex::Autolock autoLock(mLock);
diff --git a/media/libstagefright/chromium_http/support.cpp b/media/libstagefright/chromium_http/support.cpp
index 0a8e3e3..09c87be 100644
--- a/media/libstagefright/chromium_http/support.cpp
+++ b/media/libstagefright/chromium_http/support.cpp
@@ -34,14 +34,97 @@
#include "net/proxy/proxy_config_service_android.h"
#include "include/ChromiumHTTPDataSource.h"
-
+#include <arpa/inet.h>
+#include <binder/Parcel.h>
#include <cutils/log.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/Utils.h>
#include <string>
+#include <utils/Errors.h>
+#include <binder/IInterface.h>
+#include <binder/IServiceManager.h>
+
namespace android {
+// must be kept in sync with interface defined in IAudioService.aidl
+class IAudioService : public IInterface
+{
+public:
+ DECLARE_META_INTERFACE(AudioService);
+
+ virtual int verifyX509CertChain(
+ const std::vector<std::string>& cert_chain,
+ const std::string& hostname,
+ const std::string& auth_type) = 0;
+};
+
+class BpAudioService : public BpInterface<IAudioService>
+{
+public:
+ BpAudioService(const sp<IBinder>& impl)
+ : BpInterface<IAudioService>(impl)
+ {
+ }
+
+ virtual int verifyX509CertChain(
+ const std::vector<std::string>& cert_chain,
+ const std::string& hostname,
+ const std::string& auth_type)
+ {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioService::getInterfaceDescriptor());
+
+ // The vector of std::string we get isn't really a vector of strings,
+ // but rather a vector of binary certificate data. If we try to pass
+ // it to Java language code as a string, it ends up mangled on the other
+ // side, so send them as bytes instead.
+ // Since we can't send an array of byte arrays, send a single array,
+ // which will be split out by the recipient.
+
+ int numcerts = cert_chain.size();
+ data.writeInt32(numcerts);
+ size_t total = 0;
+ for (int i = 0; i < numcerts; i++) {
+ total += cert_chain[i].size();
+ }
+ size_t bytesize = total + numcerts * 4;
+ uint8_t *bytes = (uint8_t*) malloc(bytesize);
+ if (!bytes) {
+ return 5; // SSL_INVALID
+ }
+ ALOGV("%d certs: %d -> %d", numcerts, total, bytesize);
+
+ int offset = 0;
+ for (int i = 0; i < numcerts; i++) {
+ int32_t certsize = cert_chain[i].size();
+ // store this in a known order, which just happens to match the default
+ // byte order of a java ByteBuffer
+ int32_t bigsize = htonl(certsize);
+ ALOGV("cert %d, size %d", i, certsize);
+ memcpy(bytes + offset, &bigsize, sizeof(bigsize));
+ offset += sizeof(bigsize);
+ memcpy(bytes + offset, cert_chain[i].data(), certsize);
+ offset += certsize;
+ }
+ data.writeByteArray(bytesize, bytes);
+ free(bytes);
+ data.writeString16(String16(hostname.c_str()));
+ data.writeString16(String16(auth_type.c_str()));
+
+ int32_t result;
+ if (remote()->transact(IBinder::FIRST_CALL_TRANSACTION, data, &reply) != NO_ERROR
+ || reply.readExceptionCode() < 0 || reply.readInt32(&result) != NO_ERROR) {
+ return 5; // SSL_INVALID;
+ }
+ return result;
+ }
+
+};
+
+IMPLEMENT_META_INTERFACE(AudioService, "android.media.IAudioService");
+
+
static Mutex gNetworkThreadLock;
static base::Thread *gNetworkThread = NULL;
static scoped_refptr<SfRequestContext> gReqContext;
@@ -76,7 +159,7 @@ bool logMessageHandler(
struct AutoPrioritySaver {
AutoPrioritySaver()
- : mTID(androidGetTid()),
+ : mTID(gettid()),
mPrevPriority(androidGetThreadPriority(mTID)) {
androidSetThreadPriority(mTID, ANDROID_PRIORITY_NORMAL);
}
@@ -226,7 +309,24 @@ SfNetworkLibrary::VerifyResult SfNetworkLibrary::VerifyX509CertChain(
const std::vector<std::string>& cert_chain,
const std::string& hostname,
const std::string& auth_type) {
- return VERIFY_OK;
+
+ sp<IBinder> binder =
+ defaultServiceManager()->checkService(String16("audio"));
+ if (binder == 0) {
+ ALOGW("Thread cannot connect to the audio service");
+ } else {
+ sp<IAudioService> service = interface_cast<IAudioService>(binder);
+ int code = service->verifyX509CertChain(cert_chain, hostname, auth_type);
+ ALOGV("verified: %d", code);
+ if (code == -1) {
+ return VERIFY_OK;
+ } else if (code == 2) { // SSL_IDMISMATCH
+ return VERIFY_BAD_HOSTNAME;
+ } else if (code == 3) { // SSL_UNTRUSTED
+ return VERIFY_NO_TRUSTED_ROOT;
+ }
+ }
+ return VERIFY_INVOCATION_ERROR;
}
////////////////////////////////////////////////////////////////////////////////
@@ -269,6 +369,7 @@ bool SfDelegate::getUID(uid_t *uid) const {
void SfDelegate::OnReceivedRedirect(
net::URLRequest *request, const GURL &new_url, bool *defer_redirect) {
MY_LOGV("OnReceivedRedirect");
+ mOwner->onRedirect(new_url.spec().c_str());
}
void SfDelegate::OnAuthRequired(
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
index 1b20cbb..d4b0de7 100644
--- a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
+++ b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
@@ -58,6 +58,8 @@ SoftAAC2::SoftAAC2(
mIsADTS(false),
mInputBufferCount(0),
mSignalledError(false),
+ mSawInputEos(false),
+ mSignalledOutputEos(false),
mAnchorTimeUs(0),
mNumSamplesOutput(0),
mOutputPortSettingsChange(NONE) {
@@ -350,115 +352,83 @@ void SoftAAC2::onQueueFilled(OMX_U32 portIndex) {
return;
}
- while (!inQueue.empty() && !outQueue.empty()) {
- BufferInfo *inInfo = *inQueue.begin();
- OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
+ while ((!inQueue.empty() || (mSawInputEos && !mSignalledOutputEos)) && !outQueue.empty()) {
+ BufferInfo *inInfo = NULL;
+ OMX_BUFFERHEADERTYPE *inHeader = NULL;
+ if (!inQueue.empty()) {
+ inInfo = *inQueue.begin();
+ inHeader = inInfo->mHeader;
+ }
BufferInfo *outInfo = *outQueue.begin();
OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
+ outHeader->nFlags = 0;
- if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
- inQueue.erase(inQueue.begin());
- inInfo->mOwnedByUs = false;
- notifyEmptyBufferDone(inHeader);
-
- if (mDecoderHasData) {
- // flush out the decoder's delayed data by calling DecodeFrame
- // one more time, with the AACDEC_FLUSH flag set
- INT_PCM *outBuffer =
- reinterpret_cast<INT_PCM *>(
- outHeader->pBuffer + outHeader->nOffset);
-
- AAC_DECODER_ERROR decoderErr =
- aacDecoder_DecodeFrame(mAACDecoder,
- outBuffer,
- outHeader->nAllocLen,
- AACDEC_FLUSH);
- mDecoderHasData = false;
-
- if (decoderErr != AAC_DEC_OK) {
- mSignalledError = true;
-
- notify(OMX_EventError, OMX_ErrorUndefined, decoderErr,
- NULL);
-
- return;
- }
-
- outHeader->nFilledLen =
- mStreamInfo->frameSize
- * sizeof(int16_t)
- * mStreamInfo->numChannels;
- } else {
- // we never submitted any data to the decoder, so there's nothing to flush out
- outHeader->nFilledLen = 0;
+ if (inHeader) {
+ if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
+ mSawInputEos = true;
}
- outHeader->nFlags = OMX_BUFFERFLAG_EOS;
-
- outQueue.erase(outQueue.begin());
- outInfo->mOwnedByUs = false;
- notifyFillBufferDone(outHeader);
- return;
- }
-
- if (inHeader->nOffset == 0) {
- mAnchorTimeUs = inHeader->nTimeStamp;
- mNumSamplesOutput = 0;
- }
+ if (inHeader->nOffset == 0 && inHeader->nFilledLen) {
+ mAnchorTimeUs = inHeader->nTimeStamp;
+ mNumSamplesOutput = 0;
+ }
- size_t adtsHeaderSize = 0;
- if (mIsADTS) {
- // skip 30 bits, aac_frame_length follows.
- // ssssssss ssssiiip ppffffPc ccohCCll llllllll lll?????
+ if (mIsADTS) {
+ size_t adtsHeaderSize = 0;
+ // skip 30 bits, aac_frame_length follows.
+ // ssssssss ssssiiip ppffffPc ccohCCll llllllll lll?????
- const uint8_t *adtsHeader = inHeader->pBuffer + inHeader->nOffset;
+ const uint8_t *adtsHeader = inHeader->pBuffer + inHeader->nOffset;
- bool signalError = false;
- if (inHeader->nFilledLen < 7) {
- ALOGE("Audio data too short to contain even the ADTS header. "
- "Got %ld bytes.", inHeader->nFilledLen);
- hexdump(adtsHeader, inHeader->nFilledLen);
- signalError = true;
- } else {
- bool protectionAbsent = (adtsHeader[1] & 1);
-
- unsigned aac_frame_length =
- ((adtsHeader[3] & 3) << 11)
- | (adtsHeader[4] << 3)
- | (adtsHeader[5] >> 5);
-
- if (inHeader->nFilledLen < aac_frame_length) {
- ALOGE("Not enough audio data for the complete frame. "
- "Got %ld bytes, frame size according to the ADTS "
- "header is %u bytes.",
- inHeader->nFilledLen, aac_frame_length);
+ bool signalError = false;
+ if (inHeader->nFilledLen < 7) {
+ ALOGE("Audio data too short to contain even the ADTS header. "
+ "Got %d bytes.", inHeader->nFilledLen);
hexdump(adtsHeader, inHeader->nFilledLen);
signalError = true;
} else {
- adtsHeaderSize = (protectionAbsent ? 7 : 9);
-
- inBuffer[0] = (UCHAR *)adtsHeader + adtsHeaderSize;
- inBufferLength[0] = aac_frame_length - adtsHeaderSize;
-
- inHeader->nOffset += adtsHeaderSize;
- inHeader->nFilledLen -= adtsHeaderSize;
+ bool protectionAbsent = (adtsHeader[1] & 1);
+
+ unsigned aac_frame_length =
+ ((adtsHeader[3] & 3) << 11)
+ | (adtsHeader[4] << 3)
+ | (adtsHeader[5] >> 5);
+
+ if (inHeader->nFilledLen < aac_frame_length) {
+ ALOGE("Not enough audio data for the complete frame. "
+ "Got %d bytes, frame size according to the ADTS "
+ "header is %u bytes.",
+ inHeader->nFilledLen, aac_frame_length);
+ hexdump(adtsHeader, inHeader->nFilledLen);
+ signalError = true;
+ } else {
+ adtsHeaderSize = (protectionAbsent ? 7 : 9);
+
+ inBuffer[0] = (UCHAR *)adtsHeader + adtsHeaderSize;
+ inBufferLength[0] = aac_frame_length - adtsHeaderSize;
+
+ inHeader->nOffset += adtsHeaderSize;
+ inHeader->nFilledLen -= adtsHeaderSize;
+ }
}
- }
- if (signalError) {
- mSignalledError = true;
+ if (signalError) {
+ mSignalledError = true;
- notify(OMX_EventError,
- OMX_ErrorStreamCorrupt,
- ERROR_MALFORMED,
- NULL);
+ notify(OMX_EventError,
+ OMX_ErrorStreamCorrupt,
+ ERROR_MALFORMED,
+ NULL);
- return;
+ return;
+ }
+ } else {
+ inBuffer[0] = inHeader->pBuffer + inHeader->nOffset;
+ inBufferLength[0] = inHeader->nFilledLen;
}
} else {
- inBuffer[0] = inHeader->pBuffer + inHeader->nOffset;
- inBufferLength[0] = inHeader->nFilledLen;
+ inBufferLength[0] = 0;
}
// Fill and decode
@@ -471,50 +441,66 @@ void SoftAAC2::onQueueFilled(OMX_U32 portIndex) {
int prevNumChannels = mStreamInfo->numChannels;
AAC_DECODER_ERROR decoderErr = AAC_DEC_NOT_ENOUGH_BITS;
- while (bytesValid[0] > 0 && decoderErr == AAC_DEC_NOT_ENOUGH_BITS) {
+ while ((bytesValid[0] > 0 || mSawInputEos) && decoderErr == AAC_DEC_NOT_ENOUGH_BITS) {
+ mDecoderHasData |= (bytesValid[0] > 0);
aacDecoder_Fill(mAACDecoder,
inBuffer,
inBufferLength,
bytesValid);
- mDecoderHasData = true;
decoderErr = aacDecoder_DecodeFrame(mAACDecoder,
outBuffer,
outHeader->nAllocLen,
0 /* flags */);
-
if (decoderErr == AAC_DEC_NOT_ENOUGH_BITS) {
- ALOGW("Not enough bits, bytesValid %d", bytesValid[0]);
+ if (mSawInputEos && bytesValid[0] <= 0) {
+ if (mDecoderHasData) {
+ // flush out the decoder's delayed data by calling DecodeFrame
+ // one more time, with the AACDEC_FLUSH flag set
+ decoderErr = aacDecoder_DecodeFrame(mAACDecoder,
+ outBuffer,
+ outHeader->nAllocLen,
+ AACDEC_FLUSH);
+ mDecoderHasData = false;
+ }
+ outHeader->nFlags = OMX_BUFFERFLAG_EOS;
+ mSignalledOutputEos = true;
+ break;
+ } else {
+ ALOGW("Not enough bits, bytesValid %d", bytesValid[0]);
+ }
}
}
size_t numOutBytes =
mStreamInfo->frameSize * sizeof(int16_t) * mStreamInfo->numChannels;
- if (decoderErr == AAC_DEC_OK) {
- UINT inBufferUsedLength = inBufferLength[0] - bytesValid[0];
- inHeader->nFilledLen -= inBufferUsedLength;
- inHeader->nOffset += inBufferUsedLength;
- } else {
- ALOGW("AAC decoder returned error %d, substituting silence",
- decoderErr);
+ if (inHeader) {
+ if (decoderErr == AAC_DEC_OK) {
+ UINT inBufferUsedLength = inBufferLength[0] - bytesValid[0];
+ inHeader->nFilledLen -= inBufferUsedLength;
+ inHeader->nOffset += inBufferUsedLength;
+ } else {
+ ALOGW("AAC decoder returned error %d, substituting silence",
+ decoderErr);
- memset(outHeader->pBuffer + outHeader->nOffset, 0, numOutBytes);
+ memset(outHeader->pBuffer + outHeader->nOffset, 0, numOutBytes);
- // Discard input buffer.
- inHeader->nFilledLen = 0;
+ // Discard input buffer.
+ inHeader->nFilledLen = 0;
- aacDecoder_SetParam(mAACDecoder, AAC_TPDEC_CLEAR_BUFFER, 1);
+ aacDecoder_SetParam(mAACDecoder, AAC_TPDEC_CLEAR_BUFFER, 1);
- // fall through
- }
+ // fall through
+ }
- if (inHeader->nFilledLen == 0) {
- inInfo->mOwnedByUs = false;
- inQueue.erase(inQueue.begin());
- inInfo = NULL;
- notifyEmptyBufferDone(inHeader);
- inHeader = NULL;
+ if (inHeader->nFilledLen == 0) {
+ inInfo->mOwnedByUs = false;
+ inQueue.erase(inQueue.begin());
+ inInfo = NULL;
+ notifyEmptyBufferDone(inHeader);
+ inHeader = NULL;
+ }
}
/*
@@ -555,7 +541,6 @@ void SoftAAC2::onQueueFilled(OMX_U32 portIndex) {
// we've previously decoded valid data, in the latter case
// (decode failed) we'll output a silent frame.
outHeader->nFilledLen = numOutBytes;
- outHeader->nFlags = 0;
outHeader->nTimeStamp =
mAnchorTimeUs
@@ -582,6 +567,12 @@ void SoftAAC2::onPortFlushCompleted(OMX_U32 portIndex) {
// depend on fragments from the last one decoded.
// drain all existing data
drainDecoder();
+ // force decoder loop to drop the first decoded buffer by resetting these state variables,
+ // but only if initialization has already happened.
+ if (mInputBufferCount != 0) {
+ mInputBufferCount = 1;
+ mStreamInfo->sampleRate = 0;
+ }
}
}
@@ -606,6 +597,8 @@ void SoftAAC2::onReset() {
mStreamInfo->sampleRate = 0;
mSignalledError = false;
+ mSawInputEos = false;
+ mSignalledOutputEos = false;
mOutputPortSettingsChange = NONE;
}
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC2.h b/media/libstagefright/codecs/aacdec/SoftAAC2.h
index 2d960ab..a7ea1e2 100644
--- a/media/libstagefright/codecs/aacdec/SoftAAC2.h
+++ b/media/libstagefright/codecs/aacdec/SoftAAC2.h
@@ -55,6 +55,8 @@ private:
bool mDecoderHasData;
size_t mInputBufferCount;
bool mSignalledError;
+ bool mSawInputEos;
+ bool mSignalledOutputEos;
int64_t mAnchorTimeUs;
int64_t mNumSamplesOutput;
diff --git a/media/libstagefright/codecs/aacenc/SoftAACEncoder2.cpp b/media/libstagefright/codecs/aacenc/SoftAACEncoder2.cpp
index ff2b503..6093621 100644
--- a/media/libstagefright/codecs/aacenc/SoftAACEncoder2.cpp
+++ b/media/libstagefright/codecs/aacenc/SoftAACEncoder2.cpp
@@ -308,7 +308,7 @@ status_t SoftAACEncoder2::setAudioParams() {
// We call this whenever sample rate, number of channels or bitrate change
// in reponse to setParameter calls.
- ALOGV("setAudioParams: %lu Hz, %lu channels, %lu bps",
+ ALOGV("setAudioParams: %u Hz, %u channels, %u bps",
mSampleRate, mNumChannels, mBitRate);
if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_AOT,
@@ -338,7 +338,7 @@ status_t SoftAACEncoder2::setAudioParams() {
return OK;
}
-void SoftAACEncoder2::onQueueFilled(OMX_U32 portIndex) {
+void SoftAACEncoder2::onQueueFilled(OMX_U32 /* portIndex */) {
if (mSignalledError) {
return;
}
@@ -364,7 +364,7 @@ void SoftAACEncoder2::onQueueFilled(OMX_U32 portIndex) {
OMX_U32 actualBitRate = aacEncoder_GetParam(mAACEncoder, AACENC_BITRATE);
if (mBitRate != actualBitRate) {
- ALOGW("Requested bitrate %lu unsupported, using %lu", mBitRate, actualBitRate);
+ ALOGW("Requested bitrate %u unsupported, using %u", mBitRate, actualBitRate);
}
AACENC_InfoStruct encInfo;
diff --git a/media/libstagefright/codecs/aacenc/src/adj_thr.c b/media/libstagefright/codecs/aacenc/src/adj_thr.c
index ccfe883..471631c 100644
--- a/media/libstagefright/codecs/aacenc/src/adj_thr.c
+++ b/media/libstagefright/codecs/aacenc/src/adj_thr.c
@@ -72,7 +72,7 @@ static void calcThreshExp(Word32 thrExp[MAX_CHANNELS][MAX_GROUPED_SFB],
const Word16 nChannels)
{
Word16 ch, sfb, sfbGrp;
- Word32 *pthrExp, *psfbThre;
+ Word32 *pthrExp = NULL, *psfbThre;
for (ch=0; ch<nChannels; ch++) {
PSY_OUT_CHANNEL *psyOutChan = &psyOutChannel[ch];
for(sfbGrp = 0; sfbGrp < psyOutChan->sfbCnt; sfbGrp+= psyOutChan->sfbPerGroup)
diff --git a/media/libstagefright/codecs/aacenc/src/dyn_bits.c b/media/libstagefright/codecs/aacenc/src/dyn_bits.c
index 7769188..4d763d0 100644
--- a/media/libstagefright/codecs/aacenc/src/dyn_bits.c
+++ b/media/libstagefright/codecs/aacenc/src/dyn_bits.c
@@ -25,7 +25,6 @@
#include "bit_cnt.h"
#include "psy_const.h"
-
/*****************************************************************************
*
* function name: buildBitLookUp
@@ -226,7 +225,7 @@ gmStage2(SECTION_INFO *sectionInfo,
}
while (TRUE) {
- Word16 maxMergeGain, maxNdx, maxNdxNext, maxNdxLast;
+ Word16 maxMergeGain, maxNdx = 0, maxNdxNext, maxNdxLast;
maxMergeGain = findMaxMerge(mergeGainLookUp, sectionInfo, maxSfb, &maxNdx);
diff --git a/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp b/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp
index 3320688..d1b0f76 100644
--- a/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp
+++ b/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp
@@ -274,7 +274,7 @@ static size_t getFrameSize(unsigned FT) {
return frameSize;
}
-void SoftAMR::onQueueFilled(OMX_U32 portIndex) {
+void SoftAMR::onQueueFilled(OMX_U32 /* portIndex */) {
List<BufferInfo *> &inQueue = getPortQueue(0);
List<BufferInfo *> &outQueue = getPortQueue(1);
@@ -428,7 +428,7 @@ void SoftAMR::onQueueFilled(OMX_U32 portIndex) {
}
}
-void SoftAMR::onPortFlushCompleted(OMX_U32 portIndex) {
+void SoftAMR::onPortFlushCompleted(OMX_U32 /* portIndex */) {
}
void SoftAMR::onPortEnableCompleted(OMX_U32 portIndex, bool enabled) {
diff --git a/media/libstagefright/codecs/amrnb/enc/SoftAMRNBEncoder.cpp b/media/libstagefright/codecs/amrnb/enc/SoftAMRNBEncoder.cpp
index 50b739c..9489457 100644
--- a/media/libstagefright/codecs/amrnb/enc/SoftAMRNBEncoder.cpp
+++ b/media/libstagefright/codecs/amrnb/enc/SoftAMRNBEncoder.cpp
@@ -270,7 +270,7 @@ OMX_ERRORTYPE SoftAMRNBEncoder::internalSetParameter(
}
}
-void SoftAMRNBEncoder::onQueueFilled(OMX_U32 portIndex) {
+void SoftAMRNBEncoder::onQueueFilled(OMX_U32 /* portIndex */) {
if (mSignalledError) {
return;
}
diff --git a/media/libstagefright/codecs/amrwbenc/SoftAMRWBEncoder.cpp b/media/libstagefright/codecs/amrwbenc/SoftAMRWBEncoder.cpp
index 9ccb49c..91a512d 100644
--- a/media/libstagefright/codecs/amrwbenc/SoftAMRWBEncoder.cpp
+++ b/media/libstagefright/codecs/amrwbenc/SoftAMRWBEncoder.cpp
@@ -317,7 +317,7 @@ OMX_ERRORTYPE SoftAMRWBEncoder::internalSetParameter(
}
}
-void SoftAMRWBEncoder::onQueueFilled(OMX_U32 portIndex) {
+void SoftAMRWBEncoder::onQueueFilled(OMX_U32 /* portIndex */) {
if (mSignalledError) {
return;
}
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Filt_6k_7k_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Filt_6k_7k_opt.s
index 8451195..f23b5a0 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Filt_6k_7k_opt.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/Filt_6k_7k_opt.s
@@ -29,6 +29,7 @@
.global Filt_6k_7k_asm
.extern voAWB_Copy
.extern fir_6k_7k
+ .hidden fir_6k_7k
Filt_6k_7k_asm:
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/pred_lt4_1_opt.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/pred_lt4_1_opt.s
index ac2dd13..deb7efc 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/pred_lt4_1_opt.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV5E/pred_lt4_1_opt.s
@@ -32,6 +32,7 @@
.section .text
.global pred_lt4_asm
.extern inter4_2
+ .hidden inter4_2
pred_lt4_asm:
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Filt_6k_7k_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Filt_6k_7k_neon.s
index fc42a03..8df0caa 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Filt_6k_7k_neon.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/Filt_6k_7k_neon.s
@@ -28,6 +28,7 @@
.section .text
.global Filt_6k_7k_asm
.extern fir_6k_7k
+ .hidden fir_6k_7k
Filt_6k_7k_asm:
diff --git a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/pred_lt4_1_neon.s b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/pred_lt4_1_neon.s
index 8d2aaf2..67be1ed 100644
--- a/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/pred_lt4_1_neon.s
+++ b/media/libstagefright/codecs/amrwbenc/src/asm/ARMV7/pred_lt4_1_neon.s
@@ -29,6 +29,7 @@
.section .text
.global pred_lt4_asm
.extern inter4_2
+ .hidden inter4_2
pred_lt4_asm:
diff --git a/media/libstagefright/codecs/avc/enc/SoftAVCEncoder.cpp b/media/libstagefright/codecs/avc/enc/SoftAVCEncoder.cpp
index 4a21a3e..27c63c3 100644
--- a/media/libstagefright/codecs/avc/enc/SoftAVCEncoder.cpp
+++ b/media/libstagefright/codecs/avc/enc/SoftAVCEncoder.cpp
@@ -217,7 +217,7 @@ OMX_ERRORTYPE SoftAVCEncoder::initEncParams() {
mHandle->CBAVC_Free = FreeWrapper;
CHECK(mEncParams != NULL);
- memset(mEncParams, 0, sizeof(mEncParams));
+ memset(mEncParams, 0, sizeof(*mEncParams));
mEncParams->rate_control = AVC_ON;
mEncParams->initQP = 0;
mEncParams->init_CBP_removal_delay = 1600;
@@ -342,10 +342,10 @@ OMX_ERRORTYPE SoftAVCEncoder::releaseEncoder() {
PVAVCCleanUpEncoder(mHandle);
releaseOutputBuffers();
- delete mInputFrameData;
+ free(mInputFrameData);
mInputFrameData = NULL;
- delete mSliceGroup;
+ free(mSliceGroup);
mSliceGroup = NULL;
delete mEncParams;
@@ -593,6 +593,17 @@ OMX_ERRORTYPE SoftAVCEncoder::internalSetParameter(
mVideoHeight = def->format.video.nFrameHeight;
mVideoFrameRate = def->format.video.xFramerate >> 16;
mVideoColorFormat = def->format.video.eColorFormat;
+
+ OMX_PARAM_PORTDEFINITIONTYPE *portDef =
+ &editPortInfo(0)->mDef;
+ portDef->format.video.nFrameWidth = mVideoWidth;
+ portDef->format.video.nFrameHeight = mVideoHeight;
+ portDef->format.video.xFramerate = def->format.video.xFramerate;
+ portDef->format.video.eColorFormat =
+ (OMX_COLOR_FORMATTYPE) mVideoColorFormat;
+ portDef = &editPortInfo(1)->mDef;
+ portDef->format.video.nFrameWidth = mVideoWidth;
+ portDef->format.video.nFrameHeight = mVideoHeight;
} else {
mVideoBitRate = def->format.video.nBitrate;
}
@@ -808,9 +819,10 @@ void SoftAVCEncoder::onQueueFilled(OMX_U32 portIndex) {
videoInput.coding_timestamp = (inHeader->nTimeStamp + 500) / 1000; // in ms
uint8_t *inputData = NULL;
if (mStoreMetaDataInBuffers) {
- if (inHeader->nFilledLen != 8) {
+ if (inHeader->nFilledLen != (sizeof(OMX_U32) + sizeof(buffer_handle_t))) {
ALOGE("MetaData buffer is wrong size! "
- "(got %lu bytes, expected 8)", inHeader->nFilledLen);
+ "(got %u bytes, expected %d)", inHeader->nFilledLen,
+ sizeof(OMX_U32) + sizeof(buffer_handle_t));
mSignalledError = true;
notify(OMX_EventError, OMX_ErrorUndefined, 0, 0);
return;
@@ -970,11 +982,11 @@ uint8_t *SoftAVCEncoder::extractGrallocData(void *data, buffer_handle_t *buffer)
status_t res;
if (type != kMetadataBufferTypeGrallocSource) {
ALOGE("Data passed in with metadata mode does not have type "
- "kMetadataBufferTypeGrallocSource (%d), has type %ld instead",
+ "kMetadataBufferTypeGrallocSource (%d), has type %d instead",
kMetadataBufferTypeGrallocSource, type);
return NULL;
}
- buffer_handle_t imgBuffer = *(buffer_handle_t*)((uint8_t*)data + 4);
+ buffer_handle_t imgBuffer = *(buffer_handle_t*)((uint8_t*)data + sizeof(OMX_U32));
const Rect rect(mVideoWidth, mVideoHeight);
uint8_t *img;
diff --git a/media/libstagefright/codecs/avc/enc/src/bitstream_io.cpp b/media/libstagefright/codecs/avc/enc/src/bitstream_io.cpp
index 0e3037f..d71c327 100644
--- a/media/libstagefright/codecs/avc/enc/src/bitstream_io.cpp
+++ b/media/libstagefright/codecs/avc/enc/src/bitstream_io.cpp
@@ -103,6 +103,15 @@ AVCEnc_Status AVCBitstreamSaveWord(AVCEncBitstream *stream)
{
num_bits -= 8;
byte = (current_word >> num_bits) & 0xFF;
+ if (stream->count_zeros == 2)
+ { /* for num_bits = 32, this can add 2 more bytes extra for EPBS */
+ if (byte <= 3)
+ {
+ *write_pnt++ = 0x3;
+ stream->write_pos++;
+ stream->count_zeros = 0;
+ }
+ }
if (byte != 0)
{
*write_pnt++ = byte;
@@ -114,12 +123,6 @@ AVCEnc_Status AVCBitstreamSaveWord(AVCEncBitstream *stream)
stream->count_zeros++;
*write_pnt++ = byte;
stream->write_pos++;
- if (stream->count_zeros == 2)
- { /* for num_bits = 32, this can add 2 more bytes extra for EPBS */
- *write_pnt++ = 0x3;
- stream->write_pos++;
- stream->count_zeros = 0;
- }
}
}
diff --git a/media/libstagefright/codecs/common/Config.mk b/media/libstagefright/codecs/common/Config.mk
index a6d4286..a843cef 100644
--- a/media/libstagefright/codecs/common/Config.mk
+++ b/media/libstagefright/codecs/common/Config.mk
@@ -14,8 +14,10 @@ VOTT := pc
endif
# Do we also need to check on ARCH_ARM_HAVE_ARMV7A? - probably not
-ifeq ($(ARCH_ARM_HAVE_NEON),true)
-VOTT := v7
+ifeq ($(TARGET_ARCH),arm)
+ ifeq ($(ARCH_ARM_HAVE_NEON),true)
+ VOTT := v7
+ endif
endif
VOTEST := 0
diff --git a/media/libstagefright/codecs/common/cmnMemory.c b/media/libstagefright/codecs/common/cmnMemory.c
index aa52bd9..5bb6cc4 100644
--- a/media/libstagefright/codecs/common/cmnMemory.c
+++ b/media/libstagefright/codecs/common/cmnMemory.c
@@ -26,8 +26,12 @@
//VO_MEM_OPERATOR g_memOP;
+#define UNUSED(x) (void)(x)
+
VO_U32 cmnMemAlloc (VO_S32 uID, VO_MEM_INFO * pMemInfo)
{
+ UNUSED(uID);
+
if (!pMemInfo)
return VO_ERR_INVALID_ARG;
@@ -37,34 +41,48 @@ VO_U32 cmnMemAlloc (VO_S32 uID, VO_MEM_INFO * pMemInfo)
VO_U32 cmnMemFree (VO_S32 uID, VO_PTR pMem)
{
+ UNUSED(uID);
+
free (pMem);
return 0;
}
VO_U32 cmnMemSet (VO_S32 uID, VO_PTR pBuff, VO_U8 uValue, VO_U32 uSize)
{
+ UNUSED(uID);
+
memset (pBuff, uValue, uSize);
return 0;
}
VO_U32 cmnMemCopy (VO_S32 uID, VO_PTR pDest, VO_PTR pSource, VO_U32 uSize)
{
+ UNUSED(uID);
+
memcpy (pDest, pSource, uSize);
return 0;
}
VO_U32 cmnMemCheck (VO_S32 uID, VO_PTR pBuffer, VO_U32 uSize)
{
+ UNUSED(uID);
+ UNUSED(pBuffer);
+ UNUSED(uSize);
+
return 0;
}
VO_S32 cmnMemCompare (VO_S32 uID, VO_PTR pBuffer1, VO_PTR pBuffer2, VO_U32 uSize)
{
+ UNUSED(uID);
+
return memcmp(pBuffer1, pBuffer2, uSize);
}
VO_U32 cmnMemMove (VO_S32 uID, VO_PTR pDest, VO_PTR pSource, VO_U32 uSize)
{
+ UNUSED(uID);
+
memmove (pDest, pSource, uSize);
return 0;
}
diff --git a/media/libstagefright/codecs/flac/enc/SoftFlacEncoder.cpp b/media/libstagefright/codecs/flac/enc/SoftFlacEncoder.cpp
index e64fe72..d797197 100644
--- a/media/libstagefright/codecs/flac/enc/SoftFlacEncoder.cpp
+++ b/media/libstagefright/codecs/flac/enc/SoftFlacEncoder.cpp
@@ -204,7 +204,7 @@ OMX_ERRORTYPE SoftFlacEncoder::internalSetParameter(
mNumChannels = pcmParams->nChannels;
mSampleRate = pcmParams->nSamplingRate;
- ALOGV("will encode %ld channels at %ldHz", mNumChannels, mSampleRate);
+ ALOGV("will encode %d channels at %dHz", mNumChannels, mSampleRate);
return configureEncoder();
}
@@ -241,7 +241,7 @@ OMX_ERRORTYPE SoftFlacEncoder::internalSetParameter(
if (defParams->nPortIndex == 0) {
if (defParams->nBufferSize > kMaxInputBufferSize) {
- ALOGE("Input buffer size must be at most %zu bytes",
+ ALOGE("Input buffer size must be at most %d bytes",
kMaxInputBufferSize);
return OMX_ErrorUnsupportedSetting;
}
@@ -257,8 +257,8 @@ OMX_ERRORTYPE SoftFlacEncoder::internalSetParameter(
}
void SoftFlacEncoder::onQueueFilled(OMX_U32 portIndex) {
-
- ALOGV("SoftFlacEncoder::onQueueFilled(portIndex=%ld)", portIndex);
+ //UNUSED_UNLESS_VERBOSE(portIndex);
+ ALOGV("SoftFlacEncoder::onQueueFilled(portIndex=%d)", portIndex);
if (mSignalledError) {
return;
@@ -290,7 +290,7 @@ void SoftFlacEncoder::onQueueFilled(OMX_U32 portIndex) {
}
if (inHeader->nFilledLen > kMaxInputBufferSize) {
- ALOGE("input buffer too large (%ld).", inHeader->nFilledLen);
+ ALOGE("input buffer too large (%d).", inHeader->nFilledLen);
mSignalledError = true;
notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
return;
@@ -363,7 +363,7 @@ FLAC__StreamEncoderWriteStatus SoftFlacEncoder::onEncodedFlacAvailable(
if ((samples == 0) || !mEncoderWriteData) {
// called by the encoder because there's header data to save, but it's not the role
// of this component (unless WRITE_FLAC_HEADER_IN_FIRST_BUFFER is defined)
- ALOGV("ignoring %d bytes of header data (samples=%d)", bytes, samples);
+ ALOGV("ignoring %zu bytes of header data (samples=%d)", bytes, samples);
return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
}
@@ -384,9 +384,9 @@ FLAC__StreamEncoderWriteStatus SoftFlacEncoder::onEncodedFlacAvailable(
#endif
// write encoded data
- ALOGV(" writing %d bytes of encoded data on output port", bytes);
+ ALOGV(" writing %zu bytes of encoded data on output port", bytes);
if (bytes > outHeader->nAllocLen - outHeader->nOffset - outHeader->nFilledLen) {
- ALOGE(" not enough space left to write encoded data, dropping %u bytes", bytes);
+ ALOGE(" not enough space left to write encoded data, dropping %zu bytes", bytes);
// a fatal error would stop the encoding
return FLAC__STREAM_ENCODER_WRITE_STATUS_OK;
}
@@ -405,7 +405,7 @@ FLAC__StreamEncoderWriteStatus SoftFlacEncoder::onEncodedFlacAvailable(
OMX_ERRORTYPE SoftFlacEncoder::configureEncoder() {
- ALOGV("SoftFlacEncoder::configureEncoder() numChannel=%ld, sampleRate=%ld",
+ ALOGV("SoftFlacEncoder::configureEncoder() numChannel=%d, sampleRate=%d",
mNumChannels, mSampleRate);
if (mSignalledError || (mFlacStreamEncoder == NULL)) {
diff --git a/media/libstagefright/codecs/g711/dec/SoftG711.cpp b/media/libstagefright/codecs/g711/dec/SoftG711.cpp
index bcdd3c7..240c0c1 100644
--- a/media/libstagefright/codecs/g711/dec/SoftG711.cpp
+++ b/media/libstagefright/codecs/g711/dec/SoftG711.cpp
@@ -182,7 +182,7 @@ OMX_ERRORTYPE SoftG711::internalSetParameter(
}
}
-void SoftG711::onQueueFilled(OMX_U32 portIndex) {
+void SoftG711::onQueueFilled(OMX_U32 /* portIndex */) {
if (mSignalledError) {
return;
}
@@ -212,7 +212,7 @@ void SoftG711::onQueueFilled(OMX_U32 portIndex) {
}
if (inHeader->nFilledLen > kMaxNumSamplesPerFrame) {
- ALOGE("input buffer too large (%ld).", inHeader->nFilledLen);
+ ALOGE("input buffer too large (%d).", inHeader->nFilledLen);
notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
mSignalledError = true;
diff --git a/media/libstagefright/codecs/gsm/dec/SoftGSM.cpp b/media/libstagefright/codecs/gsm/dec/SoftGSM.cpp
index 00e0c85..4debc48 100644
--- a/media/libstagefright/codecs/gsm/dec/SoftGSM.cpp
+++ b/media/libstagefright/codecs/gsm/dec/SoftGSM.cpp
@@ -172,7 +172,7 @@ OMX_ERRORTYPE SoftGSM::internalSetParameter(
}
}
-void SoftGSM::onQueueFilled(OMX_U32 portIndex) {
+void SoftGSM::onQueueFilled(OMX_U32 /* portIndex */) {
if (mSignalledError) {
return;
}
@@ -202,13 +202,13 @@ void SoftGSM::onQueueFilled(OMX_U32 portIndex) {
}
if (inHeader->nFilledLen > kMaxNumSamplesPerFrame) {
- ALOGE("input buffer too large (%ld).", inHeader->nFilledLen);
+ ALOGE("input buffer too large (%d).", inHeader->nFilledLen);
notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
mSignalledError = true;
}
if(((inHeader->nFilledLen / 65) * 65) != inHeader->nFilledLen) {
- ALOGE("input buffer not multiple of 65 (%ld).", inHeader->nFilledLen);
+ ALOGE("input buffer not multiple of 65 (%d).", inHeader->nFilledLen);
notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
mSignalledError = true;
}
diff --git a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
index fb2a430..0d1ab71 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/SoftMPEG4.cpp
@@ -91,7 +91,7 @@ status_t SoftMPEG4::initDecoder() {
return OK;
}
-void SoftMPEG4::onQueueFilled(OMX_U32 portIndex) {
+void SoftMPEG4::onQueueFilled(OMX_U32 /* portIndex */) {
if (mSignalledError || mOutputPortSettingsChange != NONE) {
return;
}
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/get_pred_adv_b_add.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/get_pred_adv_b_add.cpp
index e23f23d..fe9e7dc 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/src/get_pred_adv_b_add.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/get_pred_adv_b_add.cpp
@@ -96,7 +96,7 @@ int GetPredAdvancedBy0x0(
offset = width - B_SIZE; /* offset for prev */
offset2 = (pred_width_rnd >> 1) - 4; /* offset for pred_block */
- tmp = (uint32)prev & 0x3;
+ tmp = (uintptr_t)prev & 0x3;
pred_block -= offset2; /* preset */
if (tmp == 0) /* word-aligned */
@@ -203,7 +203,7 @@ int GetPredAdvancedBy0x1(
/* Branch based on pixel location (half-pel or full-pel) for x and y */
pred_block -= offset2; /* preset */
- tmp = (uint32)prev & 3;
+ tmp = (uintptr_t)prev & 3;
mask = 254;
mask |= (mask << 8);
mask |= (mask << 16); /* 0xFEFEFEFE */
@@ -532,7 +532,7 @@ int GetPredAdvancedBy1x0(
/* Branch based on pixel location (half-pel or full-pel) for x and y */
pred_block -= offset2; /* preset */
- tmp = (uint32)prev & 3;
+ tmp = (uintptr_t)prev & 3;
mask = 254;
mask |= (mask << 8);
mask |= (mask << 16); /* 0xFEFEFEFE */
@@ -884,7 +884,7 @@ int GetPredAdvancedBy1x1(
mask |= (mask << 8);
mask |= (mask << 16); /* 0x3f3f3f3f */
- tmp = (uint32)prev & 3;
+ tmp = (uintptr_t)prev & 3;
pred_block -= 4; /* preset */
diff --git a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
index e02af90..bf77f4a 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
+++ b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
@@ -33,6 +33,8 @@
#include "SoftMPEG4Encoder.h"
+#include <inttypes.h>
+
namespace android {
template<class T>
@@ -620,7 +622,7 @@ OMX_ERRORTYPE SoftMPEG4Encoder::internalSetParameter(
}
}
-void SoftMPEG4Encoder::onQueueFilled(OMX_U32 portIndex) {
+void SoftMPEG4Encoder::onQueueFilled(OMX_U32 /* portIndex */) {
if (mSignalledError || mSawInputEOS) {
return;
}
@@ -683,7 +685,7 @@ void SoftMPEG4Encoder::onQueueFilled(OMX_U32 portIndex) {
if (mStoreMetaDataInBuffers) {
if (inHeader->nFilledLen != 8) {
ALOGE("MetaData buffer is wrong size! "
- "(got %lu bytes, expected 8)", inHeader->nFilledLen);
+ "(got %u bytes, expected 8)", inHeader->nFilledLen);
mSignalledError = true;
notify(OMX_EventError, OMX_ErrorUndefined, 0, 0);
return;
@@ -719,13 +721,13 @@ void SoftMPEG4Encoder::onQueueFilled(OMX_U32 portIndex) {
vin.uChan = vin.yChan + vin.height * vin.pitch;
vin.vChan = vin.uChan + ((vin.height * vin.pitch) >> 2);
- unsigned long modTimeMs = 0;
+ ULong modTimeMs = 0;
int32_t nLayer = 0;
MP4HintTrack hintTrack;
if (!PVEncodeVideoFrame(mHandle, &vin, &vout,
&modTimeMs, outPtr, &dataLength, &nLayer) ||
!PVGetHintTrack(mHandle, &hintTrack)) {
- ALOGE("Failed to encode frame or get hink track at frame %lld",
+ ALOGE("Failed to encode frame or get hink track at frame %" PRId64,
mNumInputFrames);
mSignalledError = true;
notify(OMX_EventError, OMX_ErrorUndefined, 0, 0);
@@ -771,7 +773,7 @@ uint8_t *SoftMPEG4Encoder::extractGrallocData(void *data, buffer_handle_t *buffe
status_t res;
if (type != kMetadataBufferTypeGrallocSource) {
ALOGE("Data passed in with metadata mode does not have type "
- "kMetadataBufferTypeGrallocSource (%d), has type %ld instead",
+ "kMetadataBufferTypeGrallocSource (%d), has type %d instead",
kMetadataBufferTypeGrallocSource, type);
return NULL;
}
diff --git a/media/libstagefright/codecs/m4v_h263/enc/include/mp4enc_api.h b/media/libstagefright/codecs/m4v_h263/enc/include/mp4enc_api.h
index a54fd8b..9451479 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/include/mp4enc_api.h
+++ b/media/libstagefright/codecs/m4v_h263/enc/include/mp4enc_api.h
@@ -29,7 +29,7 @@ typedef int Int;
typedef unsigned short UShort;
typedef short Short;
typedef unsigned int Bool;
-typedef unsigned long ULong;
+typedef uint32_t ULong;
#define PV_CODEC_INIT 0
#define PV_CODEC_STOP 1
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/dct.cpp b/media/libstagefright/codecs/m4v_h263/enc/src/dct.cpp
index fa50eeb..fa4ae23 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/src/dct.cpp
+++ b/media/libstagefright/codecs/m4v_h263/enc/src/dct.cpp
@@ -250,7 +250,7 @@ extern "C"
out[40] = k4 ; /* row 5 */
out++;
}
- while ((UInt)out < (UInt)dst) ;
+ while ((uintptr_t)out < (uintptr_t)dst) ;
return ;
}
@@ -455,7 +455,7 @@ extern "C"
out[8] = k5 ; /* row 1 */
out++;
}
- while ((UInt)out < (UInt)dst) ;
+ while ((uintptr_t)out < (uintptr_t)dst) ;
return ;
}
@@ -635,7 +635,7 @@ extern "C"
out[8] = k5 ; /* row 1 */
out++;
}
- while ((UInt)out < (UInt)dst) ;
+ while ((uintptr_t)out < (uintptr_t)dst) ;
return ;
}
@@ -846,7 +846,7 @@ extern "C"
out[40] = k4 ; /* row 5 */
out++;
}
- while ((UInt)out < (UInt)dst) ;
+ while ((uintptr_t)out < (uintptr_t)dst) ;
return ;
}
@@ -1033,7 +1033,7 @@ extern "C"
out[8] = k5 ; /* row 1 */
out++;
}
- while ((UInt)out < (UInt)dst) ;
+ while ((uintptr_t)out < (uintptr_t)dst) ;
return ;
}
@@ -1195,7 +1195,7 @@ extern "C"
out[8] = k5 ; /* row 1 */
out++;
}
- while ((UInt)out < (UInt)dst) ;
+ while ((uintptr_t)out < (uintptr_t)dst) ;
return ;
}
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/fastcodemb.cpp b/media/libstagefright/codecs/m4v_h263/enc/src/fastcodemb.cpp
index 6fd41c3..0ad39a6 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/src/fastcodemb.cpp
+++ b/media/libstagefright/codecs/m4v_h263/enc/src/fastcodemb.cpp
@@ -572,7 +572,7 @@ Int Sad8x8(UChar *cur, UChar *prev, Int width)
cur2 = cur2 & (mask << 8); /* mask first and third bytes */
sum2 = sum2 + ((UInt)cur2 >> 8);
}
- while ((UInt)curInt < (UInt)end);
+ while ((uintptr_t)curInt < (uintptr_t)end);
cur1 = sum4 - (sum2 << 8); /* get even-sum */
cur1 = cur1 + sum2; /* add 16 bit even-sum and odd-sum*/
@@ -611,7 +611,7 @@ Int getBlockSum(UChar *cur, Int width)
load2 = load2 & (mask << 8); /* even bytes */
sum2 += ((UInt)load2 >> 8); /* sum even bytes, 16 bit */
}
- while ((UInt)curInt < (UInt)end);
+ while ((uintptr_t)curInt < (uintptr_t)end);
load1 = sum4 - (sum2 << 8); /* get even-sum */
load1 = load1 + sum2; /* add 16 bit even-sum and odd-sum*/
load1 = load1 + (load1 << 16); /* add upper and lower 16 bit sum */
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/motion_comp.cpp b/media/libstagefright/codecs/m4v_h263/enc/src/motion_comp.cpp
index b81d278..9a967c2 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/src/motion_comp.cpp
+++ b/media/libstagefright/codecs/m4v_h263/enc/src/motion_comp.cpp
@@ -363,7 +363,7 @@ Int GetPredAdvBy0x0(
/* initialize offset to adjust pixel counter */
/* the next row; full-pel resolution */
- tmp = (ULong)prev & 0x3;
+ tmp = (uintptr_t)prev & 0x3;
if (tmp == 0) /* word-aligned */
{
@@ -466,7 +466,7 @@ Int GetPredAdvBy0x1(
/* Branch based on pixel location (half-pel or full-pel) for x and y */
rec -= 12; /* preset */
- tmp = (ULong)prev & 3;
+ tmp = (uintptr_t)prev & 3;
mask = 254;
mask |= (mask << 8);
mask |= (mask << 16); /* 0xFEFEFEFE */
@@ -791,7 +791,7 @@ Int GetPredAdvBy1x0(
/* Branch based on pixel location (half-pel or full-pel) for x and y */
rec -= 12; /* preset */
- tmp = (ULong)prev & 3;
+ tmp = (uintptr_t)prev & 3;
mask = 254;
mask |= (mask << 8);
mask |= (mask << 16); /* 0xFEFEFEFE */
@@ -1140,7 +1140,7 @@ Int GetPredAdvBy1x1(
mask |= (mask << 8);
mask |= (mask << 16); /* 0x3f3f3f3f */
- tmp = (ULong)prev & 3;
+ tmp = (uintptr_t)prev & 3;
rec -= 4; /* preset */
@@ -1959,7 +1959,7 @@ void PutSkippedBlock(UChar *rec, UChar *prev, Int lx)
dst += offset;
src += offset;
}
- while ((UInt)src < (UInt)end);
+ while ((uintptr_t)src < (uintptr_t)end);
return ;
}
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/mp4def.h b/media/libstagefright/codecs/m4v_h263/enc/src/mp4def.h
index 0d5a3e8..2d44482 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/src/mp4def.h
+++ b/media/libstagefright/codecs/m4v_h263/enc/src/mp4def.h
@@ -60,7 +60,7 @@ typedef unsigned short UShort;
typedef short Short;
typedef short int SInt;
typedef unsigned int Bool;
-typedef unsigned long ULong;
+typedef uint32_t ULong;
typedef void Void;
#define PV_CODEC_INIT 0
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/sad_inline.h b/media/libstagefright/codecs/m4v_h263/enc/src/sad_inline.h
index ba77dfd..b865f23 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/src/sad_inline.h
+++ b/media/libstagefright/codecs/m4v_h263/enc/src/sad_inline.h
@@ -85,7 +85,7 @@ extern "C"
x9 = 0x80808080; /* const. */
- x8 = (uint32)ref & 0x3;
+ x8 = (uintptr_t)ref & 0x3;
if (x8 == 3)
goto SadMBOffset3;
if (x8 == 2)
diff --git a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
index 7c382fb..4d864df 100644
--- a/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
+++ b/media/libstagefright/codecs/mp3dec/SoftMP3.cpp
@@ -49,6 +49,8 @@ SoftMP3::SoftMP3(
mNumChannels(2),
mSamplingRate(44100),
mSignalledError(false),
+ mSawInputEos(false),
+ mSignalledOutputEos(false),
mOutputPortSettingsChange(NONE) {
initPorts();
initDecoder();
@@ -186,7 +188,7 @@ OMX_ERRORTYPE SoftMP3::internalSetParameter(
}
}
-void SoftMP3::onQueueFilled(OMX_U32 portIndex) {
+void SoftMP3::onQueueFilled(OMX_U32 /* portIndex */) {
if (mSignalledError || mOutputPortSettingsChange != NONE) {
return;
}
@@ -194,48 +196,36 @@ void SoftMP3::onQueueFilled(OMX_U32 portIndex) {
List<BufferInfo *> &inQueue = getPortQueue(0);
List<BufferInfo *> &outQueue = getPortQueue(1);
- while (!inQueue.empty() && !outQueue.empty()) {
- BufferInfo *inInfo = *inQueue.begin();
- OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
+ while ((!inQueue.empty() || (mSawInputEos && !mSignalledOutputEos)) && !outQueue.empty()) {
+ BufferInfo *inInfo = NULL;
+ OMX_BUFFERHEADERTYPE *inHeader = NULL;
+ if (!inQueue.empty()) {
+ inInfo = *inQueue.begin();
+ inHeader = inInfo->mHeader;
+ }
BufferInfo *outInfo = *outQueue.begin();
OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
+ outHeader->nFlags = 0;
- if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
- inQueue.erase(inQueue.begin());
- inInfo->mOwnedByUs = false;
- notifyEmptyBufferDone(inHeader);
-
- if (!mIsFirst) {
- // pad the end of the stream with 529 samples, since that many samples
- // were trimmed off the beginning when decoding started
- outHeader->nFilledLen =
- kPVMP3DecoderDelay * mNumChannels * sizeof(int16_t);
+ if (inHeader) {
+ if (inHeader->nOffset == 0 && inHeader->nFilledLen) {
+ mAnchorTimeUs = inHeader->nTimeStamp;
+ mNumFramesOutput = 0;
+ }
- memset(outHeader->pBuffer, 0, outHeader->nFilledLen);
- } else {
- // Since we never discarded frames from the start, we won't have
- // to add any padding at the end either.
- outHeader->nFilledLen = 0;
+ if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
+ mSawInputEos = true;
}
- outHeader->nFlags = OMX_BUFFERFLAG_EOS;
+ mConfig->pInputBuffer =
+ inHeader->pBuffer + inHeader->nOffset;
- outQueue.erase(outQueue.begin());
- outInfo->mOwnedByUs = false;
- notifyFillBufferDone(outHeader);
- return;
- }
-
- if (inHeader->nOffset == 0) {
- mAnchorTimeUs = inHeader->nTimeStamp;
- mNumFramesOutput = 0;
+ mConfig->inputBufferCurrentLength = inHeader->nFilledLen;
+ } else {
+ mConfig->pInputBuffer = NULL;
+ mConfig->inputBufferCurrentLength = 0;
}
-
- mConfig->pInputBuffer =
- inHeader->pBuffer + inHeader->nOffset;
-
- mConfig->inputBufferCurrentLength = inHeader->nFilledLen;
mConfig->inputBufferMaxLength = 0;
mConfig->inputBufferUsedLength = 0;
@@ -262,13 +252,28 @@ void SoftMP3::onQueueFilled(OMX_U32 portIndex) {
mConfig->outputFrameSize = kOutputBufferSize / sizeof(int16_t);
}
- // This is recoverable, just ignore the current frame and
- // play silence instead.
- memset(outHeader->pBuffer,
- 0,
- mConfig->outputFrameSize * sizeof(int16_t));
-
- mConfig->inputBufferUsedLength = inHeader->nFilledLen;
+ if (decoderErr == NO_ENOUGH_MAIN_DATA_ERROR && mSawInputEos) {
+ if (!mIsFirst) {
+ // pad the end of the stream with 529 samples, since that many samples
+ // were trimmed off the beginning when decoding started
+ outHeader->nOffset = 0;
+ outHeader->nFilledLen = kPVMP3DecoderDelay * mNumChannels * sizeof(int16_t);
+
+ memset(outHeader->pBuffer, 0, outHeader->nFilledLen);
+ }
+ outHeader->nFlags = OMX_BUFFERFLAG_EOS;
+ mSignalledOutputEos = true;
+ } else {
+ // This is recoverable, just ignore the current frame and
+ // play silence instead.
+ memset(outHeader->pBuffer,
+ 0,
+ mConfig->outputFrameSize * sizeof(int16_t));
+
+ if (inHeader) {
+ mConfig->inputBufferUsedLength = inHeader->nFilledLen;
+ }
+ }
} else if (mConfig->samplingRate != mSamplingRate
|| mConfig->num_channels != mNumChannels) {
mSamplingRate = mConfig->samplingRate;
@@ -289,7 +294,7 @@ void SoftMP3::onQueueFilled(OMX_U32 portIndex) {
outHeader->nFilledLen =
mConfig->outputFrameSize * sizeof(int16_t) - outHeader->nOffset;
- } else {
+ } else if (!mSignalledOutputEos) {
outHeader->nOffset = 0;
outHeader->nFilledLen = mConfig->outputFrameSize * sizeof(int16_t);
}
@@ -298,23 +303,24 @@ void SoftMP3::onQueueFilled(OMX_U32 portIndex) {
mAnchorTimeUs
+ (mNumFramesOutput * 1000000ll) / mConfig->samplingRate;
- outHeader->nFlags = 0;
-
- CHECK_GE(inHeader->nFilledLen, mConfig->inputBufferUsedLength);
+ if (inHeader) {
+ CHECK_GE(inHeader->nFilledLen, mConfig->inputBufferUsedLength);
- inHeader->nOffset += mConfig->inputBufferUsedLength;
- inHeader->nFilledLen -= mConfig->inputBufferUsedLength;
+ inHeader->nOffset += mConfig->inputBufferUsedLength;
+ inHeader->nFilledLen -= mConfig->inputBufferUsedLength;
- mNumFramesOutput += mConfig->outputFrameSize / mNumChannels;
- if (inHeader->nFilledLen == 0) {
- inInfo->mOwnedByUs = false;
- inQueue.erase(inQueue.begin());
- inInfo = NULL;
- notifyEmptyBufferDone(inHeader);
- inHeader = NULL;
+ if (inHeader->nFilledLen == 0) {
+ inInfo->mOwnedByUs = false;
+ inQueue.erase(inQueue.begin());
+ inInfo = NULL;
+ notifyEmptyBufferDone(inHeader);
+ inHeader = NULL;
+ }
}
+ mNumFramesOutput += mConfig->outputFrameSize / mNumChannels;
+
outInfo->mOwnedByUs = false;
outQueue.erase(outQueue.begin());
outInfo = NULL;
@@ -362,6 +368,8 @@ void SoftMP3::onReset() {
pvmp3_InitDecoder(mConfig, mDecoderBuf);
mIsFirst = true;
mSignalledError = false;
+ mSawInputEos = false;
+ mSignalledOutputEos = false;
mOutputPortSettingsChange = NONE;
}
diff --git a/media/libstagefright/codecs/mp3dec/SoftMP3.h b/media/libstagefright/codecs/mp3dec/SoftMP3.h
index 4af91ea..f9e7b53 100644
--- a/media/libstagefright/codecs/mp3dec/SoftMP3.h
+++ b/media/libstagefright/codecs/mp3dec/SoftMP3.h
@@ -61,6 +61,8 @@ private:
bool mIsFirst;
bool mSignalledError;
+ bool mSawInputEos;
+ bool mSignalledOutputEos;
enum {
NONE,
diff --git a/media/libstagefright/codecs/mp3dec/src/asm/pvmp3_dct_9_arm.s b/media/libstagefright/codecs/mp3dec/src/asm/pvmp3_dct_9_arm.s
deleted file mode 100644
index 3a6dd4f..0000000
--- a/media/libstagefright/codecs/mp3dec/src/asm/pvmp3_dct_9_arm.s
+++ /dev/null
@@ -1,210 +0,0 @@
-; ------------------------------------------------------------------
-; Copyright (C) 1998-2009 PacketVideo
-;
-; Licensed under the Apache License, Version 2.0 (the "License");
-; you may not use this file except in compliance with the License.
-; You may obtain a copy of the License at
-;
-; http://www.apache.org/licenses/LICENSE-2.0
-;
-; Unless required by applicable law or agreed to in writing, software
-; distributed under the License is distributed on an "AS IS" BASIS,
-; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
-; express or implied.
-; See the License for the specific language governing permissions
-; and limitations under the License.
-; -------------------------------------------------------------------
-
-;
-;
-; Filename: pvmp3_dct_9.s
-;
-;------------------------------------------------------------------------------
-; REVISION HISTORY
-;
-;
-; Who: Date: MM/DD/YYYY
-; Description:
-;
-;------------------------------------------------------------------------------
-
- AREA |.drectve|, DRECTVE
-
- DCB "-defaultlib:coredll.lib "
- DCB "-defaultlib:corelibc.lib "
-
- IMPORT pvmp3_mdct_18 ; pvmp3_mdct_18.cpp
-
-;------------------------------------------------------------------------------
-
- AREA |.rdata|, DATA, READONLY
- % 4
-
-
-;------------------------------------------------------------------------------
-
- AREA |.text|, CODE, READONLY
-
-
-;------------------------------------------------------------------------------
-
- EXPORT |pvmp3_dct_9|
-
-|pvmp3_dct_9| PROC
- stmfd sp!,{r4-r10,lr}
- ldr r2, [r0, #0x20]
- ldr r3, [r0]
- ldr r12,[r0, #4]
- add r1,r2,r3
- sub lr,r2,r3
- ldr r3,[r0, #0x1c]
- ldr r4,[r0, #0x18]
- add r2,r3,r12
- ldr r5,[r0,#8]
- sub r3,r3,r12
- add r12,r4,r5
- sub r4,r4,r5
- ldr r5,[r0, #0x14]
- ldr r7,[r0, #0xc]
- ldr r9,[r0, #0x10]
- add r6,r5,r7
- sub r5,r5,r7
- add r7,r1,r12
- add r8,r9,r2
- add r7,r7,r6
- add r10,r7,r8
- rsb r7,r8,r7,asr #1
- str r7,[r0, #0x18]
- rsb r2,r9,r2,asr #1
- str r10,[r0]
- ldr r11,|cos_2pi_9|
- rsb r7,r2,#0
-
- mov r9,r1,lsl #1
- mov r1,r9 ;;;;;; !!!!!!
- mov r8,r7
-
-; vec[4] = fxp_mac32_Q32( vec[4], tmp0<<1, cos_2pi_9);
-
- smlal r1,r8,r11,r9
- ldr r10,|cos_4pi_9|
- ldr r11,|cos_pi_9|
-
-; vec[8] = fxp_mac32_Q32( vec[8], tmp0<<1, cos_4pi_9);
-
- smlal r1,r7,r10,r9
-
-
-
-; vec[2] = fxp_mac32_Q32( vec[2], tmp0<<1, cos_pi_9);
-
- smlal r9,r2,r11,r9
- mov r1,r12,lsl #1
- rsb r9,r10,#0
- ldr r11,|cos_5pi_9|
-
- smlal r12,r2,r9,r1
-
-
-
-; vec[2] = fxp_mac32_Q32( vec[2], tmp2<<1, cos_5pi_9);
-
- ldr r9,|cos_2pi_9|
- mov r12,r1 ;;;;;; !!!!!!
- smlal r12,r8,r11,r1
-
-
-; vec[8] = fxp_mac32_Q32( vec[8], tmp2<<1, cos_2pi_9);
-
- smlal r1,r7,r9,r1
- mov r1,r6,lsl #1
- smlal r12,r7,r11,r1
- and r6,r10,r11,asr #14
- smlal r12,r8,r6,r1
- ldr r10,|cos_11pi_18|
- add r12,r11,r6
- smlal r1,r2,r12,r1
- ldr r9,|cos_8pi_9|
- str r2,[r0,#8]
- mov r1,r5,lsl #1
-
-; vec[8] = fxp_mac32_Q32( vec[8], tmp3<<1, cos_8pi_9);
-
- smull r2,r6,r9,r1
- str r7,[r0,#0x20]
- mov r2,r4,lsl #1
- ldr r7,|cos_13pi_18|
- smlal r12,r6,r10,r2
-
- mov r3,r3,lsl #1
-
-; vec[5] = fxp_mac32_Q32( vec[5], tmp8<<1, cos_13pi_18);
-
- smlal r12,r6,r7,r3
- add r4,r5,r4
- mov r12,lr,lsl #1
- sub lr,r4,lr
- ldr r7,|cos_17pi_18|
- str r8,[r0, #0x10]
- ldr r4,|cos_pi_6|
-
- mov lr,lr,lsl #1
-
-; vec[1] = fxp_mac32_Q32( vec[1], tmp8<<1, cos_17pi_18);
-
- smlal r8,r6,r7,r12
-
-; vec[3] = fxp_mul32_Q32((tmp5 + tmp6 - tmp8)<<1, cos_pi_6);
-
- smull r5,lr,r4,lr
- str r6,[r0, #4]
- str lr,[r0, #0xc]
-
-
-; vec[5] = fxp_mul32_Q32(tmp5<<1, cos_17pi_18);
- smull r5,lr,r7,r1
- rsb r6,r9,#0
-; vec[5] = fxp_mac32_Q32( vec[5], tmp6<<1, cos_7pi_18);
- smlal r5,lr,r6,r2
-; vec[5] = fxp_mac32_Q32( vec[5], tmp7<<1, cos_pi_6);
- smlal r5,lr,r4,r3
-; vec[5] = fxp_mac32_Q32( vec[5], tmp8<<1, cos_13pi_18);
- smlal r5,lr,r10,r12
- str lr,[r0, #0x14]
- rsb lr,r10,#0
-
-; vec[7] = fxp_mul32_Q32(tmp5<<1, cos_5pi_18);
- smull r5,r1,lr,r1
-; vec[7] = fxp_mac32_Q32( vec[7], tmp6<<1, cos_17pi_18);
- smlal r2,r1,r7,r2
-; vec[7] = fxp_mac32_Q32( vec[7], tmp7<<1, cos_pi_6);
- smlal r3,r1,r4,r3
-; vec[7] = fxp_mac32_Q32( vec[7], tmp8<<1, cos_11pi_18);
- smlal r12,r1,r9,r12
- str r1,[r0, #0x1c]
- ldmfd sp!,{r4-r10,pc}
-|cos_2pi_9|
- DCD 0x620dbe80
-|cos_4pi_9|
- DCD 0x163a1a80
-|cos_pi_9|
- DCD 0x7847d900
-|cos_5pi_9|
- DCD 0x87b82700
-|cos_8pi_9|
- DCD 0xd438af00
-|cos_11pi_18|
- DCD 0xadb92280
-|cos_13pi_18|
- DCD 0x91261480
-|cos_17pi_18|
- DCD 0x81f1d200
-|cos_pi_6|
- DCD 0x6ed9eb80
- ENDP
-
-
-
-
-
- END
diff --git a/media/libstagefright/codecs/mp3dec/src/asm/pvmp3_mdct_18_arm.s b/media/libstagefright/codecs/mp3dec/src/asm/pvmp3_mdct_18_arm.s
deleted file mode 100644
index 9401d8c..0000000
--- a/media/libstagefright/codecs/mp3dec/src/asm/pvmp3_mdct_18_arm.s
+++ /dev/null
@@ -1,369 +0,0 @@
-; ------------------------------------------------------------------
-; Copyright (C) 1998-2009 PacketVideo
-;
-; Licensed under the Apache License, Version 2.0 (the "License");
-; you may not use this file except in compliance with the License.
-; You may obtain a copy of the License at
-;
-; http://www.apache.org/licenses/LICENSE-2.0
-;
-; Unless required by applicable law or agreed to in writing, software
-; distributed under the License is distributed on an "AS IS" BASIS,
-; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
-; express or implied.
-; See the License for the specific language governing permissions
-; and limitations under the License.
-; -------------------------------------------------------------------
-
-;
-;
-; Filename: pvmp3_dct_18.s
-;
-;------------------------------------------------------------------------------
-; REVISION HISTORY
-;
-;
-; Who: Date: MM/DD/YYYY
-; Description:
-;
-;------------------------------------------------------------------------------
-
- EXPORT pvmp3_mdct_18
-
- IMPORT ||Lib$$Request$$armlib|| [WEAK]
- IMPORT ||Lib$$Request$$cpplib|| [WEAK]
- IMPORT pvmp3_dct_9
-
-
-;------------------------------------------------------------------------------
-
- AREA |.text|, CODE, READONLY, ALIGN=2
-
-
-;------------------------------------------------------------------------------
-
-|pvmp3_mdct_18| PROC
- stmfd sp!,{r4-r10,lr}
- mov r7,r2
- ldr r2,table
- mov r6,r1
- add r3,r2,#0x24
- add r12,r3,#0x44
- add r1,r0,#0x44
- mov r5,r0
-
-; for ( i=9; i!=0; i--)
-; {
-
- mov r4,#9
-Loop_1
-
-; tmp = *(pt_vec);
-; tmp1 = *(pt_vec_o);
-
- ldr lr,[r0] ;; tmp == lr
- ldr r8,[r3],#4 ;; tmp1 == r8
-
-; tmp = fxp_mul32_Q32( tmp<<1, *(pt_cos++ ));
-; tmp1 = fxp_mul32_Q27( tmp1, *(pt_cos_x--));
-
- mov lr,lr,lsl #1
- smull r10,lr,r8,lr
- ldr r8,[r12],#-4
- ldr r9,[r1]
- subs r4,r4,#1
- smull r9,r10,r8,r9
- mov r8,r9,lsr #27
- add r8,r8,r10,lsl #5
-
-; *(pt_vec++) = tmp + tmp1 ;
-; *(pt_vec_o--) = fxp_mul32_Q28( (tmp - tmp1), *(pt_cos_split++));
-
- add r9,lr,r8
- sub r8,lr,r8
- ldr lr,[r2],#4
- str r9,[r0],#4
- smull r8,r9,lr,r8
- mov lr,r8,lsr #28
- add lr,lr,r9,lsl #4
- str lr,[r1],#-4
- bne Loop_1
-
-; }
-
- mov r0,r5 ;; r0 = vec
- bl pvmp3_dct_9
- add r0,r5,#0x24 ;; r0 = &vec[9]
- bl pvmp3_dct_9
-
- ldr r0,[r5,#0x20]
- ldr r2,[r5,#0x40]
- str r0,[r5,#0x40]
- ldr r0,[r5,#0x1c]
- ldr r3,[r5,#0x38]
- str r0,[r5,#0x38]
- ldr r1,[r5,#0x18]
- ldr r0,[r5,#0x30]
- str r1,[r5,#0x30]
- ldr r12,[r5,#0x14]
- ldr r1,[r5,#0x28]
- str r12,[r5,#0x28]
- ldr r12,[r5,#0x10]
- str r12,[r5,#0x20]
- ldr r12,[r5,#0xc]
- str r12,[r5,#0x18]
- ldr r12,[r5,#8]
- str r12,[r5,#0x10]
- ldr r12,[r5,#4]
- str r12,[r5,#8]
- ldr r12,[r5,#0x24]
- sub r12,r12,r1
- str r12,[r5,#4]
- ldr r12,[r5,#0x2c]
- sub r1,r12,r1
- str r1,[r5,#0xc]
- sub r1,r12,r0
- str r1,[r5,#0x14]
- ldr r1,[r5,#0x34]
- sub r0,r1,r0
- str r0,[r5,#0x1c]
- sub r0,r1,r3
- str r0,[r5,#0x24]
- ldr r1,[r5,#0x3c]
- sub r3,r1,r3
- sub r1,r1,r2
- str r1,[r5,#0x34]
- str r3,[r5,#0x2c]
- ldr r1,[r5,#0x44]
- sub r1,r1,r2
- str r1,[r5,#0x3c]
- ldr r12,[r5,#0]
-
-Loop_2
- add r1,r5,r4,lsl #2
- ldr r2,[r1,#0x28]
- ldr r3,[r6,r4,lsl #2]
- add r0,r0,r2
- str r0,[r1,#0x28]
- ldr lr,[r7,r4,lsl #2]
- ldr r1,[r1,#4]
- smlal r0,r3,lr,r0
- mov r0,r2
- add r2,r12,r1
- rsb r2,r2,#0
- str r3,[r5,r4,lsl #2]
- str r2,[r6,r4,lsl #2]
- add r4,r4,#1
- cmp r4,#6
- mov r12,r1
-
- blt Loop_2
-
- ldr r1,[r5,#0x40]
- ldr r2,[r6,#0x18]
- add r3,r0,r1
- str r3,[r5,#0x40]
- ldr lr,[r7,r4,lsl #2]
- mov r3,r3,lsl #1
- ldr r0,[r5,#0x1c]
- smlal r3,r2,lr,r3
- add r3,r12,r0
- str r2,[r5,#0x18]
- ldr r2,[r6,#0x1c]
- rsb r3,r3,#0
- str r3,[r6,#0x18]
- ldr r3,[r5,#0x20]
- add r0,r3,r0
- rsb r0,r0,#0
- str r0,[r6,#0x1c]
- ldr r3,[r5,#0x44]
- ldr r0,[r6,#0x20]
- add r3,r3,r1
- mov r1,r2
- ldr r10,[r7,#0x1c]
- mov r2,r3,lsl #1
- smlal r12,r1,r10,r2
- str r1,[r5,#0x1c]
- ldr r1,[r5,#0x20]
- ldr r3,[r5,#0x24]
- add r1,r1,r3
- rsb r1,r1,#0
- str r1,[r6,#0x20]
- ldr r1,[r5,#0x44]
- ldr r3,[r7,#0x20]
- mov r1,r1,lsl #1
- smlal r12,r0,r3,r1
- ldr lr,[r7,#0x24]
- ldr r3,[r6,#0x24]
- str r0,[r5,#0x20]
- smlal r1,r3,lr,r1
- ldr r0,[r6,#0x40]
- ldr r12,[r6,#0x44]
- str r3,[r5,#0x24]
- ldr r1,[r5,#0x28]
- ldr r3,[r7,#0x44]
- mov r1,r1,lsl #1
- smlal r1,r12,r3,r1
- ldr r1,[r5,#0x40]
- str r12,[r5,#0x44]
- rsb r8,r1,#0
- str r8,[r5,#0x28]
- ldr r1,[r5,#0x2c]
- ldr r3,[r7,#0x40]
- mov r1,r1,lsl #1
- smlal r1,r0,r3,r1
- str r0,[r5,#0x40]
- ldr r0,[r5,#0x3c]
- ldr r1,[r6,#0x38]
- ldr r3,[r6,#0x3c]
- rsb r9,r0,#0
- str r9,[r5,#0x2c]
- ldr r0,[r5,#0x30]
- ldr r12,[r7,#0x3c]
- mov r0,r0,lsl #1
- smlal r0,r3,r12,r0
- str r3,[r5,#0x3c]
- ldr r0,[r5,#0x38]
- rsb r0,r0,#0
- str r0,[r5,#0x30]
- ldr r3,[r5,#0x34]
- ldr r12,[r7,#0x38]
- mov r3,r3,lsl #1
- smlal r3,r1,r12,r3
- mov r0,r0,lsl #1
- str r1,[r5,#0x38]
- ldr r4,[r7,#0x34]
- ldr r1,[r6,#0x34]
- ldr r3,[r6,#0x30]
- smlal r0,r1,r4,r0
- ldr r12,[r6,#0x2c]
- ldr lr,[r6,#0x28]
- str r1,[r5,#0x34]
- ldr r1,[r7,#0x30]
- mov r0,r9,lsl #1
- smlal r0,r3,r1,r0
- mov r0,r8,lsl #1
- ldr r1,[r7,#0x2c]
- str r3,[r5,#0x30]
- smlal r0,r12,r1,r0
- ldr r0,[r7,#0x28]
- str r12,[r5,#0x2c]
- smlal r2,lr,r0,r2
- str lr,[r5,#0x28]
- ldr r1,[r6,#4]
- ldr r12,[r7,#0x48]
- mov r2,r1,lsl #1
- ldr r1,[r6,#0x20]
- ldr r0,[r6]
- mov r1,r1,lsl #1
- smull r4,lr,r12,r1
- ldr r3,[r6,#0x1c]
- str lr,[r6]
- ldr r12,[r7,#0x4c]
- mov r3,r3,lsl #1
- smull r4,lr,r12,r3
- mov r0,r0,lsl #1
- ldr r12,[r7,#0x64]
- str lr,[r6,#4]
- smull r4,lr,r12,r2
- ldr r12,[r7,#0x68]
- str lr,[r6,#0x1c]
- smull r4,lr,r12,r0
- ldr r12,[r7,#0x6c]
- str lr,[r6,#0x20]
- smull lr,r0,r12,r0
- ldr r12,[r7,#0x70]
- str r0,[r6,#0x24]
- smull r0,r2,r12,r2
- ldr r0,[r7,#0x88]
- str r2,[r6,#0x28]
- smull r3,r2,r0,r3
- ldr r0,[r7,#0x8c]
- str r2,[r6,#0x40]
- smull r2,r1,r0,r1
- str r1,[r6,#0x44]
- ldr r0,[r6,#0x18]
- ldr lr,[r7,#0x50]
- mov r1,r0,lsl #1
- ldr r0,[r6,#0x14]
- smull r5,r4,lr,r1
- ldr r12,[r6,#0x10]
- mov r3,r0,lsl #1
- ldr r0,[r6,#0xc]
- mov r12,r12,lsl #1
- mov r2,r0,lsl #1
- ldr r0,[r6,#8]
- str r4,[r6,#8]
- ldr lr,[r7,#0x54]
- mov r0,r0,lsl #1
- smull r5,r4,lr,r3
- ldr lr,[r7,#0x58]
- str r4,[r6,#0xc]
- smull r5,r4,lr,r12
- ldr lr,[r7,#0x5c]
- str r4,[r6,#0x10]
- smull r5,r4,lr,r2
- ldr lr,[r7,#0x60]
- str r4,[r6,#0x14]
- smull r5,r4,lr,r0
- ldr lr,[r7,#0x74]
- str r4,[r6,#0x18]
- smull r4,r0,lr,r0
- ldr lr,[r7,#0x78]
- str r0,[r6,#0x2c]
- smull r0,r2,lr,r2
- ldr r0,[r7,#0x7c]
- str r2,[r6,#0x30]
- smull r12,r2,r0,r12
- ldr r0,[r7,#0x80]
- str r2,[r6,#0x34]
- smull r3,r2,r0,r3
- ldr r0,[r7,#0x84]
- str r2,[r6,#0x38]
- smull r2,r1,r0,r1
- str r1,[r6,#0x3c]
- ldmfd sp!,{r4-r10,pc}
-table
- DCD ||.constdata$1||
- ENDP
-
-;------------------------------------------------------------------------------
-
- AREA |.constdata|, DATA, READONLY, ALIGN=2
-
-;------------------------------------------------------------------------------
-
-||.constdata$1||
-cosTerms_dct18
- DCD 0x0807d2b0
- DCD 0x08483ee0
- DCD 0x08d3b7d0
- DCD 0x09c42570
- DCD 0x0b504f30
- DCD 0x0df29440
- DCD 0x12edfb20
- DCD 0x1ee8dd40
- DCD 0x5bca2a00
-cosTerms_1_ov_cos_phi
- DCD 0x400f9c00
- DCD 0x408d6080
- DCD 0x418dcb80
- DCD 0x431b1a00
- DCD 0x4545ea00
- DCD 0x48270680
- DCD 0x4be25480
- DCD 0x50ab9480
- DCD 0x56ce4d80
- DCD 0x05ebb630
- DCD 0x06921a98
- DCD 0x0771d3a8
- DCD 0x08a9a830
- DCD 0x0a73d750
- DCD 0x0d4d5260
- DCD 0x127b1ca0
- DCD 0x1ea52b40
- DCD 0x5bb3cc80
-
-
-
- END
diff --git a/media/libstagefright/codecs/mp3dec/src/asm/pvmp3_mdct_18_wm.asm b/media/libstagefright/codecs/mp3dec/src/asm/pvmp3_mdct_18_wm.asm
deleted file mode 100644
index 5be75d4..0000000
--- a/media/libstagefright/codecs/mp3dec/src/asm/pvmp3_mdct_18_wm.asm
+++ /dev/null
@@ -1,366 +0,0 @@
-; ------------------------------------------------------------------
-; Copyright (C) 1998-2009 PacketVideo
-;
-; Licensed under the Apache License, Version 2.0 (the "License");
-; you may not use this file except in compliance with the License.
-; You may obtain a copy of the License at
-;
-; http://www.apache.org/licenses/LICENSE-2.0
-;
-; Unless required by applicable law or agreed to in writing, software
-; distributed under the License is distributed on an "AS IS" BASIS,
-; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
-; express or implied.
-; See the License for the specific language governing permissions
-; and limitations under the License.
-; -------------------------------------------------------------------
-
-;
-;
-; Filename: pvmp3_dct_18.s
-;
-;------------------------------------------------------------------------------
-; REVISION HISTORY
-;
-;
-; Who: Date: MM/DD/YYYY
-; Description:
-;
-;------------------------------------------------------------------------------
-
- EXPORT |pvmp3_mdct_18|
-
- IMPORT pvmp3_dct_9
-
-
-;------------------------------------------------------------------------------
-
- AREA |.text|, CODE, READONLY, ALIGN=2
-
-
-;------------------------------------------------------------------------------
-
-|pvmp3_mdct_18| PROC
- stmfd sp!,{r4-r10,lr}
- mov r7,r2
- ldr r2,table
- mov r6,r1
- add r3,r2,#0x24
- add r12,r3,#0x44
- add r1,r0,#0x44
- mov r5,r0
-
-; for ( i=9; i!=0; i--)
-; {
-
- mov r4,#9
-Loop_1
-
-; tmp = *(pt_vec);
-; tmp1 = *(pt_vec_o);
-
- ldr lr,[r0] ;; tmp == lr
- ldr r8,[r3],#4 ;; tmp1 == r8
-
-; tmp = fxp_mul32_Q32( tmp<<1, *(pt_cos++ ));
-; tmp1 = fxp_mul32_Q27( tmp1, *(pt_cos_x--));
-
- mov lr,lr,lsl #1
- smull r10,lr,r8,lr
- ldr r8,[r12],#-4
- ldr r9,[r1]
- subs r4,r4,#1
- smull r9,r10,r8,r9
- mov r8,r9,lsr #27
- add r8,r8,r10,lsl #5
-
-; *(pt_vec++) = tmp + tmp1 ;
-; *(pt_vec_o--) = fxp_mul32_Q28( (tmp - tmp1), *(pt_cos_split++));
-
- add r9,lr,r8
- sub r8,lr,r8
- ldr lr,[r2],#4
- str r9,[r0],#4
- smull r8,r9,lr,r8
- mov lr,r8,lsr #28
- add lr,lr,r9,lsl #4
- str lr,[r1],#-4
- bne Loop_1
-
-; }
-
- mov r0,r5 ;; r0 = vec
- bl pvmp3_dct_9
- add r0,r5,#0x24 ;; r0 = &vec[9]
- bl pvmp3_dct_9
-
- ldr r0,[r5,#0x20]
- ldr r2,[r5,#0x40]
- str r0,[r5,#0x40]
- ldr r0,[r5,#0x1c]
- ldr r3,[r5,#0x38]
- str r0,[r5,#0x38]
- ldr r1,[r5,#0x18]
- ldr r0,[r5,#0x30]
- str r1,[r5,#0x30]
- ldr r12,[r5,#0x14]
- ldr r1,[r5,#0x28]
- str r12,[r5,#0x28]
- ldr r12,[r5,#0x10]
- str r12,[r5,#0x20]
- ldr r12,[r5,#0xc]
- str r12,[r5,#0x18]
- ldr r12,[r5,#8]
- str r12,[r5,#0x10]
- ldr r12,[r5,#4]
- str r12,[r5,#8]
- ldr r12,[r5,#0x24]
- sub r12,r12,r1
- str r12,[r5,#4]
- ldr r12,[r5,#0x2c]
- sub r1,r12,r1
- str r1,[r5,#0xc]
- sub r1,r12,r0
- str r1,[r5,#0x14]
- ldr r1,[r5,#0x34]
- sub r0,r1,r0
- str r0,[r5,#0x1c]
- sub r0,r1,r3
- str r0,[r5,#0x24]
- ldr r1,[r5,#0x3c]
- sub r3,r1,r3
- sub r1,r1,r2
- str r1,[r5,#0x34]
- str r3,[r5,#0x2c]
- ldr r1,[r5,#0x44]
- sub r1,r1,r2
- str r1,[r5,#0x3c]
- ldr r12,[r5,#0]
-
-Loop_2
- add r1,r5,r4,lsl #2
- ldr r2,[r1,#0x28]
- ldr r3,[r6,r4,lsl #2]
- add r0,r0,r2
- str r0,[r1,#0x28]
- ldr lr,[r7,r4,lsl #2]
- ldr r1,[r1,#4]
- smlal r0,r3,lr,r0
- mov r0,r2
- add r2,r12,r1
- rsb r2,r2,#0
- str r3,[r5,r4,lsl #2]
- str r2,[r6,r4,lsl #2]
- add r4,r4,#1
- cmp r4,#6
- mov r12,r1
-
- blt Loop_2
-
- ldr r1,[r5,#0x40]
- ldr r2,[r6,#0x18]
- add r3,r0,r1
- str r3,[r5,#0x40]
- ldr lr,[r7,r4,lsl #2]
- mov r3,r3,lsl #1
- ldr r0,[r5,#0x1c]
- smlal r3,r2,lr,r3
- add r3,r12,r0
- str r2,[r5,#0x18]
- ldr r2,[r6,#0x1c]
- rsb r3,r3,#0
- str r3,[r6,#0x18]
- ldr r3,[r5,#0x20]
- add r0,r3,r0
- rsb r0,r0,#0
- str r0,[r6,#0x1c]
- ldr r3,[r5,#0x44]
- ldr r0,[r6,#0x20]
- add r3,r3,r1
- mov r1,r2
- ldr r10,[r7,#0x1c]
- mov r2,r3,lsl #1
- smlal r12,r1,r10,r2
- str r1,[r5,#0x1c]
- ldr r1,[r5,#0x20]
- ldr r3,[r5,#0x24]
- add r1,r1,r3
- rsb r1,r1,#0
- str r1,[r6,#0x20]
- ldr r1,[r5,#0x44]
- ldr r3,[r7,#0x20]
- mov r1,r1,lsl #1
- smlal r12,r0,r3,r1
- ldr lr,[r7,#0x24]
- ldr r3,[r6,#0x24]
- str r0,[r5,#0x20]
- smlal r1,r3,lr,r1
- ldr r0,[r6,#0x40]
- ldr r12,[r6,#0x44]
- str r3,[r5,#0x24]
- ldr r1,[r5,#0x28]
- ldr r3,[r7,#0x44]
- mov r1,r1,lsl #1
- smlal r1,r12,r3,r1
- ldr r1,[r5,#0x40]
- str r12,[r5,#0x44]
- rsb r8,r1,#0
- str r8,[r5,#0x28]
- ldr r1,[r5,#0x2c]
- ldr r3,[r7,#0x40]
- mov r1,r1,lsl #1
- smlal r1,r0,r3,r1
- str r0,[r5,#0x40]
- ldr r0,[r5,#0x3c]
- ldr r1,[r6,#0x38]
- ldr r3,[r6,#0x3c]
- rsb r9,r0,#0
- str r9,[r5,#0x2c]
- ldr r0,[r5,#0x30]
- ldr r12,[r7,#0x3c]
- mov r0,r0,lsl #1
- smlal r0,r3,r12,r0
- str r3,[r5,#0x3c]
- ldr r0,[r5,#0x38]
- rsb r0,r0,#0
- str r0,[r5,#0x30]
- ldr r3,[r5,#0x34]
- ldr r12,[r7,#0x38]
- mov r3,r3,lsl #1
- smlal r3,r1,r12,r3
- mov r0,r0,lsl #1
- str r1,[r5,#0x38]
- ldr r4,[r7,#0x34]
- ldr r1,[r6,#0x34]
- ldr r3,[r6,#0x30]
- smlal r0,r1,r4,r0
- ldr r12,[r6,#0x2c]
- ldr lr,[r6,#0x28]
- str r1,[r5,#0x34]
- ldr r1,[r7,#0x30]
- mov r0,r9,lsl #1
- smlal r0,r3,r1,r0
- mov r0,r8,lsl #1
- ldr r1,[r7,#0x2c]
- str r3,[r5,#0x30]
- smlal r0,r12,r1,r0
- ldr r0,[r7,#0x28]
- str r12,[r5,#0x2c]
- smlal r2,lr,r0,r2
- str lr,[r5,#0x28]
- ldr r1,[r6,#4]
- ldr r12,[r7,#0x48]
- mov r2,r1,lsl #1
- ldr r1,[r6,#0x20]
- ldr r0,[r6]
- mov r1,r1,lsl #1
- smull r4,lr,r12,r1
- ldr r3,[r6,#0x1c]
- str lr,[r6]
- ldr r12,[r7,#0x4c]
- mov r3,r3,lsl #1
- smull r4,lr,r12,r3
- mov r0,r0,lsl #1
- ldr r12,[r7,#0x64]
- str lr,[r6,#4]
- smull r4,lr,r12,r2
- ldr r12,[r7,#0x68]
- str lr,[r6,#0x1c]
- smull r4,lr,r12,r0
- ldr r12,[r7,#0x6c]
- str lr,[r6,#0x20]
- smull lr,r0,r12,r0
- ldr r12,[r7,#0x70]
- str r0,[r6,#0x24]
- smull r0,r2,r12,r2
- ldr r0,[r7,#0x88]
- str r2,[r6,#0x28]
- smull r3,r2,r0,r3
- ldr r0,[r7,#0x8c]
- str r2,[r6,#0x40]
- smull r2,r1,r0,r1
- str r1,[r6,#0x44]
- ldr r0,[r6,#0x18]
- ldr lr,[r7,#0x50]
- mov r1,r0,lsl #1
- ldr r0,[r6,#0x14]
- smull r5,r4,lr,r1
- ldr r12,[r6,#0x10]
- mov r3,r0,lsl #1
- ldr r0,[r6,#0xc]
- mov r12,r12,lsl #1
- mov r2,r0,lsl #1
- ldr r0,[r6,#8]
- str r4,[r6,#8]
- ldr lr,[r7,#0x54]
- mov r0,r0,lsl #1
- smull r5,r4,lr,r3
- ldr lr,[r7,#0x58]
- str r4,[r6,#0xc]
- smull r5,r4,lr,r12
- ldr lr,[r7,#0x5c]
- str r4,[r6,#0x10]
- smull r5,r4,lr,r2
- ldr lr,[r7,#0x60]
- str r4,[r6,#0x14]
- smull r5,r4,lr,r0
- ldr lr,[r7,#0x74]
- str r4,[r6,#0x18]
- smull r4,r0,lr,r0
- ldr lr,[r7,#0x78]
- str r0,[r6,#0x2c]
- smull r0,r2,lr,r2
- ldr r0,[r7,#0x7c]
- str r2,[r6,#0x30]
- smull r12,r2,r0,r12
- ldr r0,[r7,#0x80]
- str r2,[r6,#0x34]
- smull r3,r2,r0,r3
- ldr r0,[r7,#0x84]
- str r2,[r6,#0x38]
- smull r2,r1,r0,r1
- str r1,[r6,#0x3c]
- ldmfd sp!,{r4-r10,pc}
-table
- DCD cosTerms_dct18
- ENDP
-
-;------------------------------------------------------------------------------
-
- AREA |.constdata|, DATA, READONLY, ALIGN=2
-
-;------------------------------------------------------------------------------
-
-cosTerms_dct18
- DCD 0x0807d2b0
- DCD 0x08483ee0
- DCD 0x08d3b7d0
- DCD 0x09c42570
- DCD 0x0b504f30
- DCD 0x0df29440
- DCD 0x12edfb20
- DCD 0x1ee8dd40
- DCD 0x5bca2a00
-cosTerms_1_ov_cos_phi
- DCD 0x400f9c00
- DCD 0x408d6080
- DCD 0x418dcb80
- DCD 0x431b1a00
- DCD 0x4545ea00
- DCD 0x48270680
- DCD 0x4be25480
- DCD 0x50ab9480
- DCD 0x56ce4d80
- DCD 0x05ebb630
- DCD 0x06921a98
- DCD 0x0771d3a8
- DCD 0x08a9a830
- DCD 0x0a73d750
- DCD 0x0d4d5260
- DCD 0x127b1ca0
- DCD 0x1ea52b40
- DCD 0x5bb3cc80
-
-
-
- END
diff --git a/media/libstagefright/codecs/mp3dec/src/asm/pvmp3_polyphase_filter_window_arm.s b/media/libstagefright/codecs/mp3dec/src/asm/pvmp3_polyphase_filter_window_arm.s
deleted file mode 100644
index abec599..0000000
--- a/media/libstagefright/codecs/mp3dec/src/asm/pvmp3_polyphase_filter_window_arm.s
+++ /dev/null
@@ -1,237 +0,0 @@
-; ------------------------------------------------------------------
-; Copyright (C) 1998-2009 PacketVideo
-;
-; Licensed under the Apache License, Version 2.0 (the "License");
-; you may not use this file except in compliance with the License.
-; You may obtain a copy of the License at
-;
-; http://www.apache.org/licenses/LICENSE-2.0
-;
-; Unless required by applicable law or agreed to in writing, software
-; distributed under the License is distributed on an "AS IS" BASIS,
-; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
-; express or implied.
-; See the License for the specific language governing permissions
-; and limitations under the License.
-; -------------------------------------------------------------------
-
-;
-;
-; Filename: pvmp3_polyphase_filter_window.s
-;
-;------------------------------------------------------------------------------
-; REVISION HISTORY
-;
-;
-; Who: Date: MM/DD/YYYY
-; Description:
-;
-;------------------------------------------------------------------------------
-
- EXPORT pvmp3_polyphase_filter_window
-
- IMPORT ||Lib$$Request$$armlib|| [WEAK]
- IMPORT ||Lib$$Request$$cpplib|| [WEAK]
- IMPORT pqmfSynthWin
-
-
-
-;------------------------------------------------------------------------------
-
- AREA |.text|, CODE, READONLY, ALIGN=2
-
-
-;------------------------------------------------------------------------------
-
-|pvmp3_polyphase_filter_window| PROC
-
- stmfd sp!,{r0-r2,r4-r11,lr}
-
- sub sp,sp,#4
- ldr r2,[sp,#0xc]
- ldr r1,PolyPh_filter_coeff
-
- sub r2,r2,#1
- mov r10,#1
- str r2,[sp]
-
-; Accumulators r9, r11::> Initialization
-
-Loop_j
- mov r9, #0x20
- mov r11, #0x20
- mov r4, #0x10
-Loop_i
- add r2,r4,r10
- add r3,r0,r2,lsl #2
- sub r2,r4,r10
- ldr r5,[r3]
- ldr lr,[r1]
- add r12,r0,r2,lsl #2
- ldr r6,[r12,#0x780]
- smlal r2,r9,lr,r5
- smlal r2,r11,lr,r6
- ldr r2,[r1,#4]
- ldr r7,[r12,#0x80]
- smlal r5,r11,r2,r5
- smull r6,r5,r2,r6
- sub r9,r9,r5
- ldr r5,[r1,#8]
- ldr r8,[r3,#0x700]
- add r4,r4,#0x200
- smlal r6,r9,r5,r7
- smull r6,r2,r5,r8
- ldr r5,[r1,#0xc]
- sub r11,r11,r2
- smlal r8,r9,r5,r8
- smlal r7,r11,r5,r7
- ldr r5,[r3,#0x100]
- ldr r2,[r1,#0x10]
- ldr r6,[r12,#0x680]
- smlal lr,r9,r2,r5
- smlal lr,r11,r2,r6
- ldr r2,[r1,#0x14]
- ldr r7,[r12,#0x180]
- smlal r5,r11,r2,r5
- smull r6,r5,r2,r6
- ldr r6,[r1,#0x18]
- ldr r8,[r3,#0x600]
- sub r9,r9,r5
- smlal r5,r9,r6,r7
- smull r2,r5,r6,r8
- ldr r6,[r1,#0x1c]
- sub r11,r11,r5
- smlal r8,r9,r6,r8
- ldr r2,[r1,#0x20]
- ldr r5,[r3,#0x200]
- smlal r7,r11,r6,r7
- ldr r6,[r12,#0x580]
- smlal lr,r9,r2,r5
- smlal lr,r11,r2,r6
- ldr r2,[r1,#0x24]
- ldr r7,[r12,#0x280]
- smlal r5,r11,r2,r5
- smull r6,r5,r2,r6
- ldr r6,[r1,#0x28]
- ldr r8,[r3,#0x500]
- sub r9,r9,r5
- smlal r5,r9,r6,r7
- smull r2,r5,r6,r8
- ldr r6,[r1,#0x2c]
- sub r11,r11,r5
-
- smlal r8,r9,r6,r8
- smlal r7,r11,r6,r7
- ldr r5,[r3,#0x300]
- ldr r8,[r1,#0x30]
- ldr r6,[r12,#0x480]
- smlal r7,r9,r8,r5
- smlal r7,r11,r8,r6
- ldr r8,[r1,#0x34]
- ldr r12,[r12,#0x380]
- smlal r5,r11,r8,r5
- smull r6,r5,r8,r6
- ldr r6,[r1,#0x38]
-
-
- ldr r3,[r3,#0x400]
- sub r9,r9,r5
- smlal r7,r9,r6,r12
- smull r8,r7,r6,r3
- cmp r4,#0x210
- sub r11,r11,r7
-
- ldr r2,[r1,#0x3c]
- add r1,r1,#0x40
- smlal r3,r9,r2,r3
- smlal r12,r11,r2,r12
-
- blt Loop_i
-
- mov r3,r9, asr #6
- mov r4,r3, asr #15
- teq r4,r3, asr #31
- ldr r12,LOW_16BITS
- ldr r2,[sp]
- eorne r3,r12,r3,asr #31
- ldr r4,[sp,#8]
- mov r2,r10,lsl r2
- add r4,r4,r2,lsl #1
- strh r3,[r4]
-
- mov r3,r11,asr #6
- mov r4,r3,asr #15
- teq r4,r3,asr #31
- eorne r3,r12,r3,asr #31
- ldr r12,[sp,#0xc]
- ldr r11,[sp,#8]
- rsb r2,r2,r12,lsl #5
- add r2,r11,r2,lsl #1
- strh r3,[r2]
-
- add r10,r10,#1
- cmp r10,#0x10
- blt Loop_j
-
-; Accumulators r4, r5 Initialization
-
- mov r4,#0x20
- mov r5,#0x20
- mov r3,#0x10
-PolyPh_filter_loop2
- add r2,r0,r3,lsl #2
- ldr r12,[r2]
- ldr r8,[r1]
- ldr r6,[r2,#0x80]
- smlal r12,r4,r8,r12
- ldr r12,[r1,#4]
- ldr r7,[r2,#0x40]
- smlal r6,r4,r12,r6
-
- ldr r12,[r1,#8]
- ldr r6,[r2,#0x180]
- smlal r7,r5,r12,r7
- ldr r12,[r2,#0x100]
- ldr r7,[r1,#0xc]
- ldr r2,[r2,#0x140]
- smlal r12,r4,r7,r12
- ldr r12,[r1,#0x10]
- add r3,r3,#0x80
- smlal r6,r4,r12,r6
- ldr r6,[r1,#0x14]
- cmp r3,#0x210
- smlal r2,r5,r6,r2
- add r1,r1,#0x18
-
- blt PolyPh_filter_loop2
- mov r0,r4,asr #6
- mov r2,r0,asr #15
- teq r2,r0,asr #31
- ldrne r12,LOW_16BITS
- ldr r1,[sp,#8]
- eorne r0,r12,r0,asr #31
- strh r0,[r1,#0]
- mov r0,r5,asr #6
- mov r2,r0,asr #15
- teq r2,r0,asr #31
- ldrne r12,LOW_16BITS
- ldr r2,[sp]
- mov r1,#0x10
- eorne r0,r12,r0,asr #31
- ldr r12,[sp,#8]
- mov r1,r1,lsl r2
- add r1,r12,r1,lsl #1
- strh r0,[r1]
- add sp,sp,#0x10
- ldmfd sp!,{r4-r11,pc}
-
-
-PolyPh_filter_coeff
- DCD pqmfSynthWin
-LOW_16BITS
- DCD 0x00007fff
-
- ENDP
-
-
- END
diff --git a/media/libstagefright/codecs/mp3dec/src/asm/pvmp3_polyphase_filter_window_gcc.s b/media/libstagefright/codecs/mp3dec/src/asm/pvmp3_polyphase_filter_window_gcc.s
index b74c849..1140ed7 100644
--- a/media/libstagefright/codecs/mp3dec/src/asm/pvmp3_polyphase_filter_window_gcc.s
+++ b/media/libstagefright/codecs/mp3dec/src/asm/pvmp3_polyphase_filter_window_gcc.s
@@ -35,6 +35,7 @@
.text
.extern pqmfSynthWin
+.hidden pqmfSynthWin
diff --git a/media/libstagefright/codecs/mp3dec/src/asm/pvmp3_polyphase_filter_window_wm.asm b/media/libstagefright/codecs/mp3dec/src/asm/pvmp3_polyphase_filter_window_wm.asm
deleted file mode 100644
index f957267..0000000
--- a/media/libstagefright/codecs/mp3dec/src/asm/pvmp3_polyphase_filter_window_wm.asm
+++ /dev/null
@@ -1,231 +0,0 @@
-; ------------------------------------------------------------------
-; Copyright (C) 1998-2009 PacketVideo
-;
-; Licensed under the Apache License, Version 2.0 (the "License");
-; you may not use this file except in compliance with the License.
-; You may obtain a copy of the License at
-;
-; http://www.apache.org/licenses/LICENSE-2.0
-;
-; Unless required by applicable law or agreed to in writing, software
-; distributed under the License is distributed on an "AS IS" BASIS,
-; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
-; express or implied.
-; See the License for the specific language governing permissions
-; and limitations under the License.
-; -------------------------------------------------------------------
-
-;
-;
-; Filename: pvmp3_polyphase_filter_window.s
-;
-;------------------------------------------------------------------------------
-; REVISION HISTORY
-;
-;
-; Who: Date: MM/DD/YYYY
-; Description:
-;
-;------------------------------------------------------------------------------
-
- CODE32
-
- AREA |.drectve|, DRECTVE
-
- EXPORT |pvmp3_polyphase_filter_window|
- IMPORT |pqmfSynthWin|
-
- AREA |.pdata|, PDATA
-
- AREA |.text|, CODE, ARM
-
-|pvmp3_polyphase_filter_window| PROC
- stmfd sp!,{r0-r2,r4-r11,lr}
-
- sub sp,sp,#4
- ldr r2,[sp,#0xc]
- ldr r1,PolyPh_filter_coeff
-
- sub r2,r2,#1
- mov r10,#1
- str r2,[sp]
-
-; Accumulators r9, r11::> Initialization
-
-Loop_j
- mov r9, #0x20
- mov r11, #0x20
- mov r4, #0x10
-Loop_i
- add r2,r4,r10
- add r3,r0,r2,lsl #2
- sub r2,r4,r10
- ldr r5,[r3]
- ldr lr,[r1]
- add r12,r0,r2,lsl #2
- ldr r6,[r12,#0x780]
- smlal r2,r9,lr,r5
- smlal r2,r11,lr,r6
- ldr r2,[r1,#4]
- ldr r7,[r12,#0x80]
- smlal r5,r11,r2,r5
- smull r6,r5,r2,r6
- sub r9,r9,r5
- ldr r5,[r1,#8]
- ldr r8,[r3,#0x700]
- add r4,r4,#0x200
- smlal r6,r9,r5,r7
- smull r6,r2,r5,r8
- ldr r5,[r1,#0xc]
- sub r11,r11,r2
- smlal r8,r9,r5,r8
- smlal r7,r11,r5,r7
- ldr r5,[r3,#0x100]
- ldr r2,[r1,#0x10]
- ldr r6,[r12,#0x680]
- smlal lr,r9,r2,r5
- smlal lr,r11,r2,r6
- ldr r2,[r1,#0x14]
- ldr r7,[r12,#0x180]
- smlal r5,r11,r2,r5
- smull r6,r5,r2,r6
- ldr r6,[r1,#0x18]
- ldr r8,[r3,#0x600]
- sub r9,r9,r5
- smlal r5,r9,r6,r7
- smull r2,r5,r6,r8
- ldr r6,[r1,#0x1c]
- sub r11,r11,r5
- smlal r8,r9,r6,r8
- ldr r2,[r1,#0x20]
- ldr r5,[r3,#0x200]
- smlal r7,r11,r6,r7
- ldr r6,[r12,#0x580]
- smlal lr,r9,r2,r5
- smlal lr,r11,r2,r6
- ldr r2,[r1,#0x24]
- ldr r7,[r12,#0x280]
- smlal r5,r11,r2,r5
- smull r6,r5,r2,r6
- ldr r6,[r1,#0x28]
- ldr r8,[r3,#0x500]
- sub r9,r9,r5
- smlal r5,r9,r6,r7
- smull r2,r5,r6,r8
- ldr r6,[r1,#0x2c]
- sub r11,r11,r5
-
- smlal r8,r9,r6,r8
- smlal r7,r11,r6,r7
- ldr r5,[r3,#0x300]
- ldr r8,[r1,#0x30]
- ldr r6,[r12,#0x480]
- smlal r7,r9,r8,r5
- smlal r7,r11,r8,r6
- ldr r8,[r1,#0x34]
- ldr r12,[r12,#0x380]
- smlal r5,r11,r8,r5
- smull r6,r5,r8,r6
- ldr r6,[r1,#0x38]
-
-
- ldr r3,[r3,#0x400]
- sub r9,r9,r5
- smlal r7,r9,r6,r12
- smull r8,r7,r6,r3
- cmp r4,#0x210
- sub r11,r11,r7
-
- ldr r2,[r1,#0x3c]
- add r1,r1,#0x40
- smlal r3,r9,r2,r3
- smlal r12,r11,r2,r12
-
- blt Loop_i
-
- mov r3,r9, asr #6
- mov r4,r3, asr #15
- teq r4,r3, asr #31
- ldr r12,LOW_16BITS
- ldr r2,[sp]
- eorne r3,r12,r3,asr #31
- ldr r4,[sp,#8]
- mov r2,r10,lsl r2
- add r4,r4,r2,lsl #1
- strh r3,[r4]
-
- mov r3,r11,asr #6
- mov r4,r3,asr #15
- teq r4,r3,asr #31
- eorne r3,r12,r3,asr #31
- ldr r12,[sp,#0xc]
- ldr r11,[sp,#8]
- rsb r2,r2,r12,lsl #5
- add r2,r11,r2,lsl #1
- strh r3,[r2]
-
- add r10,r10,#1
- cmp r10,#0x10
- blt Loop_j
-
-; Accumulators r4, r5 Initialization
-
- mov r4,#0x20
- mov r5,#0x20
- mov r3,#0x10
-PolyPh_filter_loop2
- add r2,r0,r3,lsl #2
- ldr r12,[r2]
- ldr r8,[r1]
- ldr r6,[r2,#0x80]
- smlal r12,r4,r8,r12
- ldr r12,[r1,#4]
- ldr r7,[r2,#0x40]
- smlal r6,r4,r12,r6
-
- ldr r12,[r1,#8]
- ldr r6,[r2,#0x180]
- smlal r7,r5,r12,r7
- ldr r12,[r2,#0x100]
- ldr r7,[r1,#0xc]
- ldr r2,[r2,#0x140]
- smlal r12,r4,r7,r12
- ldr r12,[r1,#0x10]
- add r3,r3,#0x80
- smlal r6,r4,r12,r6
- ldr r6,[r1,#0x14]
- cmp r3,#0x210
- smlal r2,r5,r6,r2
- add r1,r1,#0x18
-
- blt PolyPh_filter_loop2
- mov r0,r4,asr #6
- mov r2,r0,asr #15
- teq r2,r0,asr #31
- ldrne r12,LOW_16BITS
- ldr r1,[sp,#8]
- eorne r0,r12,r0,asr #31
- strh r0,[r1,#0]
- mov r0,r5,asr #6
- mov r2,r0,asr #15
- teq r2,r0,asr #31
- ldrne r12,LOW_16BITS
- ldr r2,[sp]
- mov r1,#0x10
- eorne r0,r12,r0,asr #31
- ldr r12,[sp,#8]
- mov r1,r1,lsl r2
- add r1,r12,r1,lsl #1
- strh r0,[r1]
- add sp,sp,#0x10
- ldmfd sp!,{r4-r11,pc}
-
-
-PolyPh_filter_coeff
- DCD pqmfSynthWin
-LOW_16BITS
- DCD 0x00007fff
-
- ENDP ; |pvmp3_polyphase_filter_window|
- END
-
diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_data.cpp b/media/libstagefright/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_data.cpp
index ee42dc5..499672b 100644
--- a/media/libstagefright/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_data.cpp
+++ b/media/libstagefright/codecs/mp3dec/src/pvmp3_mpeg2_get_scale_data.cpp
@@ -139,7 +139,7 @@ void pvmp3_mpeg2_get_scale_data(mp3SideInfo *si,
int16 blocknumber = 0;
granuleInfo *gr_info = &(si->ch[ch].gran[gr]);
- uint32 scalefac_comp, int_scalefac_comp, new_slen[4];
+ uint32 scalefac_comp, int_scalefac_comp, new_slen[4] = { 0,0,0,0 };
scalefac_comp = gr_info->scalefac_compress;
diff --git a/media/libstagefright/codecs/on2/dec/SoftVPX.cpp b/media/libstagefright/codecs/on2/dec/SoftVPX.cpp
index 476e986..423a057 100644
--- a/media/libstagefright/codecs/on2/dec/SoftVPX.cpp
+++ b/media/libstagefright/codecs/on2/dec/SoftVPX.cpp
@@ -85,7 +85,7 @@ status_t SoftVPX::initDecoder() {
return OK;
}
-void SoftVPX::onQueueFilled(OMX_U32 portIndex) {
+void SoftVPX::onQueueFilled(OMX_U32 /* portIndex */) {
if (mOutputPortSettingsChange != NONE) {
return;
}
diff --git a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp
index 8375cac..5efe022 100644
--- a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp
+++ b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp
@@ -677,6 +677,9 @@ OMX_ERRORTYPE SoftVPXEncoder::internalSetPortParams(
def->format.video.nFrameHeight = mHeight;
def->format.video.xFramerate = port->format.video.xFramerate;
def->format.video.eColorFormat = mColorFormat;
+ def = &editPortInfo(kOutputPortIndex)->mDef;
+ def->format.video.nFrameWidth = mWidth;
+ def->format.video.nFrameHeight = mHeight;
return OMX_ErrorNone;
} else if (port->nPortIndex == kOutputPortIndex) {
diff --git a/media/libstagefright/codecs/on2/h264dec/Android.mk b/media/libstagefright/codecs/on2/h264dec/Android.mk
index 655b2ab..bf03ad9 100644
--- a/media/libstagefright/codecs/on2/h264dec/Android.mk
+++ b/media/libstagefright/codecs/on2/h264dec/Android.mk
@@ -84,8 +84,8 @@ MY_OMXDL_ASM_SRC := \
./omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_DequantTransformResidualFromPairAndAdd_s.S \
./omxdl/arm_neon/vc/m4p10/src_gcc/omxVCM4P10_TransformDequantChromaDCFromPair_s.S \
-
-ifeq ($(ARCH_ARM_HAVE_NEON),true)
+ifeq ($(TARGET_ARCH),arm)
+ ifeq ($(ARCH_ARM_HAVE_NEON),true)
LOCAL_ARM_NEON := true
# LOCAL_CFLAGS := -std=c99 -D._NEON -D._OMXDL
LOCAL_CFLAGS := -DH264DEC_NEON -DH264DEC_OMXDL
@@ -94,6 +94,7 @@ ifeq ($(ARCH_ARM_HAVE_NEON),true)
LOCAL_C_INCLUDES += $(LOCAL_PATH)/./omxdl/arm_neon/api \
$(LOCAL_PATH)/./omxdl/arm_neon/vc/api \
$(LOCAL_PATH)/./omxdl/arm_neon/vc/m4p10/api
+ endif
endif
LOCAL_SHARED_LIBRARIES := \
diff --git a/media/libstagefright/codecs/on2/h264dec/SoftAVC.cpp b/media/libstagefright/codecs/on2/h264dec/SoftAVC.cpp
index 7ddb13c..a7bde97 100644
--- a/media/libstagefright/codecs/on2/h264dec/SoftAVC.cpp
+++ b/media/libstagefright/codecs/on2/h264dec/SoftAVC.cpp
@@ -98,7 +98,7 @@ status_t SoftAVC::initDecoder() {
return UNKNOWN_ERROR;
}
-void SoftAVC::onQueueFilled(OMX_U32 portIndex) {
+void SoftAVC::onQueueFilled(OMX_U32 /* portIndex */) {
if (mSignalledError || mOutputPortSettingsChange != NONE) {
return;
}
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/omxtypes.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/omxtypes.h
index 8b295a6..912cb0d 100644
--- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/omxtypes.h
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm11/api/omxtypes.h
@@ -32,6 +32,7 @@
#define _OMXTYPES_H_
#include <limits.h>
+#include <stdint.h>
#define OMX_IN
#define OMX_OUT
@@ -75,64 +76,22 @@ typedef enum {
/* OMX_U8 */
-#if UCHAR_MAX == 0xff
-typedef unsigned char OMX_U8;
-#elif USHRT_MAX == 0xff
-typedef unsigned short int OMX_U8;
-#else
-#error OMX_U8 undefined
-#endif
-
+typedef uint8_t OMX_U8;
/* OMX_S8 */
-#if SCHAR_MAX == 0x7f
-typedef signed char OMX_S8;
-#elif SHRT_MAX == 0x7f
-typedef signed short int OMX_S8;
-#else
-#error OMX_S8 undefined
-#endif
-
+typedef int8_t OMX_S8;
/* OMX_U16 */
-#if USHRT_MAX == 0xffff
-typedef unsigned short int OMX_U16;
-#elif UINT_MAX == 0xffff
-typedef unsigned int OMX_U16;
-#else
-#error OMX_U16 undefined
-#endif
-
+typedef uint16_t OMX_U16;
/* OMX_S16 */
-#if SHRT_MAX == 0x7fff
-typedef signed short int OMX_S16;
-#elif INT_MAX == 0x7fff
-typedef signed int OMX_S16;
-#else
-#error OMX_S16 undefined
-#endif
-
+typedef int16_t OMX_S16;
/* OMX_U32 */
-#if UINT_MAX == 0xffffffff
-typedef unsigned int OMX_U32;
-#elif LONG_MAX == 0xffffffff
-typedef unsigned long int OMX_U32;
-#else
-#error OMX_U32 undefined
-#endif
-
+typedef uint32_t OMX_U32;
/* OMX_S32 */
-#if INT_MAX == 0x7fffffff
-typedef signed int OMX_S32;
-#elif LONG_MAX == 0x7fffffff
-typedef long signed int OMX_S32;
-#else
-#error OMX_S32 undefined
-#endif
-
+typedef int32_t OMX_S32;
/* OMX_U64 & OMX_S64 */
#if defined( _WIN32 ) || defined ( _WIN64 )
@@ -143,15 +102,14 @@ typedef long signed int OMX_S32;
#define OMX_MAX_S64 (0x7FFFFFFFFFFFFFFFi64)
#define OMX_MAX_U64 (0xFFFFFFFFFFFFFFFFi64)
#else
- typedef long long OMX_S64; /** Signed 64-bit integer */
- typedef unsigned long long OMX_U64; /** Unsigned 64-bit integer */
+ typedef int64_t OMX_S64; /** Signed 64-bit integer */
+ typedef uint64_t OMX_U64; /** Unsigned 64-bit integer */
#define OMX_MIN_S64 (0x8000000000000000LL)
#define OMX_MIN_U64 (0x0000000000000000LL)
#define OMX_MAX_S64 (0x7FFFFFFFFFFFFFFFLL)
#define OMX_MAX_U64 (0xFFFFFFFFFFFFFFFFLL)
#endif
-
/* OMX_SC8 */
typedef struct
{
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/omxtypes.h b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/omxtypes.h
index 8b295a6..912cb0d 100755
--- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/omxtypes.h
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/api/omxtypes.h
@@ -32,6 +32,7 @@
#define _OMXTYPES_H_
#include <limits.h>
+#include <stdint.h>
#define OMX_IN
#define OMX_OUT
@@ -75,64 +76,22 @@ typedef enum {
/* OMX_U8 */
-#if UCHAR_MAX == 0xff
-typedef unsigned char OMX_U8;
-#elif USHRT_MAX == 0xff
-typedef unsigned short int OMX_U8;
-#else
-#error OMX_U8 undefined
-#endif
-
+typedef uint8_t OMX_U8;
/* OMX_S8 */
-#if SCHAR_MAX == 0x7f
-typedef signed char OMX_S8;
-#elif SHRT_MAX == 0x7f
-typedef signed short int OMX_S8;
-#else
-#error OMX_S8 undefined
-#endif
-
+typedef int8_t OMX_S8;
/* OMX_U16 */
-#if USHRT_MAX == 0xffff
-typedef unsigned short int OMX_U16;
-#elif UINT_MAX == 0xffff
-typedef unsigned int OMX_U16;
-#else
-#error OMX_U16 undefined
-#endif
-
+typedef uint16_t OMX_U16;
/* OMX_S16 */
-#if SHRT_MAX == 0x7fff
-typedef signed short int OMX_S16;
-#elif INT_MAX == 0x7fff
-typedef signed int OMX_S16;
-#else
-#error OMX_S16 undefined
-#endif
-
+typedef int16_t OMX_S16;
/* OMX_U32 */
-#if UINT_MAX == 0xffffffff
-typedef unsigned int OMX_U32;
-#elif LONG_MAX == 0xffffffff
-typedef unsigned long int OMX_U32;
-#else
-#error OMX_U32 undefined
-#endif
-
+typedef uint32_t OMX_U32;
/* OMX_S32 */
-#if INT_MAX == 0x7fffffff
-typedef signed int OMX_S32;
-#elif LONG_MAX == 0x7fffffff
-typedef long signed int OMX_S32;
-#else
-#error OMX_S32 undefined
-#endif
-
+typedef int32_t OMX_S32;
/* OMX_U64 & OMX_S64 */
#if defined( _WIN32 ) || defined ( _WIN64 )
@@ -143,15 +102,14 @@ typedef long signed int OMX_S32;
#define OMX_MAX_S64 (0x7FFFFFFFFFFFFFFFi64)
#define OMX_MAX_U64 (0xFFFFFFFFFFFFFFFFi64)
#else
- typedef long long OMX_S64; /** Signed 64-bit integer */
- typedef unsigned long long OMX_U64; /** Unsigned 64-bit integer */
+ typedef int64_t OMX_S64; /** Signed 64-bit integer */
+ typedef uint64_t OMX_U64; /** Unsigned 64-bit integer */
#define OMX_MIN_S64 (0x8000000000000000LL)
#define OMX_MIN_U64 (0x0000000000000000LL)
#define OMX_MAX_S64 (0x7FFFFFFFFFFFFFFFLL)
#define OMX_MAX_U64 (0xFFFFFFFFFFFFFFFFLL)
#endif
-
/* OMX_SC8 */
typedef struct
{
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_DecodeCoeffsToPair_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_DecodeCoeffsToPair_s.S
index 073dbba..bcc6b6b 100644
--- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_DecodeCoeffsToPair_s.S
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_DecodeCoeffsToPair_s.S
@@ -10,6 +10,22 @@
.fpu neon
.text
+ .extern armVCM4P10_CAVLCCoeffTokenTables
+ .extern armVCM4P10_SuffixToLevel
+ .extern armVCM4P10_CAVLCTotalZeros2x2Tables
+ .extern armVCM4P10_CAVLCTotalZeroTables
+ .extern armVCM4P10_CAVLCRunBeforeTables
+ .extern armVCM4P10_ZigZag_2x2
+ .extern armVCM4P10_ZigZag_4x4
+
+ .hidden armVCM4P10_CAVLCCoeffTokenTables
+ .hidden armVCM4P10_SuffixToLevel
+ .hidden armVCM4P10_CAVLCTotalZeros2x2Tables
+ .hidden armVCM4P10_CAVLCTotalZeroTables
+ .hidden armVCM4P10_CAVLCRunBeforeTables
+ .hidden armVCM4P10_ZigZag_2x2
+ .hidden armVCM4P10_ZigZag_4x4
+
.global armVCM4P10_DecodeCoeffsToPair
.func armVCM4P10_DecodeCoeffsToPair
armVCM4P10_DecodeCoeffsToPair:
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_DequantTables_s.S b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_DequantTables_s.S
index 44eb428..5bc7875 100644
--- a/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_DequantTables_s.S
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/arm_neon/vc/m4p10/src_gcc/armVCM4P10_DequantTables_s.S
@@ -20,6 +20,14 @@
.global armVCM4P10_QPModuloTable
.global armVCM4P10_VMatrixU16
+ .hidden armVCM4P10_QPDivTable
+ .hidden armVCM4P10_VMatrixQPModTable
+ .hidden armVCM4P10_PosToVCol4x4
+ .hidden armVCM4P10_PosToVCol2x2
+ .hidden armVCM4P10_VMatrix
+ .hidden armVCM4P10_QPModuloTable
+ .hidden armVCM4P10_VMatrixU16
+
armVCM4P10_PosToVCol4x4:
.byte 0, 2, 0, 2
.byte 2, 1, 2, 1
diff --git a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/api/omxtypes.h b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/api/omxtypes.h
index 8b295a6..912cb0d 100644
--- a/media/libstagefright/codecs/on2/h264dec/omxdl/reference/api/omxtypes.h
+++ b/media/libstagefright/codecs/on2/h264dec/omxdl/reference/api/omxtypes.h
@@ -32,6 +32,7 @@
#define _OMXTYPES_H_
#include <limits.h>
+#include <stdint.h>
#define OMX_IN
#define OMX_OUT
@@ -75,64 +76,22 @@ typedef enum {
/* OMX_U8 */
-#if UCHAR_MAX == 0xff
-typedef unsigned char OMX_U8;
-#elif USHRT_MAX == 0xff
-typedef unsigned short int OMX_U8;
-#else
-#error OMX_U8 undefined
-#endif
-
+typedef uint8_t OMX_U8;
/* OMX_S8 */
-#if SCHAR_MAX == 0x7f
-typedef signed char OMX_S8;
-#elif SHRT_MAX == 0x7f
-typedef signed short int OMX_S8;
-#else
-#error OMX_S8 undefined
-#endif
-
+typedef int8_t OMX_S8;
/* OMX_U16 */
-#if USHRT_MAX == 0xffff
-typedef unsigned short int OMX_U16;
-#elif UINT_MAX == 0xffff
-typedef unsigned int OMX_U16;
-#else
-#error OMX_U16 undefined
-#endif
-
+typedef uint16_t OMX_U16;
/* OMX_S16 */
-#if SHRT_MAX == 0x7fff
-typedef signed short int OMX_S16;
-#elif INT_MAX == 0x7fff
-typedef signed int OMX_S16;
-#else
-#error OMX_S16 undefined
-#endif
-
+typedef int16_t OMX_S16;
/* OMX_U32 */
-#if UINT_MAX == 0xffffffff
-typedef unsigned int OMX_U32;
-#elif LONG_MAX == 0xffffffff
-typedef unsigned long int OMX_U32;
-#else
-#error OMX_U32 undefined
-#endif
-
+typedef uint32_t OMX_U32;
/* OMX_S32 */
-#if INT_MAX == 0x7fffffff
-typedef signed int OMX_S32;
-#elif LONG_MAX == 0x7fffffff
-typedef long signed int OMX_S32;
-#else
-#error OMX_S32 undefined
-#endif
-
+typedef int32_t OMX_S32;
/* OMX_U64 & OMX_S64 */
#if defined( _WIN32 ) || defined ( _WIN64 )
@@ -143,15 +102,14 @@ typedef long signed int OMX_S32;
#define OMX_MAX_S64 (0x7FFFFFFFFFFFFFFFi64)
#define OMX_MAX_U64 (0xFFFFFFFFFFFFFFFFi64)
#else
- typedef long long OMX_S64; /** Signed 64-bit integer */
- typedef unsigned long long OMX_U64; /** Unsigned 64-bit integer */
+ typedef int64_t OMX_S64; /** Signed 64-bit integer */
+ typedef uint64_t OMX_U64; /** Unsigned 64-bit integer */
#define OMX_MIN_S64 (0x8000000000000000LL)
#define OMX_MIN_U64 (0x0000000000000000LL)
#define OMX_MAX_S64 (0x7FFFFFFFFFFFFFFFLL)
#define OMX_MAX_U64 (0xFFFFFFFFFFFFFFFFLL)
#endif
-
/* OMX_SC8 */
typedef struct
{
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_conceal.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_conceal.c
index 493fb9e..7a262ed 100755
--- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_conceal.c
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_conceal.c
@@ -267,7 +267,7 @@ u32 ConcealMb(mbStorage_t *pMb, image_t *currImage, u32 row, u32 col,
i32 firstPhase[16];
i32 *pTmp;
/* neighbours above, below, left and right */
- i32 a[4], b[4], l[4], r[4];
+ i32 a[4] = { 0,0,0,0 }, b[4], l[4] = { 0,0,0,0 }, r[4];
u32 A, B, L, R;
#ifdef H264DEC_OMXDL
u8 fillBuff[32*21 + 15 + 32];
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_intra_prediction.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_intra_prediction.c
index 15eabfb..52c85e5 100755
--- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_intra_prediction.c
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_intra_prediction.c
@@ -1110,7 +1110,7 @@ void Intra16x16PlanePrediction(u8 *data, u8 *above, u8 *left)
/* Variables */
- u32 i, j;
+ i32 i, j;
i32 a, b, c;
i32 tmp;
@@ -1123,20 +1123,20 @@ void Intra16x16PlanePrediction(u8 *data, u8 *above, u8 *left)
a = 16 * (above[15] + left[15]);
for (i = 0, b = 0; i < 8; i++)
- b += ((i32)i + 1) * (above[8+i] - above[6-i]);
+ b += (i + 1) * (above[8+i] - above[6-i]);
b = (5 * b + 32) >> 6;
for (i = 0, c = 0; i < 7; i++)
- c += ((i32)i + 1) * (left[8+i] - left[6-i]);
+ c += (i + 1) * (left[8+i] - left[6-i]);
/* p[-1,-1] has to be accessed through above pointer */
- c += ((i32)i + 1) * (left[8+i] - above[-1]);
+ c += (i + 1) * (left[8+i] - above[-1]);
c = (5 * c + 32) >> 6;
for (i = 0; i < 16; i++)
{
for (j = 0; j < 16; j++)
{
- tmp = (a + b * ((i32)j - 7) + c * ((i32)i - 7) + 16) >> 5;
+ tmp = (a + b * (j - 7) + c * (i - 7) + 16) >> 5;
data[i*16+j] = (u8)CLIP1(tmp);
}
}
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_util.c b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_util.c
index cc838fd..fb97a28 100755
--- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_util.c
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_util.c
@@ -186,7 +186,7 @@ u32 h264bsdMoreRbspData(strmData_t *pStrmData)
return(HANTRO_FALSE);
if ( (bits > 8) ||
- ((h264bsdShowBits32(pStrmData)>>(32-bits)) != (1 << (bits-1))) )
+ ((h264bsdShowBits32(pStrmData)>>(32-bits)) != (1ul << (bits-1))) )
return(HANTRO_TRUE);
else
return(HANTRO_FALSE);
diff --git a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_util.h b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_util.h
index cb3adda..216ad04 100755
--- a/media/libstagefright/codecs/on2/h264dec/source/h264bsd_util.h
+++ b/media/libstagefright/codecs/on2/h264dec/source/h264bsd_util.h
@@ -42,6 +42,7 @@
#include <stdio.h>
#endif
+#include <stdint.h>
#include "basetype.h"
#include "h264bsd_stream.h"
#include "h264bsd_image.h"
@@ -150,7 +151,7 @@
}
#define ALIGN(ptr, bytePos) \
- (ptr + ( ((bytePos - (int)ptr) & (bytePos - 1)) / sizeof(*ptr) ))
+ (ptr + ( ((bytePos - (uintptr_t)ptr) & (bytePos - 1)) / sizeof(*ptr) ))
extern const u32 h264bsdQpC[52];
diff --git a/media/libstagefright/codecs/raw/SoftRaw.cpp b/media/libstagefright/codecs/raw/SoftRaw.cpp
index 19d6f13..9d514a6 100644
--- a/media/libstagefright/codecs/raw/SoftRaw.cpp
+++ b/media/libstagefright/codecs/raw/SoftRaw.cpp
@@ -163,7 +163,7 @@ OMX_ERRORTYPE SoftRaw::internalSetParameter(
}
}
-void SoftRaw::onQueueFilled(OMX_U32 portIndex) {
+void SoftRaw::onQueueFilled(OMX_U32 /* portIndex */) {
if (mSignalledError) {
return;
}
diff --git a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp
index 51bb958..8f356b6 100644
--- a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp
+++ b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp
@@ -54,6 +54,8 @@ SoftVorbis::SoftVorbis(
mAnchorTimeUs(0),
mNumFramesOutput(0),
mNumFramesLeftOnPage(-1),
+ mSawInputEos(false),
+ mSignalledOutputEos(false),
mOutputPortSettingsChange(NONE) {
initPorts();
CHECK_EQ(initDecoder(), (status_t)OK);
@@ -290,48 +292,47 @@ void SoftVorbis::onQueueFilled(OMX_U32 portIndex) {
return;
}
- while (!inQueue.empty() && !outQueue.empty()) {
- BufferInfo *inInfo = *inQueue.begin();
- OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
+ while ((!inQueue.empty() || (mSawInputEos && !mSignalledOutputEos)) && !outQueue.empty()) {
+ BufferInfo *inInfo = NULL;
+ OMX_BUFFERHEADERTYPE *inHeader = NULL;
+ if (!inQueue.empty()) {
+ inInfo = *inQueue.begin();
+ inHeader = inInfo->mHeader;
+ }
BufferInfo *outInfo = *outQueue.begin();
OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
- if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
- inQueue.erase(inQueue.begin());
- inInfo->mOwnedByUs = false;
- notifyEmptyBufferDone(inHeader);
+ int32_t numPageSamples = 0;
- outHeader->nFilledLen = 0;
- outHeader->nFlags = OMX_BUFFERFLAG_EOS;
+ if (inHeader) {
+ if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
+ mSawInputEos = true;
+ }
- outQueue.erase(outQueue.begin());
- outInfo->mOwnedByUs = false;
- notifyFillBufferDone(outHeader);
- return;
- }
+ if (inHeader->nFilledLen || !mSawInputEos) {
+ CHECK_GE(inHeader->nFilledLen, sizeof(numPageSamples));
+ memcpy(&numPageSamples,
+ inHeader->pBuffer
+ + inHeader->nOffset + inHeader->nFilledLen - 4,
+ sizeof(numPageSamples));
- int32_t numPageSamples;
- CHECK_GE(inHeader->nFilledLen, sizeof(numPageSamples));
- memcpy(&numPageSamples,
- inHeader->pBuffer
- + inHeader->nOffset + inHeader->nFilledLen - 4,
- sizeof(numPageSamples));
+ if (inHeader->nOffset == 0) {
+ mAnchorTimeUs = inHeader->nTimeStamp;
+ mNumFramesOutput = 0;
+ }
- if (numPageSamples >= 0) {
- mNumFramesLeftOnPage = numPageSamples;
+ inHeader->nFilledLen -= sizeof(numPageSamples);;
+ }
}
- if (inHeader->nOffset == 0) {
- mAnchorTimeUs = inHeader->nTimeStamp;
- mNumFramesOutput = 0;
+ if (numPageSamples >= 0) {
+ mNumFramesLeftOnPage = numPageSamples;
}
- inHeader->nFilledLen -= sizeof(numPageSamples);;
-
ogg_buffer buf;
- buf.data = inHeader->pBuffer + inHeader->nOffset;
- buf.size = inHeader->nFilledLen;
+ buf.data = inHeader ? inHeader->pBuffer + inHeader->nOffset : NULL;
+ buf.size = inHeader ? inHeader->nFilledLen : 0;
buf.refcount = 1;
buf.ptr.owner = NULL;
@@ -351,9 +352,15 @@ void SoftVorbis::onQueueFilled(OMX_U32 portIndex) {
int numFrames = 0;
+ outHeader->nFlags = 0;
int err = vorbis_dsp_synthesis(mState, &pack, 1);
if (err != 0) {
+ // FIXME temporary workaround for log spam
+#if !defined(__arm__) && !defined(__aarch64__)
+ ALOGV("vorbis_dsp_synthesis returned %d", err);
+#else
ALOGW("vorbis_dsp_synthesis returned %d", err);
+#endif
} else {
numFrames = vorbis_dsp_pcmout(
mState, (int16_t *)outHeader->pBuffer,
@@ -370,13 +377,16 @@ void SoftVorbis::onQueueFilled(OMX_U32 portIndex) {
ALOGV("discarding %d frames at end of page",
numFrames - mNumFramesLeftOnPage);
numFrames = mNumFramesLeftOnPage;
+ if (mSawInputEos) {
+ outHeader->nFlags = OMX_BUFFERFLAG_EOS;
+ mSignalledOutputEos = true;
+ }
}
mNumFramesLeftOnPage -= numFrames;
}
outHeader->nFilledLen = numFrames * sizeof(int16_t) * mVi->channels;
outHeader->nOffset = 0;
- outHeader->nFlags = 0;
outHeader->nTimeStamp =
mAnchorTimeUs
@@ -384,11 +394,13 @@ void SoftVorbis::onQueueFilled(OMX_U32 portIndex) {
mNumFramesOutput += numFrames;
- inInfo->mOwnedByUs = false;
- inQueue.erase(inQueue.begin());
- inInfo = NULL;
- notifyEmptyBufferDone(inHeader);
- inHeader = NULL;
+ if (inHeader) {
+ inInfo->mOwnedByUs = false;
+ inQueue.erase(inQueue.begin());
+ inInfo = NULL;
+ notifyEmptyBufferDone(inHeader);
+ inHeader = NULL;
+ }
outInfo->mOwnedByUs = false;
outQueue.erase(outQueue.begin());
@@ -425,6 +437,8 @@ void SoftVorbis::onReset() {
mVi = NULL;
}
+ mSawInputEos = false;
+ mSignalledOutputEos = false;
mOutputPortSettingsChange = NONE;
}
diff --git a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.h b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.h
index cb628a0..1d00816 100644
--- a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.h
+++ b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.h
@@ -59,6 +59,8 @@ private:
int64_t mAnchorTimeUs;
int64_t mNumFramesOutput;
int32_t mNumFramesLeftOnPage;
+ bool mSawInputEos;
+ bool mSignalledOutputEos;
enum {
NONE,
diff --git a/media/libstagefright/foundation/ANetworkSession.cpp b/media/libstagefright/foundation/ANetworkSession.cpp
index e629588..4504c2b 100644
--- a/media/libstagefright/foundation/ANetworkSession.cpp
+++ b/media/libstagefright/foundation/ANetworkSession.cpp
@@ -521,7 +521,7 @@ status_t ANetworkSession::Session::readMore() {
return err;
}
-void ANetworkSession::Session::dumpFragmentStats(const Fragment &frag) {
+void ANetworkSession::Session::dumpFragmentStats(const Fragment & /* frag */) {
#if 0
int64_t nowUs = ALooper::GetNowUs();
int64_t delayMs = (nowUs - frag.mTimeUs) / 1000ll;
@@ -579,7 +579,7 @@ status_t ANetworkSession::Session::writeMore() {
if (err == -EAGAIN) {
if (!mOutFragments.empty()) {
- ALOGI("%d datagrams remain queued.", mOutFragments.size());
+ ALOGI("%zu datagrams remain queued.", mOutFragments.size());
}
err = OK;
}
@@ -623,7 +623,7 @@ status_t ANetworkSession::Session::writeMore() {
CHECK_EQ(mState, CONNECTED);
CHECK(!mOutFragments.empty());
- ssize_t n;
+ ssize_t n = -1;
while (!mOutFragments.empty()) {
const Fragment &frag = *mOutFragments.begin();
diff --git a/media/libstagefright/foundation/AString.cpp b/media/libstagefright/foundation/AString.cpp
index dee786d..b6b21f1 100644
--- a/media/libstagefright/foundation/AString.cpp
+++ b/media/libstagefright/foundation/AString.cpp
@@ -189,64 +189,64 @@ void AString::append(const AString &from, size_t offset, size_t n) {
void AString::append(int x) {
char s[16];
- sprintf(s, "%d", x);
-
+ int result = snprintf(s, sizeof(s), "%d", x);
+ CHECK((result > 0) && ((size_t) result) < sizeof(s));
append(s);
}
void AString::append(unsigned x) {
char s[16];
- sprintf(s, "%u", x);
-
+ int result = snprintf(s, sizeof(s), "%u", x);
+ CHECK((result > 0) && ((size_t) result) < sizeof(s));
append(s);
}
void AString::append(long x) {
- char s[16];
- sprintf(s, "%ld", x);
-
+ char s[32];
+ int result = snprintf(s, sizeof(s), "%ld", x);
+ CHECK((result > 0) && ((size_t) result) < sizeof(s));
append(s);
}
void AString::append(unsigned long x) {
- char s[16];
- sprintf(s, "%lu", x);
-
+ char s[32];
+ int result = snprintf(s, sizeof(s), "%lu", x);
+ CHECK((result > 0) && ((size_t) result) < sizeof(s));
append(s);
}
void AString::append(long long x) {
char s[32];
- sprintf(s, "%lld", x);
-
+ int result = snprintf(s, sizeof(s), "%lld", x);
+ CHECK((result > 0) && ((size_t) result) < sizeof(s));
append(s);
}
void AString::append(unsigned long long x) {
char s[32];
- sprintf(s, "%llu", x);
-
+ int result = snprintf(s, sizeof(s), "%llu", x);
+ CHECK((result > 0) && ((size_t) result) < sizeof(s));
append(s);
}
void AString::append(float x) {
char s[16];
- sprintf(s, "%f", x);
-
+ int result = snprintf(s, sizeof(s), "%f", x);
+ CHECK((result > 0) && ((size_t) result) < sizeof(s));
append(s);
}
void AString::append(double x) {
char s[16];
- sprintf(s, "%f", x);
-
+ int result = snprintf(s, sizeof(s), "%f", x);
+ CHECK((result > 0) && ((size_t) result) < sizeof(s));
append(s);
}
void AString::append(void *x) {
- char s[16];
- sprintf(s, "%p", x);
-
+ char s[32];
+ int result = snprintf(s, sizeof(s), "%p", x);
+ CHECK((result > 0) && ((size_t) result) < sizeof(s));
append(s);
}
diff --git a/media/libstagefright/foundation/Android.mk b/media/libstagefright/foundation/Android.mk
index ad2dab5..90a6a23 100644
--- a/media/libstagefright/foundation/Android.mk
+++ b/media/libstagefright/foundation/Android.mk
@@ -24,7 +24,7 @@ LOCAL_SHARED_LIBRARIES := \
libutils \
liblog
-LOCAL_CFLAGS += -Wno-multichar
+LOCAL_CFLAGS += -Wno-multichar -Werror
LOCAL_MODULE:= libstagefright_foundation
diff --git a/media/libstagefright/httplive/LiveSession.cpp b/media/libstagefright/httplive/LiveSession.cpp
index bd12ddc..6d48ab7 100644
--- a/media/libstagefright/httplive/LiveSession.cpp
+++ b/media/libstagefright/httplive/LiveSession.cpp
@@ -37,7 +37,10 @@
#include <media/stagefright/MetaData.h>
#include <media/stagefright/Utils.h>
+#include <utils/Mutex.h>
+
#include <ctype.h>
+#include <inttypes.h>
#include <openssl/aes.h>
#include <openssl/md5.h>
@@ -57,32 +60,57 @@ LiveSession::LiveSession(
: 0)),
mPrevBandwidthIndex(-1),
mStreamMask(0),
+ mNewStreamMask(0),
+ mSwapMask(0),
mCheckBandwidthGeneration(0),
+ mSwitchGeneration(0),
mLastDequeuedTimeUs(0ll),
mRealTimeBaseUs(0ll),
mReconfigurationInProgress(false),
- mDisconnectReplyID(0) {
+ mSwitchInProgress(false),
+ mDisconnectReplyID(0),
+ mSeekReplyID(0) {
if (mUIDValid) {
mHTTPDataSource->setUID(mUID);
}
- mPacketSources.add(
- STREAMTYPE_AUDIO, new AnotherPacketSource(NULL /* meta */));
-
- mPacketSources.add(
- STREAMTYPE_VIDEO, new AnotherPacketSource(NULL /* meta */));
+ mStreams[kAudioIndex] = StreamItem("audio");
+ mStreams[kVideoIndex] = StreamItem("video");
+ mStreams[kSubtitleIndex] = StreamItem("subtitles");
- mPacketSources.add(
- STREAMTYPE_SUBTITLES, new AnotherPacketSource(NULL /* meta */));
+ for (size_t i = 0; i < kMaxStreams; ++i) {
+ mPacketSources.add(indexToType(i), new AnotherPacketSource(NULL /* meta */));
+ mPacketSources2.add(indexToType(i), new AnotherPacketSource(NULL /* meta */));
+ }
}
LiveSession::~LiveSession() {
}
+sp<ABuffer> LiveSession::createFormatChangeBuffer(bool swap) {
+ ABuffer *discontinuity = new ABuffer(0);
+ discontinuity->meta()->setInt32("discontinuity", ATSParser::DISCONTINUITY_FORMATCHANGE);
+ discontinuity->meta()->setInt32("swapPacketSource", swap);
+ discontinuity->meta()->setInt32("switchGeneration", mSwitchGeneration);
+ discontinuity->meta()->setInt64("timeUs", -1);
+ return discontinuity;
+}
+
+void LiveSession::swapPacketSource(StreamType stream) {
+ sp<AnotherPacketSource> &aps = mPacketSources.editValueFor(stream);
+ sp<AnotherPacketSource> &aps2 = mPacketSources2.editValueFor(stream);
+ sp<AnotherPacketSource> tmp = aps;
+ aps = aps2;
+ aps2 = tmp;
+ aps2->clear();
+}
+
status_t LiveSession::dequeueAccessUnit(
StreamType stream, sp<ABuffer> *accessUnit) {
if (!(mStreamMask & stream)) {
- return UNKNOWN_ERROR;
+ // return -EWOULDBLOCK to avoid halting the decoder
+ // when switching between audio/video and audio only.
+ return -EWOULDBLOCK;
}
sp<AnotherPacketSource> packetSource = mPacketSources.valueFor(stream);
@@ -122,11 +150,30 @@ status_t LiveSession::dequeueAccessUnit(
streamStr,
type,
extra == NULL ? "NULL" : extra->debugString().c_str());
+
+ int32_t swap;
+ if (type == ATSParser::DISCONTINUITY_FORMATCHANGE
+ && (*accessUnit)->meta()->findInt32("swapPacketSource", &swap)
+ && swap) {
+
+ int32_t switchGeneration;
+ CHECK((*accessUnit)->meta()->findInt32("switchGeneration", &switchGeneration));
+ {
+ Mutex::Autolock lock(mSwapMutex);
+ if (switchGeneration == mSwitchGeneration) {
+ swapPacketSource(stream);
+ sp<AMessage> msg = new AMessage(kWhatSwapped, id());
+ msg->setInt32("stream", stream);
+ msg->setInt32("switchGeneration", switchGeneration);
+ msg->post();
+ }
+ }
+ }
} else if (err == OK) {
if (stream == STREAMTYPE_AUDIO || stream == STREAMTYPE_VIDEO) {
int64_t timeUs;
CHECK((*accessUnit)->meta()->findInt64("timeUs", &timeUs));
- ALOGV("[%s] read buffer at time %lld us", streamStr, timeUs);
+ ALOGV("[%s] read buffer at time %" PRId64 " us", streamStr, timeUs);
mLastDequeuedTimeUs = timeUs;
mRealTimeBaseUs = ALooper::GetNowUs() - timeUs;
@@ -143,6 +190,7 @@ status_t LiveSession::dequeueAccessUnit(
}
status_t LiveSession::getStreamFormat(StreamType stream, sp<AMessage> *format) {
+ // No swapPacketSource race condition; called from the same thread as dequeueAccessUnit.
if (!(mStreamMask & stream)) {
return UNKNOWN_ERROR;
}
@@ -188,6 +236,10 @@ status_t LiveSession::seekTo(int64_t timeUs) {
sp<AMessage> response;
status_t err = msg->postAndAwaitResponse(&response);
+ uint32_t replyID;
+ CHECK(response == mSeekReply && 0 != mSeekReplyID);
+ mSeekReply.clear();
+ mSeekReplyID = 0;
return err;
}
@@ -213,15 +265,12 @@ void LiveSession::onMessageReceived(const sp<AMessage> &msg) {
case kWhatSeek:
{
- uint32_t replyID;
- CHECK(msg->senderAwaitsResponse(&replyID));
+ CHECK(msg->senderAwaitsResponse(&mSeekReplyID));
status_t err = onSeek(msg);
- sp<AMessage> response = new AMessage;
- response->setInt32("err", err);
-
- response->postReply(replyID);
+ mSeekReply = new AMessage;
+ mSeekReply->setInt32("err", err);
break;
}
@@ -239,13 +288,23 @@ void LiveSession::onMessageReceived(const sp<AMessage> &msg) {
if (what == PlaylistFetcher::kWhatStopped) {
AString uri;
CHECK(msg->findString("uri", &uri));
- mFetcherInfos.removeItem(uri);
+ if (mFetcherInfos.removeItem(uri) < 0) {
+ // ignore duplicated kWhatStopped messages.
+ break;
+ }
+
+ tryToFinishBandwidthSwitch();
}
if (mContinuation != NULL) {
CHECK_GT(mContinuationCounter, 0);
if (--mContinuationCounter == 0) {
mContinuation->post();
+
+ if (mSeekReplyID != 0) {
+ CHECK(mSeekReply != NULL);
+ mSeekReply->postReply(mSeekReplyID);
+ }
}
}
break;
@@ -275,6 +334,8 @@ void LiveSession::onMessageReceived(const sp<AMessage> &msg) {
postPrepared(err);
}
+ cancelBandwidthSwitch();
+
mPacketSources.valueFor(STREAMTYPE_AUDIO)->signalEOS(err);
mPacketSources.valueFor(STREAMTYPE_VIDEO)->signalEOS(err);
@@ -313,6 +374,27 @@ void LiveSession::onMessageReceived(const sp<AMessage> &msg) {
break;
}
+ case PlaylistFetcher::kWhatStartedAt:
+ {
+ int32_t switchGeneration;
+ CHECK(msg->findInt32("switchGeneration", &switchGeneration));
+
+ if (switchGeneration != mSwitchGeneration) {
+ break;
+ }
+
+ // Resume fetcher for the original variant; the resumed fetcher should
+ // continue until the timestamps found in msg, which is stored by the
+ // new fetcher to indicate where the new variant has started buffering.
+ for (size_t i = 0; i < mFetcherInfos.size(); i++) {
+ const FetcherInfo info = mFetcherInfos.valueAt(i);
+ if (info.mToBeRemoved) {
+ info.mFetcher->resumeUntilAsync(msg);
+ }
+ }
+ break;
+ }
+
default:
TRESPASS();
}
@@ -357,6 +439,11 @@ void LiveSession::onMessageReceived(const sp<AMessage> &msg) {
break;
}
+ case kWhatSwapped:
+ {
+ onSwapped(msg);
+ break;
+ }
default:
TRESPASS();
break;
@@ -374,6 +461,12 @@ int LiveSession::SortByBandwidth(const BandwidthItem *a, const BandwidthItem *b)
return 1;
}
+// static
+LiveSession::StreamType LiveSession::indexToType(int idx) {
+ CHECK(idx >= 0 && idx < kMaxStreams);
+ return (StreamType)(1 << idx);
+}
+
void LiveSession::onConnect(const sp<AMessage> &msg) {
AString url;
CHECK(msg->findString("url", &url));
@@ -400,7 +493,7 @@ void LiveSession::onConnect(const sp<AMessage> &msg) {
mPlaylist = fetchPlaylist(url.c_str(), NULL /* curPlaylistHash */, &dummy);
if (mPlaylist == NULL) {
- ALOGE("unable to fetch master playlist '%s'.", url.c_str());
+ ALOGE("unable to fetch master playlist <URL suppressed>.");
postPrepared(ERROR_IO);
return;
@@ -461,6 +554,10 @@ void LiveSession::finishDisconnect() {
// during disconnection either.
cancelCheckBandwidthEvent();
+ // Protect mPacketSources from a swapPacketSource race condition through disconnect.
+ // (finishDisconnect, onFinishDisconnect2)
+ cancelBandwidthSwitch();
+
for (size_t i = 0; i < mFetcherInfos.size(); ++i) {
mFetcherInfos.valueAt(i).mFetcher->stopAsync();
}
@@ -500,11 +597,13 @@ sp<PlaylistFetcher> LiveSession::addFetcher(const char *uri) {
sp<AMessage> notify = new AMessage(kWhatFetcherNotify, id());
notify->setString("uri", uri);
+ notify->setInt32("switchGeneration", mSwitchGeneration);
FetcherInfo info;
info.mFetcher = new PlaylistFetcher(notify, this, uri);
info.mDurationUs = -1ll;
info.mIsPrepared = false;
+ info.mToBeRemoved = false;
looper()->registerHandler(info.mFetcher);
mFetcherInfos.add(uri, info);
@@ -512,56 +611,85 @@ sp<PlaylistFetcher> LiveSession::addFetcher(const char *uri) {
return info.mFetcher;
}
-status_t LiveSession::fetchFile(
+/*
+ * Illustration of parameters:
+ *
+ * 0 `range_offset`
+ * +------------+-------------------------------------------------------+--+--+
+ * | | | next block to fetch | | |
+ * | | `source` handle => `out` buffer | | | |
+ * | `url` file |<--------- buffer size --------->|<--- `block_size` -->| | |
+ * | |<----------- `range_length` / buffer capacity ----------->| |
+ * |<------------------------------ file_size ------------------------------->|
+ *
+ * Special parameter values:
+ * - range_length == -1 means entire file
+ * - block_size == 0 means entire range
+ *
+ */
+ssize_t LiveSession::fetchFile(
const char *url, sp<ABuffer> *out,
- int64_t range_offset, int64_t range_length) {
- *out = NULL;
+ int64_t range_offset, int64_t range_length,
+ uint32_t block_size, /* download block size */
+ sp<DataSource> *source, /* to return and reuse source */
+ String8 *actualUrl) {
+ off64_t size;
+ sp<DataSource> temp_source;
+ if (source == NULL) {
+ source = &temp_source;
+ }
- sp<DataSource> source;
+ if (*source == NULL) {
+ if (!strncasecmp(url, "file://", 7)) {
+ *source = new FileSource(url + 7);
+ } else if (strncasecmp(url, "http://", 7)
+ && strncasecmp(url, "https://", 8)) {
+ return ERROR_UNSUPPORTED;
+ } else {
+ KeyedVector<String8, String8> headers = mExtraHeaders;
+ if (range_offset > 0 || range_length >= 0) {
+ headers.add(
+ String8("Range"),
+ String8(
+ StringPrintf(
+ "bytes=%lld-%s",
+ range_offset,
+ range_length < 0
+ ? "" : StringPrintf("%lld",
+ range_offset + range_length - 1).c_str()).c_str()));
+ }
+ status_t err = mHTTPDataSource->connect(url, &headers);
- if (!strncasecmp(url, "file://", 7)) {
- source = new FileSource(url + 7);
- } else if (strncasecmp(url, "http://", 7)
- && strncasecmp(url, "https://", 8)) {
- return ERROR_UNSUPPORTED;
- } else {
- KeyedVector<String8, String8> headers = mExtraHeaders;
- if (range_offset > 0 || range_length >= 0) {
- headers.add(
- String8("Range"),
- String8(
- StringPrintf(
- "bytes=%lld-%s",
- range_offset,
- range_length < 0
- ? "" : StringPrintf("%lld", range_offset + range_length - 1).c_str()).c_str()));
- }
- status_t err = mHTTPDataSource->connect(url, &headers);
+ if (err != OK) {
+ return err;
+ }
- if (err != OK) {
- return err;
+ *source = mHTTPDataSource;
}
-
- source = mHTTPDataSource;
}
- off64_t size;
- status_t err = source->getSize(&size);
-
- if (err != OK) {
+ status_t getSizeErr = (*source)->getSize(&size);
+ if (getSizeErr != OK) {
size = 65536;
}
- sp<ABuffer> buffer = new ABuffer(size);
- buffer->setRange(0, 0);
+ sp<ABuffer> buffer = *out != NULL ? *out : new ABuffer(size);
+ if (*out == NULL) {
+ buffer->setRange(0, 0);
+ }
+ ssize_t bytesRead = 0;
+ // adjust range_length if only reading partial block
+ if (block_size > 0 && (range_length == -1 || buffer->size() + block_size < range_length)) {
+ range_length = buffer->size() + block_size;
+ }
for (;;) {
+ // Only resize when we don't know the size.
size_t bufferRemaining = buffer->capacity() - buffer->size();
-
- if (bufferRemaining == 0) {
+ if (bufferRemaining == 0 && getSizeErr != OK) {
bufferRemaining = 32768;
- ALOGV("increasing download buffer to %d bytes",
+ ALOGV("increasing download buffer to %zu bytes",
buffer->size() + bufferRemaining);
sp<ABuffer> copy = new ABuffer(buffer->size() + bufferRemaining);
@@ -574,7 +702,7 @@ status_t LiveSession::fetchFile(
size_t maxBytesToRead = bufferRemaining;
if (range_length >= 0) {
int64_t bytesLeftInRange = range_length - buffer->size();
- if (bytesLeftInRange < maxBytesToRead) {
+ if (bytesLeftInRange < (int64_t)maxBytesToRead) {
maxBytesToRead = bytesLeftInRange;
if (bytesLeftInRange == 0) {
@@ -583,7 +711,9 @@ status_t LiveSession::fetchFile(
}
}
- ssize_t n = source->readAt(
+ // The DataSource is responsible for informing us of error (n < 0) or eof (n == 0)
+ // to help us break out of the loop.
+ ssize_t n = (*source)->readAt(
buffer->size(), buffer->data() + buffer->size(),
maxBytesToRead);
@@ -596,11 +726,18 @@ status_t LiveSession::fetchFile(
}
buffer->setRange(0, buffer->size() + (size_t)n);
+ bytesRead += n;
}
*out = buffer;
+ if (actualUrl != NULL) {
+ *actualUrl = (*source)->getUri();
+ if (actualUrl->isEmpty()) {
+ *actualUrl = url;
+ }
+ }
- return OK;
+ return bytesRead;
}
sp<M3UParser> LiveSession::fetchPlaylist(
@@ -610,9 +747,10 @@ sp<M3UParser> LiveSession::fetchPlaylist(
*unchanged = false;
sp<ABuffer> buffer;
- status_t err = fetchFile(url, &buffer);
+ String8 actualUrl;
+ ssize_t err = fetchFile(url, &buffer, 0, -1, 0, NULL, &actualUrl);
- if (err != OK) {
+ if (err <= 0) {
return NULL;
}
@@ -632,9 +770,6 @@ sp<M3UParser> LiveSession::fetchPlaylist(
// playlist unchanged
*unchanged = true;
- ALOGV("Playlist unchanged, refresh state is now %d",
- (int)mRefreshState);
-
return NULL;
}
@@ -644,7 +779,7 @@ sp<M3UParser> LiveSession::fetchPlaylist(
#endif
sp<M3UParser> playlist =
- new M3UParser(url, buffer->data(), buffer->size());
+ new M3UParser(actualUrl.string(), buffer->data(), buffer->size());
if (playlist->initCheck() != OK) {
ALOGE("failed to parse .m3u8 playlist");
@@ -810,14 +945,31 @@ status_t LiveSession::selectTrack(size_t index, bool select) {
return err;
}
+bool LiveSession::canSwitchUp() {
+ // Allow upwards bandwidth switch when a stream has buffered at least 10 seconds.
+ status_t err = OK;
+ for (size_t i = 0; i < mPacketSources.size(); ++i) {
+ sp<AnotherPacketSource> source = mPacketSources.valueAt(i);
+ int64_t dur = source->getBufferedDurationUs(&err);
+ if (err == OK && dur > 10000000) {
+ return true;
+ }
+ }
+ return false;
+}
+
void LiveSession::changeConfiguration(
int64_t timeUs, size_t bandwidthIndex, bool pickTrack) {
+ // Protect mPacketSources from a swapPacketSource race condition through reconfiguration.
+ // (changeConfiguration, onChangeConfiguration2, onChangeConfiguration3).
+ cancelBandwidthSwitch();
+
CHECK(!mReconfigurationInProgress);
mReconfigurationInProgress = true;
mPrevBandwidthIndex = bandwidthIndex;
- ALOGV("changeConfiguration => timeUs:%lld us, bwIndex:%d, pickTrack:%d",
+ ALOGV("changeConfiguration => timeUs:%" PRId64 " us, bwIndex:%zu, pickTrack:%d",
timeUs, bandwidthIndex, pickTrack);
if (pickTrack) {
@@ -827,21 +979,14 @@ void LiveSession::changeConfiguration(
CHECK_LT(bandwidthIndex, mBandwidthItems.size());
const BandwidthItem &item = mBandwidthItems.itemAt(bandwidthIndex);
- uint32_t streamMask = 0;
-
- AString audioURI;
- if (mPlaylist->getAudioURI(item.mPlaylistIndex, &audioURI)) {
- streamMask |= STREAMTYPE_AUDIO;
- }
-
- AString videoURI;
- if (mPlaylist->getVideoURI(item.mPlaylistIndex, &videoURI)) {
- streamMask |= STREAMTYPE_VIDEO;
- }
+ uint32_t streamMask = 0; // streams that should be fetched by the new fetcher
+ uint32_t resumeMask = 0; // streams that should be fetched by the original fetcher
- AString subtitleURI;
- if (mPlaylist->getSubtitleURI(item.mPlaylistIndex, &subtitleURI)) {
- streamMask |= STREAMTYPE_SUBTITLES;
+ AString URIs[kMaxStreams];
+ for (size_t i = 0; i < kMaxStreams; ++i) {
+ if (mPlaylist->getTypeURI(item.mPlaylistIndex, mStreams[i].mType, &URIs[i])) {
+ streamMask |= indexToType(i);
+ }
}
// Step 1, stop and discard fetchers that are no longer needed.
@@ -853,10 +998,15 @@ void LiveSession::changeConfiguration(
// If we're seeking all current fetchers are discarded.
if (timeUs < 0ll) {
- if (((streamMask & STREAMTYPE_AUDIO) && uri == audioURI)
- || ((streamMask & STREAMTYPE_VIDEO) && uri == videoURI)
- || ((streamMask & STREAMTYPE_SUBTITLES) && uri == subtitleURI)) {
- discardFetcher = false;
+ // delay fetcher removal
+ discardFetcher = false;
+
+ for (size_t j = 0; j < kMaxStreams; ++j) {
+ StreamType type = indexToType(j);
+ if ((streamMask & type) && uri == URIs[j]) {
+ resumeMask |= type;
+ streamMask &= ~type;
+ }
}
}
@@ -867,17 +1017,20 @@ void LiveSession::changeConfiguration(
}
}
- sp<AMessage> msg = new AMessage(kWhatChangeConfiguration2, id());
+ sp<AMessage> msg;
+ if (timeUs < 0ll) {
+ // skip onChangeConfiguration2 (decoder destruction) if switching.
+ msg = new AMessage(kWhatChangeConfiguration3, id());
+ } else {
+ msg = new AMessage(kWhatChangeConfiguration2, id());
+ }
msg->setInt32("streamMask", streamMask);
+ msg->setInt32("resumeMask", resumeMask);
msg->setInt64("timeUs", timeUs);
- if (streamMask & STREAMTYPE_AUDIO) {
- msg->setString("audioURI", audioURI.c_str());
- }
- if (streamMask & STREAMTYPE_VIDEO) {
- msg->setString("videoURI", videoURI.c_str());
- }
- if (streamMask & STREAMTYPE_SUBTITLES) {
- msg->setString("subtitleURI", subtitleURI.c_str());
+ for (size_t i = 0; i < kMaxStreams; ++i) {
+ if (streamMask & indexToType(i)) {
+ msg->setString(mStreams[i].uriKey().c_str(), URIs[i].c_str());
+ }
}
// Every time a fetcher acknowledges the stopAsync or pauseAsync request
@@ -889,6 +1042,11 @@ void LiveSession::changeConfiguration(
if (mContinuationCounter == 0) {
msg->post();
+
+ if (mSeekReplyID != 0) {
+ CHECK(mSeekReply != NULL);
+ mSeekReply->postReply(mSeekReplyID);
+ }
}
}
@@ -908,18 +1066,13 @@ void LiveSession::onChangeConfiguration2(const sp<AMessage> &msg) {
uint32_t streamMask;
CHECK(msg->findInt32("streamMask", (int32_t *)&streamMask));
- AString audioURI, videoURI, subtitleURI;
- if (streamMask & STREAMTYPE_AUDIO) {
- CHECK(msg->findString("audioURI", &audioURI));
- ALOGV("audioURI = '%s'", audioURI.c_str());
- }
- if (streamMask & STREAMTYPE_VIDEO) {
- CHECK(msg->findString("videoURI", &videoURI));
- ALOGV("videoURI = '%s'", videoURI.c_str());
- }
- if (streamMask & STREAMTYPE_SUBTITLES) {
- CHECK(msg->findString("subtitleURI", &subtitleURI));
- ALOGV("subtitleURI = '%s'", subtitleURI.c_str());
+ AString URIs[kMaxStreams];
+ for (size_t i = 0; i < kMaxStreams; ++i) {
+ if (streamMask & indexToType(i)) {
+ const AString &uriKey = mStreams[i].uriKey();
+ CHECK(msg->findString(uriKey.c_str(), &URIs[i]));
+ ALOGV("%s = '%s'", uriKey.c_str(), URIs[i].c_str());
+ }
}
// Determine which decoders to shutdown on the player side,
@@ -929,15 +1082,12 @@ void LiveSession::onChangeConfiguration2(const sp<AMessage> &msg) {
// 2) its streamtype was already active and still is but the URI
// has changed.
uint32_t changedMask = 0;
- if (((mStreamMask & streamMask & STREAMTYPE_AUDIO)
- && !(audioURI == mAudioURI))
- || (mStreamMask & ~streamMask & STREAMTYPE_AUDIO)) {
- changedMask |= STREAMTYPE_AUDIO;
- }
- if (((mStreamMask & streamMask & STREAMTYPE_VIDEO)
- && !(videoURI == mVideoURI))
- || (mStreamMask & ~streamMask & STREAMTYPE_VIDEO)) {
- changedMask |= STREAMTYPE_VIDEO;
+ for (size_t i = 0; i < kMaxStreams && i != kSubtitleIndex; ++i) {
+ if (((mStreamMask & streamMask & indexToType(i))
+ && !(URIs[i] == mStreams[i].mUri))
+ || (mStreamMask & ~streamMask & indexToType(i))) {
+ changedMask |= indexToType(i);
+ }
}
if (changedMask == 0) {
@@ -963,68 +1113,54 @@ void LiveSession::onChangeConfiguration2(const sp<AMessage> &msg) {
}
void LiveSession::onChangeConfiguration3(const sp<AMessage> &msg) {
+ mContinuation.clear();
// All remaining fetchers are still suspended, the player has shutdown
// any decoders that needed it.
- uint32_t streamMask;
+ uint32_t streamMask, resumeMask;
CHECK(msg->findInt32("streamMask", (int32_t *)&streamMask));
+ CHECK(msg->findInt32("resumeMask", (int32_t *)&resumeMask));
- AString audioURI, videoURI, subtitleURI;
- if (streamMask & STREAMTYPE_AUDIO) {
- CHECK(msg->findString("audioURI", &audioURI));
- }
- if (streamMask & STREAMTYPE_VIDEO) {
- CHECK(msg->findString("videoURI", &videoURI));
- }
- if (streamMask & STREAMTYPE_SUBTITLES) {
- CHECK(msg->findString("subtitleURI", &subtitleURI));
+ for (size_t i = 0; i < kMaxStreams; ++i) {
+ if (streamMask & indexToType(i)) {
+ CHECK(msg->findString(mStreams[i].uriKey().c_str(), &mStreams[i].mUri));
+ }
}
int64_t timeUs;
+ bool switching = false;
CHECK(msg->findInt64("timeUs", &timeUs));
if (timeUs < 0ll) {
timeUs = mLastDequeuedTimeUs;
+ switching = true;
}
mRealTimeBaseUs = ALooper::GetNowUs() - timeUs;
- mStreamMask = streamMask;
- mAudioURI = audioURI;
- mVideoURI = videoURI;
- mSubtitleURI = subtitleURI;
+ mNewStreamMask = streamMask;
- // Resume all existing fetchers and assign them packet sources.
+ // Of all existing fetchers:
+ // * Resume fetchers that are still needed and assign them original packet sources.
+ // * Mark otherwise unneeded fetchers for removal.
+ ALOGV("resuming fetchers for mask 0x%08x", resumeMask);
for (size_t i = 0; i < mFetcherInfos.size(); ++i) {
const AString &uri = mFetcherInfos.keyAt(i);
- uint32_t resumeMask = 0;
-
- sp<AnotherPacketSource> audioSource;
- if ((streamMask & STREAMTYPE_AUDIO) && uri == audioURI) {
- audioSource = mPacketSources.valueFor(STREAMTYPE_AUDIO);
- resumeMask |= STREAMTYPE_AUDIO;
- }
-
- sp<AnotherPacketSource> videoSource;
- if ((streamMask & STREAMTYPE_VIDEO) && uri == videoURI) {
- videoSource = mPacketSources.valueFor(STREAMTYPE_VIDEO);
- resumeMask |= STREAMTYPE_VIDEO;
+ sp<AnotherPacketSource> sources[kMaxStreams];
+ for (size_t j = 0; j < kMaxStreams; ++j) {
+ if ((resumeMask & indexToType(j)) && uri == mStreams[j].mUri) {
+ sources[j] = mPacketSources.valueFor(indexToType(j));
+ }
}
- sp<AnotherPacketSource> subtitleSource;
- if ((streamMask & STREAMTYPE_SUBTITLES) && uri == subtitleURI) {
- subtitleSource = mPacketSources.valueFor(STREAMTYPE_SUBTITLES);
- resumeMask |= STREAMTYPE_SUBTITLES;
+ FetcherInfo &info = mFetcherInfos.editValueAt(i);
+ if (sources[kAudioIndex] != NULL || sources[kVideoIndex] != NULL
+ || sources[kSubtitleIndex] != NULL) {
+ info.mFetcher->startAsync(
+ sources[kAudioIndex], sources[kVideoIndex], sources[kSubtitleIndex]);
+ } else {
+ info.mToBeRemoved = true;
}
-
- CHECK_NE(resumeMask, 0u);
-
- ALOGV("resuming fetchers for mask 0x%08x", resumeMask);
-
- streamMask &= ~resumeMask;
-
- mFetcherInfos.valueAt(i).mFetcher->startAsync(
- audioSource, videoSource, subtitleSource);
}
// streamMask now only contains the types that need a new fetcher created.
@@ -1033,52 +1169,65 @@ void LiveSession::onChangeConfiguration3(const sp<AMessage> &msg) {
ALOGV("creating new fetchers for mask 0x%08x", streamMask);
}
- while (streamMask != 0) {
- StreamType streamType = (StreamType)(streamMask & ~(streamMask - 1));
+ // Find out when the original fetchers have buffered up to and start the new fetchers
+ // at a later timestamp.
+ for (size_t i = 0; i < kMaxStreams; i++) {
+ if (!(indexToType(i) & streamMask)) {
+ continue;
+ }
AString uri;
- switch (streamType) {
- case STREAMTYPE_AUDIO:
- uri = audioURI;
- break;
- case STREAMTYPE_VIDEO:
- uri = videoURI;
- break;
- case STREAMTYPE_SUBTITLES:
- uri = subtitleURI;
- break;
- default:
- TRESPASS();
- }
+ uri = mStreams[i].mUri;
sp<PlaylistFetcher> fetcher = addFetcher(uri.c_str());
CHECK(fetcher != NULL);
- sp<AnotherPacketSource> audioSource;
- if ((streamMask & STREAMTYPE_AUDIO) && uri == audioURI) {
- audioSource = mPacketSources.valueFor(STREAMTYPE_AUDIO);
- audioSource->clear();
-
- streamMask &= ~STREAMTYPE_AUDIO;
- }
-
- sp<AnotherPacketSource> videoSource;
- if ((streamMask & STREAMTYPE_VIDEO) && uri == videoURI) {
- videoSource = mPacketSources.valueFor(STREAMTYPE_VIDEO);
- videoSource->clear();
-
- streamMask &= ~STREAMTYPE_VIDEO;
- }
+ int32_t latestSeq = -1;
+ int64_t latestTimeUs = 0ll;
+ sp<AnotherPacketSource> sources[kMaxStreams];
+
+ // TRICKY: looping from i as earlier streams are already removed from streamMask
+ for (size_t j = i; j < kMaxStreams; ++j) {
+ if ((streamMask & indexToType(j)) && uri == mStreams[j].mUri) {
+ sources[j] = mPacketSources.valueFor(indexToType(j));
+
+ if (!switching) {
+ sources[j]->clear();
+ } else {
+ int32_t type, seq;
+ int64_t srcTimeUs;
+ sp<AMessage> meta = sources[j]->getLatestMeta();
+
+ if (meta != NULL && !meta->findInt32("discontinuity", &type)) {
+ CHECK(meta->findInt32("seq", &seq));
+ if (seq > latestSeq) {
+ latestSeq = seq;
+ }
+ CHECK(meta->findInt64("timeUs", &srcTimeUs));
+ if (srcTimeUs > latestTimeUs) {
+ latestTimeUs = srcTimeUs;
+ }
+ }
- sp<AnotherPacketSource> subtitleSource;
- if ((streamMask & STREAMTYPE_SUBTITLES) && uri == subtitleURI) {
- subtitleSource = mPacketSources.valueFor(STREAMTYPE_SUBTITLES);
- subtitleSource->clear();
+ sources[j] = mPacketSources2.valueFor(indexToType(j));
+ sources[j]->clear();
+ uint32_t extraStreams = mNewStreamMask & (~mStreamMask);
+ if (extraStreams & indexToType(j)) {
+ sources[j]->queueAccessUnit(createFormatChangeBuffer(/* swap = */ false));
+ }
+ }
- streamMask &= ~STREAMTYPE_SUBTITLES;
+ streamMask &= ~indexToType(j);
+ }
}
- fetcher->startAsync(audioSource, videoSource, subtitleSource, timeUs);
+ fetcher->startAsync(
+ sources[kAudioIndex],
+ sources[kVideoIndex],
+ sources[kSubtitleIndex],
+ timeUs,
+ latestTimeUs /* min start time(us) */,
+ latestSeq >= 0 ? latestSeq + 1 : -1 /* starting sequence number hint */ );
}
// All fetchers have now been started, the configuration change
@@ -1087,14 +1236,61 @@ void LiveSession::onChangeConfiguration3(const sp<AMessage> &msg) {
scheduleCheckBandwidthEvent();
ALOGV("XXX configuration change completed.");
-
mReconfigurationInProgress = false;
+ if (switching) {
+ mSwitchInProgress = true;
+ } else {
+ mStreamMask = mNewStreamMask;
+ }
if (mDisconnectReplyID != 0) {
finishDisconnect();
}
}
+void LiveSession::onSwapped(const sp<AMessage> &msg) {
+ int32_t switchGeneration;
+ CHECK(msg->findInt32("switchGeneration", &switchGeneration));
+ if (switchGeneration != mSwitchGeneration) {
+ return;
+ }
+
+ int32_t stream;
+ CHECK(msg->findInt32("stream", &stream));
+ mSwapMask |= stream;
+ if (mSwapMask != mStreamMask) {
+ return;
+ }
+
+ // Check if new variant contains extra streams.
+ uint32_t extraStreams = mNewStreamMask & (~mStreamMask);
+ while (extraStreams) {
+ StreamType extraStream = (StreamType) (extraStreams & ~(extraStreams - 1));
+ swapPacketSource(extraStream);
+ extraStreams &= ~extraStream;
+ }
+
+ tryToFinishBandwidthSwitch();
+}
+
+// Mark switch done when:
+// 1. all old buffers are swapped out, AND
+// 2. all old fetchers are removed.
+void LiveSession::tryToFinishBandwidthSwitch() {
+ bool needToRemoveFetchers = false;
+ for (size_t i = 0; i < mFetcherInfos.size(); ++i) {
+ if (mFetcherInfos.valueAt(i).mToBeRemoved) {
+ needToRemoveFetchers = true;
+ break;
+ }
+ }
+ if (!needToRemoveFetchers && mSwapMask == mStreamMask) {
+ mStreamMask = mNewStreamMask;
+ mSwitchInProgress = false;
+ mSwapMask = 0;
+ }
+}
+
void LiveSession::scheduleCheckBandwidthEvent() {
sp<AMessage> msg = new AMessage(kWhatCheckBandwidth, id());
msg->setInt32("generation", mCheckBandwidthGeneration);
@@ -1105,16 +1301,37 @@ void LiveSession::cancelCheckBandwidthEvent() {
++mCheckBandwidthGeneration;
}
-void LiveSession::onCheckBandwidth() {
- if (mReconfigurationInProgress) {
- scheduleCheckBandwidthEvent();
- return;
+void LiveSession::cancelBandwidthSwitch() {
+ Mutex::Autolock lock(mSwapMutex);
+ mSwitchGeneration++;
+ mSwitchInProgress = false;
+ mSwapMask = 0;
+}
+
+bool LiveSession::canSwitchBandwidthTo(size_t bandwidthIndex) {
+ if (mReconfigurationInProgress || mSwitchInProgress) {
+ return false;
+ }
+
+ if (mPrevBandwidthIndex < 0) {
+ return true;
}
+ if (bandwidthIndex == (size_t)mPrevBandwidthIndex) {
+ return false;
+ } else if (bandwidthIndex > (size_t)mPrevBandwidthIndex) {
+ return canSwitchUp();
+ } else {
+ return true;
+ }
+}
+
+void LiveSession::onCheckBandwidth() {
size_t bandwidthIndex = getBandwidthIndex();
- if (mPrevBandwidthIndex < 0
- || bandwidthIndex != (size_t)mPrevBandwidthIndex) {
+ if (canSwitchBandwidthTo(bandwidthIndex)) {
changeConfiguration(-1ll /* timeUs */, bandwidthIndex);
+ } else {
+ scheduleCheckBandwidthEvent();
}
// Handling the kWhatCheckBandwidth even here does _not_ automatically
diff --git a/media/libstagefright/httplive/LiveSession.h b/media/libstagefright/httplive/LiveSession.h
index 99b480a8..3f8fee5 100644
--- a/media/libstagefright/httplive/LiveSession.h
+++ b/media/libstagefright/httplive/LiveSession.h
@@ -42,10 +42,17 @@ struct LiveSession : public AHandler {
const sp<AMessage> &notify,
uint32_t flags = 0, bool uidValid = false, uid_t uid = 0);
+ enum StreamIndex {
+ kAudioIndex = 0,
+ kVideoIndex = 1,
+ kSubtitleIndex = 2,
+ kMaxStreams = 3,
+ };
+
enum StreamType {
- STREAMTYPE_AUDIO = 1,
- STREAMTYPE_VIDEO = 2,
- STREAMTYPE_SUBTITLES = 4,
+ STREAMTYPE_AUDIO = 1 << kAudioIndex,
+ STREAMTYPE_VIDEO = 1 << kVideoIndex,
+ STREAMTYPE_SUBTITLES = 1 << kSubtitleIndex,
};
status_t dequeueAccessUnit(StreamType stream, sp<ABuffer> *accessUnit);
@@ -74,6 +81,11 @@ struct LiveSession : public AHandler {
kWhatPreparationFailed,
};
+ // create a format-change discontinuity
+ //
+ // swap:
+ // whether is format-change discontinuity should trigger a buffer swap
+ sp<ABuffer> createFormatChangeBuffer(bool swap = true);
protected:
virtual ~LiveSession();
@@ -92,6 +104,7 @@ private:
kWhatChangeConfiguration2 = 'chC2',
kWhatChangeConfiguration3 = 'chC3',
kWhatFinishDisconnect2 = 'fin2',
+ kWhatSwapped = 'swap',
};
struct BandwidthItem {
@@ -103,8 +116,22 @@ private:
sp<PlaylistFetcher> mFetcher;
int64_t mDurationUs;
bool mIsPrepared;
+ bool mToBeRemoved;
};
+ struct StreamItem {
+ const char *mType;
+ AString mUri;
+ StreamItem() : mType("") {}
+ StreamItem(const char *type) : mType(type) {}
+ AString uriKey() {
+ AString key(mType);
+ key.append("URI");
+ return key;
+ }
+ };
+ StreamItem mStreams[kMaxStreams];
+
sp<AMessage> mNotify;
uint32_t mFlags;
bool mUIDValid;
@@ -123,21 +150,40 @@ private:
sp<M3UParser> mPlaylist;
KeyedVector<AString, FetcherInfo> mFetcherInfos;
- AString mAudioURI, mVideoURI, mSubtitleURI;
uint32_t mStreamMask;
+ // Masks used during reconfiguration:
+ // mNewStreamMask: streams in the variant playlist we're switching to;
+ // we don't want to immediately overwrite the original value.
+ uint32_t mNewStreamMask;
+
+ // mSwapMask: streams that have started to playback content in the new variant playlist;
+ // we use this to track reconfiguration progress.
+ uint32_t mSwapMask;
+
KeyedVector<StreamType, sp<AnotherPacketSource> > mPacketSources;
+ // A second set of packet sources that buffer content for the variant we're switching to.
+ KeyedVector<StreamType, sp<AnotherPacketSource> > mPacketSources2;
+
+ // A mutex used to serialize two sets of events:
+ // * the swapping of packet sources in dequeueAccessUnit on the player thread, AND
+ // * a forced bandwidth switch termination in cancelSwitch on the live looper.
+ Mutex mSwapMutex;
int32_t mCheckBandwidthGeneration;
+ int32_t mSwitchGeneration;
size_t mContinuationCounter;
sp<AMessage> mContinuation;
+ sp<AMessage> mSeekReply;
int64_t mLastDequeuedTimeUs;
int64_t mRealTimeBaseUs;
bool mReconfigurationInProgress;
+ bool mSwitchInProgress;
uint32_t mDisconnectReplyID;
+ uint32_t mSeekReplyID;
sp<PlaylistFetcher> addFetcher(const char *uri);
@@ -145,9 +191,26 @@ private:
status_t onSeek(const sp<AMessage> &msg);
void onFinishDisconnect2();
- status_t fetchFile(
+ // If given a non-zero block_size (default 0), it is used to cap the number of
+ // bytes read in from the DataSource. If given a non-NULL buffer, new content
+ // is read into the end.
+ //
+ // The DataSource we read from is responsible for signaling error or EOF to help us
+ // break out of the read loop. The DataSource can be returned to the caller, so
+ // that the caller can reuse it for subsequent fetches (within the initially
+ // requested range).
+ //
+ // For reused HTTP sources, the caller must download a file sequentially without
+ // any overlaps or gaps to prevent reconnection.
+ ssize_t fetchFile(
const char *url, sp<ABuffer> *out,
- int64_t range_offset = 0, int64_t range_length = -1);
+ /* request/open a file starting at range_offset for range_length bytes */
+ int64_t range_offset = 0, int64_t range_length = -1,
+ /* download block size */
+ uint32_t block_size = 0,
+ /* reuse DataSource if doing partial fetch */
+ sp<DataSource> *source = NULL,
+ String8 *actualUrl = NULL);
sp<M3UParser> fetchPlaylist(
const char *url, uint8_t *curPlaylistHash, bool *unchanged);
@@ -155,22 +218,34 @@ private:
size_t getBandwidthIndex();
static int SortByBandwidth(const BandwidthItem *, const BandwidthItem *);
+ static StreamType indexToType(int idx);
void changeConfiguration(
int64_t timeUs, size_t bandwidthIndex, bool pickTrack = false);
void onChangeConfiguration(const sp<AMessage> &msg);
void onChangeConfiguration2(const sp<AMessage> &msg);
void onChangeConfiguration3(const sp<AMessage> &msg);
+ void onSwapped(const sp<AMessage> &msg);
+ void tryToFinishBandwidthSwitch();
void scheduleCheckBandwidthEvent();
void cancelCheckBandwidthEvent();
+ // cancelBandwidthSwitch is atomic wrt swapPacketSource; call it to prevent packet sources
+ // from being swapped out on stale discontinuities while manipulating
+ // mPacketSources/mPacketSources2.
+ void cancelBandwidthSwitch();
+
+ bool canSwitchBandwidthTo(size_t bandwidthIndex);
void onCheckBandwidth();
void finishDisconnect();
void postPrepared(status_t err);
+ void swapPacketSource(StreamType stream);
+ bool canSwitchUp();
+
DISALLOW_EVIL_CONSTRUCTORS(LiveSession);
};
diff --git a/media/libstagefright/httplive/M3UParser.cpp b/media/libstagefright/httplive/M3UParser.cpp
index 243888c..0700de0 100644
--- a/media/libstagefright/httplive/M3UParser.cpp
+++ b/media/libstagefright/httplive/M3UParser.cpp
@@ -24,6 +24,7 @@
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/MediaErrors.h>
+#include <media/stagefright/Utils.h>
#include <media/mediaplayer.h>
namespace android {
@@ -125,7 +126,7 @@ void M3UParser::MediaGroup::pickRandomMediaItems() {
mSelectedIndex = strtoul(value, &end, 10);
CHECK(end > value && *end == '\0');
- if (mSelectedIndex >= mMediaItems.size()) {
+ if (mSelectedIndex >= (ssize_t)mMediaItems.size()) {
mSelectedIndex = mMediaItems.size() - 1;
}
} else {
@@ -162,18 +163,18 @@ status_t M3UParser::MediaGroup::selectTrack(size_t index, bool select) {
if (select) {
if (index >= mMediaItems.size()) {
- ALOGE("track %d does not exist", index);
+ ALOGE("track %zu does not exist", index);
return INVALID_OPERATION;
}
- if (mSelectedIndex == index) {
- ALOGE("track %d already selected", index);
+ if (mSelectedIndex == (ssize_t)index) {
+ ALOGE("track %zu already selected", index);
return BAD_VALUE;
}
ALOGV("selected track %d", index);
mSelectedIndex = index;
} else {
- if (mSelectedIndex != index) {
- ALOGE("track %d is not selected", index);
+ if (mSelectedIndex != (ssize_t)index) {
+ ALOGE("track %zu is not selected", index);
return BAD_VALUE;
}
ALOGV("unselected track %d", index);
@@ -352,9 +353,28 @@ bool M3UParser::getTypeURI(size_t index, const char *key, AString *uri) const {
if (!meta->findString(key, &groupID)) {
*uri = mItems.itemAt(index).mURI;
- // Assume media without any more specific attribute contains
- // audio and video, but no subtitles.
- return !strcmp("audio", key) || !strcmp("video", key);
+ AString codecs;
+ if (!meta->findString("codecs", &codecs)) {
+ // Assume media without any more specific attribute contains
+ // audio and video, but no subtitles.
+ return !strcmp("audio", key) || !strcmp("video", key);
+ } else {
+ // Split the comma separated list of codecs.
+ size_t offset = 0;
+ ssize_t commaPos = -1;
+ codecs.append(',');
+ while ((commaPos = codecs.find(",", offset)) >= 0) {
+ AString codec(codecs, offset, commaPos - offset);
+ codec.trim();
+ // return true only if a codec of type `key` ("audio"/"video")
+ // is found.
+ if (codecIsType(codec, key)) {
+ return true;
+ }
+ offset = commaPos + 1;
+ }
+ return false;
+ }
}
sp<MediaGroup> group = mMediaGroups.valueFor(groupID);
@@ -369,18 +389,6 @@ bool M3UParser::getTypeURI(size_t index, const char *key, AString *uri) const {
return true;
}
-bool M3UParser::getAudioURI(size_t index, AString *uri) const {
- return getTypeURI(index, "audio", uri);
-}
-
-bool M3UParser::getVideoURI(size_t index, AString *uri) const {
- return getTypeURI(index, "video", uri);
-}
-
-bool M3UParser::getSubtitleURI(size_t index, AString *uri) const {
- return getTypeURI(index, "subtitles", uri);
-}
-
static bool MakeURL(const char *baseURL, const char *url, AString *out) {
out->clear();
@@ -390,6 +398,8 @@ static bool MakeURL(const char *baseURL, const char *url, AString *out) {
// Base URL must be absolute
return false;
}
+ const size_t schemeEnd = (strstr(baseURL, "//") - baseURL) + 2;
+ CHECK(schemeEnd == 7 || schemeEnd == 8);
if (!strncasecmp("http://", url, 7) || !strncasecmp("https://", url, 8)) {
// "url" is already an absolute URL, ignore base URL.
@@ -416,22 +426,32 @@ static bool MakeURL(const char *baseURL, const char *url, AString *out) {
} else {
// URL is a relative path
- size_t n = strlen(baseURL);
- if (baseURL[n - 1] == '/') {
- out->setTo(baseURL);
- out->append(url);
+ // Check for a possible query string
+ const char *qsPos = strchr(baseURL, '?');
+ size_t end;
+ if (qsPos != NULL) {
+ end = qsPos - baseURL;
} else {
- const char *slashPos = strrchr(baseURL, '/');
-
- if (slashPos > &baseURL[6]) {
- out->setTo(baseURL, slashPos - baseURL);
- } else {
- out->setTo(baseURL);
+ end = strlen(baseURL);
+ }
+ // Check for the last slash before a potential query string
+ for (ssize_t pos = end - 1; pos >= 0; pos--) {
+ if (baseURL[pos] == '/') {
+ end = pos;
+ break;
}
+ }
- out->append("/");
- out->append(url);
+ // Check whether the found slash actually is part of the path
+ // and not part of the "http://".
+ if (end >= schemeEnd) {
+ out->setTo(baseURL, end);
+ } else {
+ out->setTo(baseURL);
}
+
+ out->append("/");
+ out->append(url);
}
ALOGV("base:'%s', url:'%s' => '%s'", baseURL, url, out->c_str());
@@ -608,7 +628,7 @@ status_t M3UParser::parseMetaDataDuration(
if (meta->get() == NULL) {
*meta = new AMessage;
}
- (*meta)->setInt64(key, (int64_t)x * 1E6);
+ (*meta)->setInt64(key, (int64_t)(x * 1E6));
return OK;
}
@@ -684,12 +704,25 @@ status_t M3UParser::parseStreamInf(
*meta = new AMessage;
}
(*meta)->setInt32("bandwidth", x);
+ } else if (!strcasecmp("codecs", key.c_str())) {
+ if (!isQuotedString(val)) {
+ ALOGE("Expected quoted string for %s attribute, "
+ "got '%s' instead.",
+ key.c_str(), val.c_str());;
+
+ return ERROR_MALFORMED;
+ }
+
+ key.tolower();
+ const AString &codecs = unquoteString(val);
+ if (meta->get() == NULL) {
+ *meta = new AMessage;
+ }
+ (*meta)->setString(key.c_str(), codecs.c_str());
} else if (!strcasecmp("audio", key.c_str())
|| !strcasecmp("video", key.c_str())
|| !strcasecmp("subtitles", key.c_str())) {
- if (val.size() < 2
- || val.c_str()[0] != '"'
- || val.c_str()[val.size() - 1] != '"') {
+ if (!isQuotedString(val)) {
ALOGE("Expected quoted string for %s attribute, "
"got '%s' instead.",
key.c_str(), val.c_str());
@@ -697,7 +730,7 @@ status_t M3UParser::parseStreamInf(
return ERROR_MALFORMED;
}
- AString groupID(val, 1, val.size() - 2);
+ const AString &groupID = unquoteString(val);
ssize_t groupIndex = mMediaGroups.indexOfKey(groupID);
if (groupIndex < 0) {
@@ -708,6 +741,9 @@ status_t M3UParser::parseStreamInf(
}
key.tolower();
+ if (meta->get() == NULL) {
+ *meta = new AMessage;
+ }
(*meta)->setString(key.c_str(), groupID.c_str());
}
}
@@ -770,8 +806,7 @@ status_t M3UParser::parseCipherInfo(
if (MakeURL(baseURI.c_str(), val.c_str(), &absURI)) {
val = absURI;
} else {
- ALOGE("failed to make absolute url for '%s'.",
- val.c_str());
+ ALOGE("failed to make absolute url for <URL suppressed>.");
}
}
@@ -1086,4 +1121,121 @@ status_t M3UParser::ParseDouble(const char *s, double *x) {
return OK;
}
+// static
+bool M3UParser::isQuotedString(const AString &str) {
+ if (str.size() < 2
+ || str.c_str()[0] != '"'
+ || str.c_str()[str.size() - 1] != '"') {
+ return false;
+ }
+ return true;
+}
+
+// static
+AString M3UParser::unquoteString(const AString &str) {
+ if (!isQuotedString(str)) {
+ return str;
+ }
+ return AString(str, 1, str.size() - 2);
+}
+
+// static
+bool M3UParser::codecIsType(const AString &codec, const char *type) {
+ if (codec.size() < 4) {
+ return false;
+ }
+ const char *c = codec.c_str();
+ switch (FOURCC(c[0], c[1], c[2], c[3])) {
+ // List extracted from http://www.mp4ra.org/codecs.html
+ case 'ac-3':
+ case 'alac':
+ case 'dra1':
+ case 'dtsc':
+ case 'dtse':
+ case 'dtsh':
+ case 'dtsl':
+ case 'ec-3':
+ case 'enca':
+ case 'g719':
+ case 'g726':
+ case 'm4ae':
+ case 'mlpa':
+ case 'mp4a':
+ case 'raw ':
+ case 'samr':
+ case 'sawb':
+ case 'sawp':
+ case 'sevc':
+ case 'sqcp':
+ case 'ssmv':
+ case 'twos':
+ case 'agsm':
+ case 'alaw':
+ case 'dvi ':
+ case 'fl32':
+ case 'fl64':
+ case 'ima4':
+ case 'in24':
+ case 'in32':
+ case 'lpcm':
+ case 'Qclp':
+ case 'QDM2':
+ case 'QDMC':
+ case 'ulaw':
+ case 'vdva':
+ return !strcmp("audio", type);
+
+ case 'avc1':
+ case 'avc2':
+ case 'avcp':
+ case 'drac':
+ case 'encv':
+ case 'mjp2':
+ case 'mp4v':
+ case 'mvc1':
+ case 'mvc2':
+ case 'resv':
+ case 's263':
+ case 'svc1':
+ case 'vc-1':
+ case 'CFHD':
+ case 'civd':
+ case 'DV10':
+ case 'dvh5':
+ case 'dvh6':
+ case 'dvhp':
+ case 'DVOO':
+ case 'DVOR':
+ case 'DVTV':
+ case 'DVVT':
+ case 'flic':
+ case 'gif ':
+ case 'h261':
+ case 'h263':
+ case 'HD10':
+ case 'jpeg':
+ case 'M105':
+ case 'mjpa':
+ case 'mjpb':
+ case 'png ':
+ case 'PNTG':
+ case 'rle ':
+ case 'rpza':
+ case 'Shr0':
+ case 'Shr1':
+ case 'Shr2':
+ case 'Shr3':
+ case 'Shr4':
+ case 'SVQ1':
+ case 'SVQ3':
+ case 'tga ':
+ case 'tiff':
+ case 'WRLE':
+ return !strcmp("video", type);
+
+ default:
+ return false;
+ }
+}
+
} // namespace android
diff --git a/media/libstagefright/httplive/M3UParser.h b/media/libstagefright/httplive/M3UParser.h
index 5248004..ccd6556 100644
--- a/media/libstagefright/httplive/M3UParser.h
+++ b/media/libstagefright/httplive/M3UParser.h
@@ -45,9 +45,7 @@ struct M3UParser : public RefBase {
status_t getTrackInfo(Parcel* reply) const;
ssize_t getSelectedIndex() const;
- bool getAudioURI(size_t index, AString *uri) const;
- bool getVideoURI(size_t index, AString *uri) const;
- bool getSubtitleURI(size_t index, AString *uri) const;
+ bool getTypeURI(size_t index, const char *key, AString *uri) const;
protected:
virtual ~M3UParser();
@@ -95,11 +93,13 @@ private:
status_t parseMedia(const AString &line);
- bool getTypeURI(size_t index, const char *key, AString *uri) const;
-
static status_t ParseInt32(const char *s, int32_t *x);
static status_t ParseDouble(const char *s, double *x);
+ static bool isQuotedString(const AString &str);
+ static AString unquoteString(const AString &str);
+ static bool codecIsType(const AString &codec, const char *type);
+
DISALLOW_EVIL_CONSTRUCTORS(M3UParser);
};
diff --git a/media/libstagefright/httplive/PlaylistFetcher.cpp b/media/libstagefright/httplive/PlaylistFetcher.cpp
index 973b779..513f114 100644
--- a/media/libstagefright/httplive/PlaylistFetcher.cpp
+++ b/media/libstagefright/httplive/PlaylistFetcher.cpp
@@ -40,6 +40,7 @@
#include <media/stagefright/Utils.h>
#include <ctype.h>
+#include <inttypes.h>
#include <openssl/aes.h>
#include <openssl/md5.h>
@@ -47,26 +48,35 @@ namespace android {
// static
const int64_t PlaylistFetcher::kMinBufferedDurationUs = 10000000ll;
+const int64_t PlaylistFetcher::kMaxMonitorDelayUs = 3000000ll;
+const int32_t PlaylistFetcher::kDownloadBlockSize = 192;
+const int32_t PlaylistFetcher::kNumSkipFrames = 10;
PlaylistFetcher::PlaylistFetcher(
const sp<AMessage> &notify,
const sp<LiveSession> &session,
const char *uri)
: mNotify(notify),
+ mStartTimeUsNotify(notify->dup()),
mSession(session),
mURI(uri),
mStreamTypeMask(0),
mStartTimeUs(-1ll),
+ mMinStartTimeUs(0ll),
+ mStopParams(NULL),
mLastPlaylistFetchTimeUs(-1ll),
mSeqNumber(-1),
mNumRetries(0),
mStartup(true),
+ mPrepared(false),
mNextPTSTimeUs(-1ll),
mMonitorQueueGeneration(0),
mRefreshState(INITIAL_MINIMUM_RELOAD_DELAY),
mFirstPTSValid(false),
mAbsoluteTimeAnchorUs(0ll) {
memset(mPlaylistHash, 0, sizeof(mPlaylistHash));
+ mStartTimeUsNotify->setInt32("what", kWhatStartedAt);
+ mStartTimeUsNotify->setInt32("streamMask", 0);
}
PlaylistFetcher::~PlaylistFetcher() {
@@ -103,10 +113,16 @@ int64_t PlaylistFetcher::getSegmentStartTimeUs(int32_t seqNumber) const {
return segmentStartUs;
}
-bool PlaylistFetcher::timeToRefreshPlaylist(int64_t nowUs) const {
- if (mPlaylist == NULL) {
+int64_t PlaylistFetcher::delayUsToRefreshPlaylist() const {
+ int64_t nowUs = ALooper::GetNowUs();
+
+ if (mPlaylist == NULL || mLastPlaylistFetchTimeUs < 0ll) {
CHECK_EQ((int)mRefreshState, (int)INITIAL_MINIMUM_RELOAD_DELAY);
- return true;
+ return 0ll;
+ }
+
+ if (mPlaylist->isComplete()) {
+ return (~0llu >> 1);
}
int32_t targetDurationSecs;
@@ -157,11 +173,13 @@ bool PlaylistFetcher::timeToRefreshPlaylist(int64_t nowUs) const {
break;
}
- return mLastPlaylistFetchTimeUs + minPlaylistAgeUs <= nowUs;
+ int64_t delayUs = mLastPlaylistFetchTimeUs + minPlaylistAgeUs - nowUs;
+ return delayUs > 0ll ? delayUs : 0ll;
}
status_t PlaylistFetcher::decryptBuffer(
- size_t playlistIndex, const sp<ABuffer> &buffer) {
+ size_t playlistIndex, const sp<ABuffer> &buffer,
+ bool first) {
sp<AMessage> itemMeta;
bool found = false;
AString method;
@@ -179,6 +197,7 @@ status_t PlaylistFetcher::decryptBuffer(
if (!found) {
method = "NONE";
}
+ buffer->meta()->setString("cipher-method", method.c_str());
if (method == "NONE") {
return OK;
@@ -199,9 +218,9 @@ status_t PlaylistFetcher::decryptBuffer(
if (index >= 0) {
key = mAESKeyForURI.valueAt(index);
} else {
- status_t err = mSession->fetchFile(keyURI.c_str(), &key);
+ ssize_t err = mSession->fetchFile(keyURI.c_str(), &key);
- if (err != OK) {
+ if (err < 0) {
ALOGE("failed to fetch cipher key from '%s'.", keyURI.c_str());
return ERROR_IO;
} else if (key->size() != 16) {
@@ -218,63 +237,89 @@ status_t PlaylistFetcher::decryptBuffer(
return UNKNOWN_ERROR;
}
- unsigned char aes_ivec[16];
+ size_t n = buffer->size();
+ if (!n) {
+ return OK;
+ }
+ CHECK(n % 16 == 0);
- AString iv;
- if (itemMeta->findString("cipher-iv", &iv)) {
- if ((!iv.startsWith("0x") && !iv.startsWith("0X"))
- || iv.size() != 16 * 2 + 2) {
- ALOGE("malformed cipher IV '%s'.", iv.c_str());
- return ERROR_MALFORMED;
- }
+ if (first) {
+ // If decrypting the first block in a file, read the iv from the manifest
+ // or derive the iv from the file's sequence number.
- memset(aes_ivec, 0, sizeof(aes_ivec));
- for (size_t i = 0; i < 16; ++i) {
- char c1 = tolower(iv.c_str()[2 + 2 * i]);
- char c2 = tolower(iv.c_str()[3 + 2 * i]);
- if (!isxdigit(c1) || !isxdigit(c2)) {
+ AString iv;
+ if (itemMeta->findString("cipher-iv", &iv)) {
+ if ((!iv.startsWith("0x") && !iv.startsWith("0X"))
+ || iv.size() != 16 * 2 + 2) {
ALOGE("malformed cipher IV '%s'.", iv.c_str());
return ERROR_MALFORMED;
}
- uint8_t nibble1 = isdigit(c1) ? c1 - '0' : c1 - 'a' + 10;
- uint8_t nibble2 = isdigit(c2) ? c2 - '0' : c2 - 'a' + 10;
- aes_ivec[i] = nibble1 << 4 | nibble2;
+ memset(mAESInitVec, 0, sizeof(mAESInitVec));
+ for (size_t i = 0; i < 16; ++i) {
+ char c1 = tolower(iv.c_str()[2 + 2 * i]);
+ char c2 = tolower(iv.c_str()[3 + 2 * i]);
+ if (!isxdigit(c1) || !isxdigit(c2)) {
+ ALOGE("malformed cipher IV '%s'.", iv.c_str());
+ return ERROR_MALFORMED;
+ }
+ uint8_t nibble1 = isdigit(c1) ? c1 - '0' : c1 - 'a' + 10;
+ uint8_t nibble2 = isdigit(c2) ? c2 - '0' : c2 - 'a' + 10;
+
+ mAESInitVec[i] = nibble1 << 4 | nibble2;
+ }
+ } else {
+ memset(mAESInitVec, 0, sizeof(mAESInitVec));
+ mAESInitVec[15] = mSeqNumber & 0xff;
+ mAESInitVec[14] = (mSeqNumber >> 8) & 0xff;
+ mAESInitVec[13] = (mSeqNumber >> 16) & 0xff;
+ mAESInitVec[12] = (mSeqNumber >> 24) & 0xff;
}
- } else {
- memset(aes_ivec, 0, sizeof(aes_ivec));
- aes_ivec[15] = mSeqNumber & 0xff;
- aes_ivec[14] = (mSeqNumber >> 8) & 0xff;
- aes_ivec[13] = (mSeqNumber >> 16) & 0xff;
- aes_ivec[12] = (mSeqNumber >> 24) & 0xff;
}
AES_cbc_encrypt(
buffer->data(), buffer->data(), buffer->size(),
- &aes_key, aes_ivec, AES_DECRYPT);
-
- // hexdump(buffer->data(), buffer->size());
+ &aes_key, mAESInitVec, AES_DECRYPT);
- size_t n = buffer->size();
- CHECK_GT(n, 0u);
+ return OK;
+}
- size_t pad = buffer->data()[n - 1];
+status_t PlaylistFetcher::checkDecryptPadding(const sp<ABuffer> &buffer) {
+ status_t err;
+ AString method;
+ CHECK(buffer->meta()->findString("cipher-method", &method));
+ if (method == "NONE") {
+ return OK;
+ }
- CHECK_GT(pad, 0u);
- CHECK_LE(pad, 16u);
- CHECK_GE((size_t)n, pad);
- for (size_t i = 0; i < pad; ++i) {
- CHECK_EQ((unsigned)buffer->data()[n - 1 - i], pad);
+ uint8_t padding = 0;
+ if (buffer->size() > 0) {
+ padding = buffer->data()[buffer->size() - 1];
}
- n -= pad;
+ if (padding > 16) {
+ return ERROR_MALFORMED;
+ }
- buffer->setRange(buffer->offset(), n);
+ for (size_t i = buffer->size() - padding; i < padding; i++) {
+ if (buffer->data()[i] != padding) {
+ return ERROR_MALFORMED;
+ }
+ }
+ buffer->setRange(buffer->offset(), buffer->size() - padding);
return OK;
}
-void PlaylistFetcher::postMonitorQueue(int64_t delayUs) {
+void PlaylistFetcher::postMonitorQueue(int64_t delayUs, int64_t minDelayUs) {
+ int64_t maxDelayUs = delayUsToRefreshPlaylist();
+ if (maxDelayUs < minDelayUs) {
+ maxDelayUs = minDelayUs;
+ }
+ if (delayUs > maxDelayUs) {
+ ALOGV("Need to refresh playlist in %lld", maxDelayUs);
+ delayUs = maxDelayUs;
+ }
sp<AMessage> msg = new AMessage(kWhatMonitorQueue, id());
msg->setInt32("generation", mMonitorQueueGeneration);
msg->post(delayUs);
@@ -288,7 +333,9 @@ void PlaylistFetcher::startAsync(
const sp<AnotherPacketSource> &audioSource,
const sp<AnotherPacketSource> &videoSource,
const sp<AnotherPacketSource> &subtitleSource,
- int64_t startTimeUs) {
+ int64_t startTimeUs,
+ int64_t minStartTimeUs,
+ int32_t startSeqNumberHint) {
sp<AMessage> msg = new AMessage(kWhatStart, id());
uint32_t streamTypeMask = 0ul;
@@ -310,6 +357,8 @@ void PlaylistFetcher::startAsync(
msg->setInt32("streamTypeMask", streamTypeMask);
msg->setInt64("startTimeUs", startTimeUs);
+ msg->setInt64("minStartTimeUs", minStartTimeUs);
+ msg->setInt32("startSeqNumberHint", startSeqNumberHint);
msg->post();
}
@@ -317,8 +366,16 @@ void PlaylistFetcher::pauseAsync() {
(new AMessage(kWhatPause, id()))->post();
}
-void PlaylistFetcher::stopAsync() {
- (new AMessage(kWhatStop, id()))->post();
+void PlaylistFetcher::stopAsync(bool selfTriggered) {
+ sp<AMessage> msg = new AMessage(kWhatStop, id());
+ msg->setInt32("selfTriggered", selfTriggered);
+ msg->post();
+}
+
+void PlaylistFetcher::resumeUntilAsync(const sp<AMessage> &params) {
+ AMessage* msg = new AMessage(kWhatResumeUntil, id());
+ msg->setMessage("params", params);
+ msg->post();
}
void PlaylistFetcher::onMessageReceived(const sp<AMessage> &msg) {
@@ -346,7 +403,7 @@ void PlaylistFetcher::onMessageReceived(const sp<AMessage> &msg) {
case kWhatStop:
{
- onStop();
+ onStop(msg);
sp<AMessage> notify = mNotify->dup();
notify->setInt32("what", kWhatStopped);
@@ -355,6 +412,7 @@ void PlaylistFetcher::onMessageReceived(const sp<AMessage> &msg) {
}
case kWhatMonitorQueue:
+ case kWhatDownloadNext:
{
int32_t generation;
CHECK(msg->findInt32("generation", &generation));
@@ -364,7 +422,17 @@ void PlaylistFetcher::onMessageReceived(const sp<AMessage> &msg) {
break;
}
- onMonitorQueue();
+ if (msg->what() == kWhatMonitorQueue) {
+ onMonitorQueue();
+ } else {
+ onDownloadNext();
+ }
+ break;
+ }
+
+ case kWhatResumeUntil:
+ {
+ onResumeUntil(msg);
break;
}
@@ -380,7 +448,10 @@ status_t PlaylistFetcher::onStart(const sp<AMessage> &msg) {
CHECK(msg->findInt32("streamTypeMask", (int32_t *)&streamTypeMask));
int64_t startTimeUs;
+ int32_t startSeqNumberHint;
CHECK(msg->findInt64("startTimeUs", &startTimeUs));
+ CHECK(msg->findInt64("minStartTimeUs", (int64_t *) &mMinStartTimeUs));
+ CHECK(msg->findInt32("startSeqNumberHint", &startSeqNumberHint));
if (streamTypeMask & LiveSession::STREAMTYPE_AUDIO) {
void *ptr;
@@ -415,6 +486,11 @@ status_t PlaylistFetcher::onStart(const sp<AMessage> &msg) {
if (mStartTimeUs >= 0ll) {
mSeqNumber = -1;
mStartup = true;
+ mPrepared = false;
+ }
+
+ if (startSeqNumberHint >= 0) {
+ mSeqNumber = startSeqNumberHint;
}
postMonitorQueue();
@@ -424,22 +500,83 @@ status_t PlaylistFetcher::onStart(const sp<AMessage> &msg) {
void PlaylistFetcher::onPause() {
cancelMonitorQueue();
-
- mPacketSources.clear();
- mStreamTypeMask = 0;
}
-void PlaylistFetcher::onStop() {
+void PlaylistFetcher::onStop(const sp<AMessage> &msg) {
cancelMonitorQueue();
- for (size_t i = 0; i < mPacketSources.size(); ++i) {
- mPacketSources.valueAt(i)->clear();
+ int32_t selfTriggered;
+ CHECK(msg->findInt32("selfTriggered", &selfTriggered));
+ if (!selfTriggered) {
+ // Self triggered stops only happen during switching, in which case we do not want
+ // to clear the discontinuities queued at the end of packet sources.
+ for (size_t i = 0; i < mPacketSources.size(); i++) {
+ sp<AnotherPacketSource> packetSource = mPacketSources.valueAt(i);
+ packetSource->clear();
+ }
}
mPacketSources.clear();
mStreamTypeMask = 0;
}
+// Resume until we have reached the boundary timestamps listed in `msg`; when
+// the remaining time is too short (within a resume threshold) stop immediately
+// instead.
+status_t PlaylistFetcher::onResumeUntil(const sp<AMessage> &msg) {
+ sp<AMessage> params;
+ CHECK(msg->findMessage("params", &params));
+
+ bool stop = false;
+ for (size_t i = 0; i < mPacketSources.size(); i++) {
+ sp<AnotherPacketSource> packetSource = mPacketSources.valueAt(i);
+
+ const char *stopKey;
+ int streamType = mPacketSources.keyAt(i);
+ switch (streamType) {
+ case LiveSession::STREAMTYPE_VIDEO:
+ stopKey = "timeUsVideo";
+ break;
+
+ case LiveSession::STREAMTYPE_AUDIO:
+ stopKey = "timeUsAudio";
+ break;
+
+ case LiveSession::STREAMTYPE_SUBTITLES:
+ stopKey = "timeUsSubtitle";
+ break;
+
+ default:
+ TRESPASS();
+ }
+
+ // Don't resume if we would stop within a resume threshold.
+ int64_t latestTimeUs = 0, stopTimeUs = 0;
+ sp<AMessage> latestMeta = packetSource->getLatestMeta();
+ if (latestMeta != NULL
+ && (latestMeta->findInt64("timeUs", &latestTimeUs)
+ && params->findInt64(stopKey, &stopTimeUs))) {
+ int64_t diffUs = stopTimeUs - latestTimeUs;
+ if (diffUs < resumeThreshold(latestMeta)) {
+ stop = true;
+ }
+ }
+ }
+
+ if (stop) {
+ for (size_t i = 0; i < mPacketSources.size(); i++) {
+ mPacketSources.valueAt(i)->queueAccessUnit(mSession->createFormatChangeBuffer());
+ }
+ stopAsync(/* selfTriggered = */ true);
+ return OK;
+ }
+
+ mStopParams = params;
+ postMonitorQueue();
+
+ return OK;
+}
+
void PlaylistFetcher::notifyError(status_t err) {
sp<AMessage> notify = mNotify->dup();
notify->setInt32("what", kWhatError);
@@ -456,41 +593,70 @@ void PlaylistFetcher::queueDiscontinuity(
void PlaylistFetcher::onMonitorQueue() {
bool downloadMore = false;
+ refreshPlaylist();
+
+ int32_t targetDurationSecs;
+ int64_t targetDurationUs = kMinBufferedDurationUs;
+ if (mPlaylist != NULL) {
+ CHECK(mPlaylist->meta()->findInt32("target-duration", &targetDurationSecs));
+ targetDurationUs = targetDurationSecs * 1000000ll;
+ }
- status_t finalResult;
+ // buffer at least 3 times the target duration, or up to 10 seconds
+ int64_t durationToBufferUs = targetDurationUs * 3;
+ if (durationToBufferUs > kMinBufferedDurationUs) {
+ durationToBufferUs = kMinBufferedDurationUs;
+ }
+
+ int64_t bufferedDurationUs = 0ll;
+ status_t finalResult = NOT_ENOUGH_DATA;
if (mStreamTypeMask == LiveSession::STREAMTYPE_SUBTITLES) {
sp<AnotherPacketSource> packetSource =
mPacketSources.valueFor(LiveSession::STREAMTYPE_SUBTITLES);
- int64_t bufferedDurationUs =
+ bufferedDurationUs =
packetSource->getBufferedDurationUs(&finalResult);
-
- downloadMore = (bufferedDurationUs < kMinBufferedDurationUs);
finalResult = OK;
} else {
- bool first = true;
- int64_t minBufferedDurationUs = 0ll;
-
+ // Use max stream duration to prevent us from waiting on a non-existent stream;
+ // when we cannot make out from the manifest what streams are included in a playlist
+ // we might assume extra streams.
for (size_t i = 0; i < mPacketSources.size(); ++i) {
if ((mStreamTypeMask & mPacketSources.keyAt(i)) == 0) {
continue;
}
- int64_t bufferedDurationUs =
+ int64_t bufferedStreamDurationUs =
mPacketSources.valueAt(i)->getBufferedDurationUs(&finalResult);
-
- if (first || bufferedDurationUs < minBufferedDurationUs) {
- minBufferedDurationUs = bufferedDurationUs;
- first = false;
+ ALOGV("buffered %lld for stream %d",
+ bufferedStreamDurationUs, mPacketSources.keyAt(i));
+ if (bufferedStreamDurationUs > bufferedDurationUs) {
+ bufferedDurationUs = bufferedStreamDurationUs;
}
}
+ }
+ downloadMore = (bufferedDurationUs < durationToBufferUs);
+
+ // signal start if buffered up at least the target size
+ if (!mPrepared && bufferedDurationUs > targetDurationUs && downloadMore) {
+ mPrepared = true;
- downloadMore =
- !first && (minBufferedDurationUs < kMinBufferedDurationUs);
+ ALOGV("prepared, buffered=%lld > %lld",
+ bufferedDurationUs, targetDurationUs);
+ sp<AMessage> msg = mNotify->dup();
+ msg->setInt32("what", kWhatTemporarilyDoneFetching);
+ msg->post();
}
if (finalResult == OK && downloadMore) {
- onDownloadNext();
+ ALOGV("monitoring, buffered=%lld < %lld",
+ bufferedDurationUs, durationToBufferUs);
+ // delay the next download slightly; hopefully this gives other concurrent fetchers
+ // a better chance to run.
+ // onDownloadNext();
+ sp<AMessage> msg = new AMessage(kWhatDownloadNext, id());
+ msg->setInt32("generation", mMonitorQueueGeneration);
+ msg->post(1000l);
} else {
// Nothing to do yet, try again in a second.
@@ -498,15 +664,17 @@ void PlaylistFetcher::onMonitorQueue() {
msg->setInt32("what", kWhatTemporarilyDoneFetching);
msg->post();
- postMonitorQueue(1000000ll);
+ int64_t delayUs = mPrepared ? kMaxMonitorDelayUs : targetDurationUs / 2;
+ ALOGV("pausing for %lld, buffered=%lld > %lld",
+ delayUs, bufferedDurationUs, durationToBufferUs);
+ // :TRICKY: need to enforce minimum delay because the delay to
+ // refresh the playlist will become 0
+ postMonitorQueue(delayUs, mPrepared ? targetDurationUs * 2 : 0);
}
}
-void PlaylistFetcher::onDownloadNext() {
- int64_t nowUs = ALooper::GetNowUs();
-
- if (mLastPlaylistFetchTimeUs < 0ll
- || (!mPlaylist->isComplete() && timeToRefreshPlaylist(nowUs))) {
+status_t PlaylistFetcher::refreshPlaylist() {
+ if (delayUsToRefreshPlaylist() <= 0) {
bool unchanged;
sp<M3UParser> playlist = mSession->fetchPlaylist(
mURI.c_str(), mPlaylistHash, &unchanged);
@@ -522,7 +690,7 @@ void PlaylistFetcher::onDownloadNext() {
} else {
ALOGE("failed to load playlist at url '%s'", mURI.c_str());
notifyError(ERROR_IO);
- return;
+ return ERROR_IO;
}
} else {
mRefreshState = INITIAL_MINIMUM_RELOAD_DELAY;
@@ -535,6 +703,18 @@ void PlaylistFetcher::onDownloadNext() {
mLastPlaylistFetchTimeUs = ALooper::GetNowUs();
}
+ return OK;
+}
+
+// static
+bool PlaylistFetcher::bufferStartsWithTsSyncByte(const sp<ABuffer>& buffer) {
+ return buffer->size() > 0 && buffer->data()[0] == 0x47;
+}
+
+void PlaylistFetcher::onDownloadNext() {
+ if (refreshPlaylist() != OK) {
+ return;
+ }
int32_t firstSeqNumberInPlaylist;
if (mPlaylist->meta() == NULL || !mPlaylist->meta()->findInt32(
@@ -548,17 +728,29 @@ void PlaylistFetcher::onDownloadNext() {
const int32_t lastSeqNumberInPlaylist =
firstSeqNumberInPlaylist + (int32_t)mPlaylist->size() - 1;
+ if (mStartup && mSeqNumber >= 0
+ && (mSeqNumber < firstSeqNumberInPlaylist || mSeqNumber > lastSeqNumberInPlaylist)) {
+ // in case we guessed wrong during reconfiguration, try fetching the latest content.
+ mSeqNumber = lastSeqNumberInPlaylist;
+ }
+
if (mSeqNumber < 0) {
CHECK_GE(mStartTimeUs, 0ll);
if (mPlaylist->isComplete() || mPlaylist->isEvent()) {
mSeqNumber = getSeqNumberForTime(mStartTimeUs);
+ ALOGV("Initial sequence number for time %lld is %ld from (%ld .. %ld)",
+ mStartTimeUs, mSeqNumber, firstSeqNumberInPlaylist,
+ lastSeqNumberInPlaylist);
} else {
// If this is a live session, start 3 segments from the end.
mSeqNumber = lastSeqNumberInPlaylist - 3;
if (mSeqNumber < firstSeqNumberInPlaylist) {
mSeqNumber = firstSeqNumberInPlaylist;
}
+ ALOGV("Initial sequence number for live event %ld from (%ld .. %ld)",
+ mSeqNumber, firstSeqNumberInPlaylist,
+ lastSeqNumberInPlaylist);
}
mStartTimeUs = -1ll;
@@ -570,16 +762,34 @@ void PlaylistFetcher::onDownloadNext() {
++mNumRetries;
if (mSeqNumber > lastSeqNumberInPlaylist) {
- mLastPlaylistFetchTimeUs = -1;
- postMonitorQueue(3000000ll);
+ // refresh in increasing fraction (1/2, 1/3, ...) of the
+ // playlist's target duration or 3 seconds, whichever is less
+ int32_t targetDurationSecs;
+ CHECK(mPlaylist->meta()->findInt32(
+ "target-duration", &targetDurationSecs));
+ int64_t delayUs = mPlaylist->size() * targetDurationSecs *
+ 1000000ll / (1 + mNumRetries);
+ if (delayUs > kMaxMonitorDelayUs) {
+ delayUs = kMaxMonitorDelayUs;
+ }
+ ALOGV("sequence number high: %ld from (%ld .. %ld), monitor in %lld (retry=%d)",
+ mSeqNumber, firstSeqNumberInPlaylist,
+ lastSeqNumberInPlaylist, delayUs, mNumRetries);
+ postMonitorQueue(delayUs);
return;
}
// we've missed the boat, let's start from the lowest sequence
// number available and signal a discontinuity.
- ALOGI("We've missed the boat, restarting playback.");
- mSeqNumber = lastSeqNumberInPlaylist;
+ ALOGI("We've missed the boat, restarting playback."
+ " mStartup=%d, was looking for %d in %d-%d",
+ mStartup, mSeqNumber, firstSeqNumberInPlaylist,
+ lastSeqNumberInPlaylist);
+ mSeqNumber = lastSeqNumberInPlaylist - 3;
+ if (mSeqNumber < firstSeqNumberInPlaylist) {
+ mSeqNumber = firstSeqNumberInPlaylist;
+ }
explicitDiscontinuity = true;
// fall through
@@ -587,7 +797,7 @@ void PlaylistFetcher::onDownloadNext() {
ALOGE("Cannot find sequence number %d in playlist "
"(contains %d - %d)",
mSeqNumber, firstSeqNumberInPlaylist,
- firstSeqNumberInPlaylist + mPlaylist->size() - 1);
+ firstSeqNumberInPlaylist + (int32_t)mPlaylist->size() - 1);
notifyError(ERROR_END_OF_STREAM);
return;
@@ -620,50 +830,160 @@ void PlaylistFetcher::onDownloadNext() {
ALOGV("fetching '%s'", uri.c_str());
- sp<ABuffer> buffer;
- status_t err = mSession->fetchFile(
- uri.c_str(), &buffer, range_offset, range_length);
-
- if (err != OK) {
- ALOGE("failed to fetch .ts segment at url '%s'", uri.c_str());
- notifyError(err);
- return;
+ sp<DataSource> source;
+ sp<ABuffer> buffer, tsBuffer;
+ // decrypt a junk buffer to prefetch key; since a session uses only one http connection,
+ // this avoids interleaved connections to the key and segment file.
+ {
+ sp<ABuffer> junk = new ABuffer(16);
+ junk->setRange(0, 16);
+ status_t err = decryptBuffer(mSeqNumber - firstSeqNumberInPlaylist, junk,
+ true /* first */);
+ if (err != OK) {
+ notifyError(err);
+ return;
+ }
}
- CHECK(buffer != NULL);
+ // block-wise download
+ ssize_t bytesRead;
+ do {
+ bytesRead = mSession->fetchFile(
+ uri.c_str(), &buffer, range_offset, range_length, kDownloadBlockSize, &source);
+
+ if (bytesRead < 0) {
+ status_t err = bytesRead;
+ ALOGE("failed to fetch .ts segment at url '%s'", uri.c_str());
+ notifyError(err);
+ return;
+ }
- err = decryptBuffer(mSeqNumber - firstSeqNumberInPlaylist, buffer);
+ CHECK(buffer != NULL);
- if (err != OK) {
- ALOGE("decryptBuffer failed w/ error %d", err);
+ size_t size = buffer->size();
+ // Set decryption range.
+ buffer->setRange(size - bytesRead, bytesRead);
+ status_t err = decryptBuffer(mSeqNumber - firstSeqNumberInPlaylist, buffer,
+ buffer->offset() == 0 /* first */);
+ // Unset decryption range.
+ buffer->setRange(0, size);
- notifyError(err);
- return;
- }
+ if (err != OK) {
+ ALOGE("decryptBuffer failed w/ error %d", err);
- if (mStartup || seekDiscontinuity || explicitDiscontinuity) {
- // Signal discontinuity.
+ notifyError(err);
+ return;
+ }
- if (mPlaylist->isComplete() || mPlaylist->isEvent()) {
- // If this was a live event this made no sense since
- // we don't have access to all the segment before the current
- // one.
- mNextPTSTimeUs = getSegmentStartTimeUs(mSeqNumber);
+ if (mStartup || seekDiscontinuity || explicitDiscontinuity) {
+ // Signal discontinuity.
+
+ if (mPlaylist->isComplete() || mPlaylist->isEvent()) {
+ // If this was a live event this made no sense since
+ // we don't have access to all the segment before the current
+ // one.
+ mNextPTSTimeUs = getSegmentStartTimeUs(mSeqNumber);
+ }
+
+ if (seekDiscontinuity || explicitDiscontinuity) {
+ ALOGI("queueing discontinuity (seek=%d, explicit=%d)",
+ seekDiscontinuity, explicitDiscontinuity);
+
+ queueDiscontinuity(
+ explicitDiscontinuity
+ ? ATSParser::DISCONTINUITY_FORMATCHANGE
+ : ATSParser::DISCONTINUITY_SEEK,
+ NULL /* extra */);
+ }
+ }
+
+ err = OK;
+ if (bufferStartsWithTsSyncByte(buffer)) {
+ // Incremental extraction is only supported for MPEG2 transport streams.
+ if (tsBuffer == NULL) {
+ tsBuffer = new ABuffer(buffer->data(), buffer->capacity());
+ tsBuffer->setRange(0, 0);
+ } else if (tsBuffer->capacity() != buffer->capacity()) {
+ size_t tsOff = tsBuffer->offset(), tsSize = tsBuffer->size();
+ tsBuffer = new ABuffer(buffer->data(), buffer->capacity());
+ tsBuffer->setRange(tsOff, tsSize);
+ }
+ tsBuffer->setRange(tsBuffer->offset(), tsBuffer->size() + bytesRead);
+
+ err = extractAndQueueAccessUnitsFromTs(tsBuffer);
+ }
+
+ if (err == -EAGAIN) {
+ // bad starting sequence number hint
+ postMonitorQueue();
+ return;
}
- if (seekDiscontinuity || explicitDiscontinuity) {
- ALOGI("queueing discontinuity (seek=%d, explicit=%d)",
- seekDiscontinuity, explicitDiscontinuity);
+ if (err == ERROR_OUT_OF_RANGE) {
+ // reached stopping point
+ stopAsync(/* selfTriggered = */ true);
+ return;
+ }
- queueDiscontinuity(
- explicitDiscontinuity
- ? ATSParser::DISCONTINUITY_FORMATCHANGE
- : ATSParser::DISCONTINUITY_SEEK,
- NULL /* extra */);
+ if (err != OK) {
+ notifyError(err);
+ return;
}
+
+ mStartup = false;
+ } while (bytesRead != 0);
+
+ if (bufferStartsWithTsSyncByte(buffer)) {
+ // If we still don't see a stream after fetching a full ts segment mark it as
+ // nonexistent.
+ const size_t kNumTypes = ATSParser::NUM_SOURCE_TYPES;
+ ATSParser::SourceType srcTypes[kNumTypes] =
+ { ATSParser::VIDEO, ATSParser::AUDIO };
+ LiveSession::StreamType streamTypes[kNumTypes] =
+ { LiveSession::STREAMTYPE_VIDEO, LiveSession::STREAMTYPE_AUDIO };
+
+ for (size_t i = 0; i < kNumTypes; i++) {
+ ATSParser::SourceType srcType = srcTypes[i];
+ LiveSession::StreamType streamType = streamTypes[i];
+
+ sp<AnotherPacketSource> source =
+ static_cast<AnotherPacketSource *>(
+ mTSParser->getSource(srcType).get());
+
+ if (source == NULL) {
+ ALOGW("MPEG2 Transport stream does not contain %s data.",
+ srcType == ATSParser::VIDEO ? "video" : "audio");
+
+ mStreamTypeMask &= ~streamType;
+ mPacketSources.removeItem(streamType);
+ }
+ }
+
+ }
+
+ if (checkDecryptPadding(buffer) != OK) {
+ ALOGE("Incorrect padding bytes after decryption.");
+ notifyError(ERROR_MALFORMED);
+ return;
}
- err = extractAndQueueAccessUnits(buffer, itemMeta);
+ status_t err = OK;
+ if (tsBuffer != NULL) {
+ AString method;
+ CHECK(buffer->meta()->findString("cipher-method", &method));
+ if ((tsBuffer->size() > 0 && method == "NONE")
+ || tsBuffer->size() > 16) {
+ ALOGE("MPEG2 transport stream is not an even multiple of 188 "
+ "bytes in length.");
+ notifyError(ERROR_MALFORMED);
+ return;
+ }
+ }
+
+ // bulk extract non-ts files
+ if (tsBuffer == NULL) {
+ err = extractAndQueueAccessUnits(buffer, itemMeta);
+ }
if (err != OK) {
notifyError(err);
@@ -673,8 +993,6 @@ void PlaylistFetcher::onDownloadNext() {
++mSeqNumber;
postMonitorQueue();
-
- mStartup = false;
}
int32_t PlaylistFetcher::getSeqNumberForTime(int64_t timeUs) const {
@@ -709,95 +1027,163 @@ int32_t PlaylistFetcher::getSeqNumberForTime(int64_t timeUs) const {
return firstSeqNumberInPlaylist + index;
}
-status_t PlaylistFetcher::extractAndQueueAccessUnits(
- const sp<ABuffer> &buffer, const sp<AMessage> &itemMeta) {
- if (buffer->size() > 0 && buffer->data()[0] == 0x47) {
- // Let's assume this is an MPEG2 transport stream.
+status_t PlaylistFetcher::extractAndQueueAccessUnitsFromTs(const sp<ABuffer> &buffer) {
+ if (mTSParser == NULL) {
+ // Use TS_TIMESTAMPS_ARE_ABSOLUTE so pts carry over between fetchers.
+ mTSParser = new ATSParser(ATSParser::TS_TIMESTAMPS_ARE_ABSOLUTE);
+ }
- if ((buffer->size() % 188) != 0) {
- ALOGE("MPEG2 transport stream is not an even multiple of 188 "
- "bytes in length.");
- return ERROR_MALFORMED;
- }
+ if (mNextPTSTimeUs >= 0ll) {
+ sp<AMessage> extra = new AMessage;
+ // Since we are using absolute timestamps, signal an offset of 0 to prevent
+ // ATSParser from skewing the timestamps of access units.
+ extra->setInt64(IStreamListener::kKeyMediaTimeUs, 0);
- if (mTSParser == NULL) {
- mTSParser = new ATSParser;
- }
+ mTSParser->signalDiscontinuity(
+ ATSParser::DISCONTINUITY_SEEK, extra);
- if (mNextPTSTimeUs >= 0ll) {
- sp<AMessage> extra = new AMessage;
- extra->setInt64(IStreamListener::kKeyMediaTimeUs, mNextPTSTimeUs);
+ mNextPTSTimeUs = -1ll;
+ }
- mTSParser->signalDiscontinuity(
- ATSParser::DISCONTINUITY_SEEK, extra);
+ size_t offset = 0;
+ while (offset + 188 <= buffer->size()) {
+ status_t err = mTSParser->feedTSPacket(buffer->data() + offset, 188);
- mNextPTSTimeUs = -1ll;
+ if (err != OK) {
+ return err;
}
- size_t offset = 0;
- while (offset < buffer->size()) {
- status_t err = mTSParser->feedTSPacket(buffer->data() + offset, 188);
+ offset += 188;
+ }
+ // setRange to indicate consumed bytes.
+ buffer->setRange(buffer->offset() + offset, buffer->size() - offset);
+
+ status_t err = OK;
+ for (size_t i = mPacketSources.size(); i-- > 0;) {
+ sp<AnotherPacketSource> packetSource = mPacketSources.valueAt(i);
+
+ const char *key;
+ ATSParser::SourceType type;
+ const LiveSession::StreamType stream = mPacketSources.keyAt(i);
+ switch (stream) {
+ case LiveSession::STREAMTYPE_VIDEO:
+ type = ATSParser::VIDEO;
+ key = "timeUsVideo";
+ break;
+
+ case LiveSession::STREAMTYPE_AUDIO:
+ type = ATSParser::AUDIO;
+ key = "timeUsAudio";
+ break;
- if (err != OK) {
- return err;
+ case LiveSession::STREAMTYPE_SUBTITLES:
+ {
+ ALOGE("MPEG2 Transport streams do not contain subtitles.");
+ return ERROR_MALFORMED;
+ break;
}
- offset += 188;
+ default:
+ TRESPASS();
}
- for (size_t i = mPacketSources.size(); i-- > 0;) {
- sp<AnotherPacketSource> packetSource = mPacketSources.valueAt(i);
+ sp<AnotherPacketSource> source =
+ static_cast<AnotherPacketSource *>(
+ mTSParser->getSource(type).get());
- ATSParser::SourceType type;
- switch (mPacketSources.keyAt(i)) {
- case LiveSession::STREAMTYPE_VIDEO:
- type = ATSParser::VIDEO;
- break;
+ if (source == NULL) {
+ continue;
+ }
- case LiveSession::STREAMTYPE_AUDIO:
- type = ATSParser::AUDIO;
+ int64_t timeUs;
+ sp<ABuffer> accessUnit;
+ status_t finalResult;
+ while (source->hasBufferAvailable(&finalResult)
+ && source->dequeueAccessUnit(&accessUnit) == OK) {
+
+ CHECK(accessUnit->meta()->findInt64("timeUs", &timeUs));
+ if (mMinStartTimeUs > 0) {
+ if (timeUs < mMinStartTimeUs) {
+ // TODO untested path
+ // try a later ts
+ int32_t targetDuration;
+ mPlaylist->meta()->findInt32("target-duration", &targetDuration);
+ int32_t incr = (mMinStartTimeUs - timeUs) / 1000000 / targetDuration;
+ if (incr == 0) {
+ // increment mSeqNumber by at least one
+ incr = 1;
+ }
+ mSeqNumber += incr;
+ err = -EAGAIN;
break;
+ } else {
+ int64_t startTimeUs;
+ if (mStartTimeUsNotify != NULL
+ && !mStartTimeUsNotify->findInt64(key, &startTimeUs)) {
+ mStartTimeUsNotify->setInt64(key, timeUs);
+
+ uint32_t streamMask = 0;
+ mStartTimeUsNotify->findInt32("streamMask", (int32_t *) &streamMask);
+ streamMask |= mPacketSources.keyAt(i);
+ mStartTimeUsNotify->setInt32("streamMask", streamMask);
+
+ if (streamMask == mStreamTypeMask) {
+ mStartTimeUsNotify->post();
+ mStartTimeUsNotify.clear();
+ }
+ }
+ }
+ }
- case LiveSession::STREAMTYPE_SUBTITLES:
- {
- ALOGE("MPEG2 Transport streams do not contain subtitles.");
- return ERROR_MALFORMED;
+ if (mStopParams != NULL) {
+ // Queue discontinuity in original stream.
+ int64_t stopTimeUs;
+ if (!mStopParams->findInt64(key, &stopTimeUs) || timeUs >= stopTimeUs) {
+ packetSource->queueAccessUnit(mSession->createFormatChangeBuffer());
+ mStreamTypeMask &= ~stream;
+ mPacketSources.removeItemsAt(i);
break;
}
-
- default:
- TRESPASS();
}
- sp<AnotherPacketSource> source =
- static_cast<AnotherPacketSource *>(
- mTSParser->getSource(type).get());
-
- if (source == NULL) {
- ALOGW("MPEG2 Transport stream does not contain %s data.",
- type == ATSParser::VIDEO ? "video" : "audio");
+ // Note that we do NOT dequeue any discontinuities except for format change.
- mStreamTypeMask &= ~mPacketSources.keyAt(i);
- mPacketSources.removeItemsAt(i);
- continue;
+ // for simplicity, store a reference to the format in each unit
+ sp<MetaData> format = source->getFormat();
+ if (format != NULL) {
+ accessUnit->meta()->setObject("format", format);
}
- sp<ABuffer> accessUnit;
- status_t finalResult;
- while (source->hasBufferAvailable(&finalResult)
- && source->dequeueAccessUnit(&accessUnit) == OK) {
- // Note that we do NOT dequeue any discontinuities.
+ // Stash the sequence number so we can hint future playlist where to start at.
+ accessUnit->meta()->setInt32("seq", mSeqNumber);
+ packetSource->queueAccessUnit(accessUnit);
+ }
- packetSource->queueAccessUnit(accessUnit);
- }
+ if (err != OK) {
+ break;
+ }
+ }
- if (packetSource->getFormat() == NULL) {
- packetSource->setFormat(source->getFormat());
- }
+ if (err != OK) {
+ for (size_t i = mPacketSources.size(); i-- > 0;) {
+ sp<AnotherPacketSource> packetSource = mPacketSources.valueAt(i);
+ packetSource->clear();
}
+ return err;
+ }
- return OK;
- } else if (buffer->size() >= 7 && !memcmp("WEBVTT\n", buffer->data(), 7)) {
+ if (!mStreamTypeMask) {
+ // Signal gap is filled between original and new stream.
+ ALOGV("ERROR OUT OF RANGE");
+ return ERROR_OUT_OF_RANGE;
+ }
+
+ return OK;
+}
+
+status_t PlaylistFetcher::extractAndQueueAccessUnits(
+ const sp<ABuffer> &buffer, const sp<AMessage> &itemMeta) {
+ if (buffer->size() >= 7 && !memcmp("WEBVTT\n", buffer->data(), 7)) {
if (mStreamTypeMask != LiveSession::STREAMTYPE_SUBTITLES) {
ALOGE("This stream only contains subtitles.");
return ERROR_MALFORMED;
@@ -810,6 +1196,7 @@ status_t PlaylistFetcher::extractAndQueueAccessUnits(
CHECK(itemMeta->findInt64("durationUs", &durationUs));
buffer->meta()->setInt64("timeUs", getSegmentStartTimeUs(mSeqNumber));
buffer->meta()->setInt64("durationUs", durationUs);
+ buffer->meta()->setInt32("seq", mSeqNumber);
packetSource->queueAccessUnit(buffer);
return OK;
@@ -935,6 +1322,18 @@ status_t PlaylistFetcher::extractAndQueueAccessUnits(
| (adtsHeader[4] << 3)
| (adtsHeader[5] >> 5);
+ if (aac_frame_length == 0) {
+ const uint8_t *id3Header = adtsHeader;
+ if (!memcmp(id3Header, "ID3", 3)) {
+ ID3 id3(id3Header, buffer->size() - offset, true);
+ if (id3.isValid()) {
+ offset += id3.rawSize();
+ continue;
+ };
+ }
+ return ERROR_MALFORMED;
+ }
+
CHECK_LE(offset + aac_frame_length, buffer->size());
sp<ABuffer> unit = new ABuffer(aac_frame_length);
@@ -946,6 +1345,7 @@ status_t PlaylistFetcher::extractAndQueueAccessUnits(
// Each AAC frame encodes 1024 samples.
numSamples += 1024;
+ unit->meta()->setInt32("seq", mSeqNumber);
packetSource->queueAccessUnit(unit);
offset += aac_frame_length;
@@ -973,4 +1373,33 @@ void PlaylistFetcher::updateDuration() {
msg->post();
}
+int64_t PlaylistFetcher::resumeThreshold(const sp<AMessage> &msg) {
+ int64_t durationUs, threshold;
+ if (msg->findInt64("durationUs", &durationUs)) {
+ return kNumSkipFrames * durationUs;
+ }
+
+ sp<RefBase> obj;
+ msg->findObject("format", &obj);
+ MetaData *format = static_cast<MetaData *>(obj.get());
+
+ const char *mime;
+ CHECK(format->findCString(kKeyMIMEType, &mime));
+ bool audio = !strncasecmp(mime, "audio/", 6);
+ if (audio) {
+ // Assumes 1000 samples per frame.
+ int32_t sampleRate;
+ CHECK(format->findInt32(kKeySampleRate, &sampleRate));
+ return kNumSkipFrames /* frames */ * 1000 /* samples */
+ * (1000000 / sampleRate) /* sample duration (us) */;
+ } else {
+ int32_t frameRate;
+ if (format->findInt32(kKeyFrameRate, &frameRate) && frameRate > 0) {
+ return kNumSkipFrames * (1000000 / frameRate);
+ }
+ }
+
+ return 500000ll;
+}
+
} // namespace android
diff --git a/media/libstagefright/httplive/PlaylistFetcher.h b/media/libstagefright/httplive/PlaylistFetcher.h
index 1648e02..7e21523 100644
--- a/media/libstagefright/httplive/PlaylistFetcher.h
+++ b/media/libstagefright/httplive/PlaylistFetcher.h
@@ -43,6 +43,7 @@ struct PlaylistFetcher : public AHandler {
kWhatTemporarilyDoneFetching,
kWhatPrepared,
kWhatPreparationFailed,
+ kWhatStartedAt,
};
PlaylistFetcher(
@@ -56,11 +57,15 @@ struct PlaylistFetcher : public AHandler {
const sp<AnotherPacketSource> &audioSource,
const sp<AnotherPacketSource> &videoSource,
const sp<AnotherPacketSource> &subtitleSource,
- int64_t startTimeUs = -1ll);
+ int64_t startTimeUs = -1ll,
+ int64_t minStartTimeUs = 0ll /* start after this timestamp */,
+ int32_t startSeqNumberHint = -1 /* try starting at this sequence number */);
void pauseAsync();
- void stopAsync();
+ void stopAsync(bool selfTriggered = false);
+
+ void resumeUntilAsync(const sp<AMessage> &params);
protected:
virtual ~PlaylistFetcher();
@@ -76,16 +81,28 @@ private:
kWhatPause = 'paus',
kWhatStop = 'stop',
kWhatMonitorQueue = 'moni',
+ kWhatResumeUntil = 'rsme',
+ kWhatDownloadNext = 'dlnx',
};
static const int64_t kMinBufferedDurationUs;
+ static const int64_t kMaxMonitorDelayUs;
+ static const int32_t kDownloadBlockSize;
+ static const int32_t kNumSkipFrames;
+
+ static bool bufferStartsWithTsSyncByte(const sp<ABuffer>& buffer);
+ // notifications to mSession
sp<AMessage> mNotify;
+ sp<AMessage> mStartTimeUsNotify;
+
sp<LiveSession> mSession;
AString mURI;
uint32_t mStreamTypeMask;
int64_t mStartTimeUs;
+ int64_t mMinStartTimeUs; // start fetching no earlier than this value
+ sp<AMessage> mStopParams; // message containing the latest timestamps we should fetch.
KeyedVector<LiveSession::StreamType, sp<AnotherPacketSource> >
mPacketSources;
@@ -97,6 +114,7 @@ private:
int32_t mSeqNumber;
int32_t mNumRetries;
bool mStartup;
+ bool mPrepared;
int64_t mNextPTSTimeUs;
int32_t mMonitorQueueGeneration;
@@ -117,13 +135,29 @@ private:
uint64_t mFirstPTS;
int64_t mAbsoluteTimeAnchorUs;
+ // Stores the initialization vector to decrypt the next block of cipher text, which can
+ // either be derived from the sequence number, read from the manifest, or copied from
+ // the last block of cipher text (cipher-block chaining).
+ unsigned char mAESInitVec[16];
+
+ // Set first to true if decrypting the first segment of a playlist segment. When
+ // first is true, reset the initialization vector based on the available
+ // information in the manifest; otherwise, use the initialization vector as
+ // updated by the last call to AES_cbc_encrypt.
+ //
+ // For the input to decrypt correctly, decryptBuffer must be called on
+ // consecutive byte ranges on block boundaries, e.g. 0..15, 16..47, 48..63,
+ // and so on.
status_t decryptBuffer(
- size_t playlistIndex, const sp<ABuffer> &buffer);
+ size_t playlistIndex, const sp<ABuffer> &buffer,
+ bool first = true);
+ status_t checkDecryptPadding(const sp<ABuffer> &buffer);
- void postMonitorQueue(int64_t delayUs = 0);
+ void postMonitorQueue(int64_t delayUs = 0, int64_t minDelayUs = 0);
void cancelMonitorQueue();
- bool timeToRefreshPlaylist(int64_t nowUs) const;
+ int64_t delayUsToRefreshPlaylist() const;
+ status_t refreshPlaylist();
// Returns the media time in us of the segment specified by seqNumber.
// This is computed by summing the durations of all segments before it.
@@ -131,10 +165,15 @@ private:
status_t onStart(const sp<AMessage> &msg);
void onPause();
- void onStop();
+ void onStop(const sp<AMessage> &msg);
void onMonitorQueue();
void onDownloadNext();
+ // Resume a fetcher to continue until the stopping point stored in msg.
+ status_t onResumeUntil(const sp<AMessage> &msg);
+
+ status_t extractAndQueueAccessUnitsFromTs(const sp<ABuffer> &buffer);
+
status_t extractAndQueueAccessUnits(
const sp<ABuffer> &buffer, const sp<AMessage> &itemMeta);
@@ -147,6 +186,10 @@ private:
void updateDuration();
+ // Before resuming a fetcher in onResume, check the remaining duration is longer than that
+ // returned by resumeThreshold.
+ int64_t resumeThreshold(const sp<AMessage> &msg);
+
DISALLOW_EVIL_CONSTRUCTORS(PlaylistFetcher);
};
diff --git a/media/libstagefright/id3/ID3.cpp b/media/libstagefright/id3/ID3.cpp
index 34d671a..1199c22 100644
--- a/media/libstagefright/id3/ID3.cpp
+++ b/media/libstagefright/id3/ID3.cpp
@@ -41,9 +41,9 @@ struct MemorySource : public DataSource {
}
virtual ssize_t readAt(off64_t offset, void *data, size_t size) {
- off64_t available = (offset >= mSize) ? 0ll : mSize - offset;
+ off64_t available = (offset >= (off64_t)mSize) ? 0ll : mSize - offset;
- size_t copy = (available > size) ? size : available;
+ size_t copy = (available > (off64_t)size) ? size : available;
memcpy(data, mData + offset, copy);
return copy;
@@ -56,14 +56,14 @@ private:
DISALLOW_EVIL_CONSTRUCTORS(MemorySource);
};
-ID3::ID3(const sp<DataSource> &source, bool ignoreV1)
+ID3::ID3(const sp<DataSource> &source, bool ignoreV1, off64_t offset)
: mIsValid(false),
mData(NULL),
mSize(0),
mFirstFrameOffset(0),
mVersion(ID3_UNKNOWN),
mRawSize(0) {
- mIsValid = parseV2(source);
+ mIsValid = parseV2(source, offset);
if (!mIsValid && !ignoreV1) {
mIsValid = parseV1(source);
@@ -79,7 +79,7 @@ ID3::ID3(const uint8_t *data, size_t size, bool ignoreV1)
mRawSize(0) {
sp<MemorySource> source = new MemorySource(data, size);
- mIsValid = parseV2(source);
+ mIsValid = parseV2(source, 0);
if (!mIsValid && !ignoreV1) {
mIsValid = parseV1(source);
@@ -115,7 +115,7 @@ bool ID3::ParseSyncsafeInteger(const uint8_t encoded[4], size_t *x) {
return true;
}
-bool ID3::parseV2(const sp<DataSource> &source) {
+bool ID3::parseV2(const sp<DataSource> &source, off64_t offset) {
struct id3_header {
char id[3];
uint8_t version_major;
@@ -126,7 +126,7 @@ struct id3_header {
id3_header header;
if (source->readAt(
- 0, &header, sizeof(header)) != (ssize_t)sizeof(header)) {
+ offset, &header, sizeof(header)) != (ssize_t)sizeof(header)) {
return false;
}
@@ -172,7 +172,7 @@ struct id3_header {
}
if (size > kMaxMetadataSize) {
- ALOGE("skipping huge ID3 metadata of size %d", size);
+ ALOGE("skipping huge ID3 metadata of size %zu", size);
return false;
}
@@ -185,7 +185,7 @@ struct id3_header {
mSize = size;
mRawSize = mSize + sizeof(header);
- if (source->readAt(sizeof(header), mData, mSize) != (ssize_t)mSize) {
+ if (source->readAt(offset + sizeof(header), mData, mSize) != (ssize_t)mSize) {
free(mData);
mData = NULL;
@@ -654,8 +654,8 @@ void ID3::Iterator::findFrame() {
mFrameSize += 6;
if (mOffset + mFrameSize > mParent.mSize) {
- ALOGV("partial frame at offset %d (size = %d, bytes-remaining = %d)",
- mOffset, mFrameSize, mParent.mSize - mOffset - 6);
+ ALOGV("partial frame at offset %zu (size = %zu, bytes-remaining = %zu)",
+ mOffset, mFrameSize, mParent.mSize - mOffset - (size_t)6);
return;
}
@@ -695,8 +695,8 @@ void ID3::Iterator::findFrame() {
mFrameSize = 10 + baseSize;
if (mOffset + mFrameSize > mParent.mSize) {
- ALOGV("partial frame at offset %d (size = %d, bytes-remaining = %d)",
- mOffset, mFrameSize, mParent.mSize - mOffset - 10);
+ ALOGV("partial frame at offset %zu (size = %zu, bytes-remaining = %zu)",
+ mOffset, mFrameSize, mParent.mSize - mOffset - (size_t)10);
return;
}
diff --git a/media/libstagefright/id3/testid3.cpp b/media/libstagefright/id3/testid3.cpp
index bc4572c..b2f4188 100644
--- a/media/libstagefright/id3/testid3.cpp
+++ b/media/libstagefright/id3/testid3.cpp
@@ -33,7 +33,7 @@ static void hexdump(const void *_data, size_t size) {
const uint8_t *data = (const uint8_t *)_data;
size_t offset = 0;
while (offset < size) {
- printf("0x%04x ", offset);
+ printf("0x%04zx ", offset);
size_t n = size - offset;
if (n > 16) {
@@ -101,7 +101,7 @@ void scanFile(const char *path) {
const void *data = tag.getAlbumArt(&dataSize, &mime);
if (data) {
- printf("found album art: size=%d mime='%s'\n", dataSize,
+ printf("found album art: size=%zu mime='%s'\n", dataSize,
mime.string());
hexdump(data, dataSize > 128 ? 128 : dataSize);
diff --git a/media/libstagefright/include/AwesomePlayer.h b/media/libstagefright/include/AwesomePlayer.h
index 271df8e..6ee95a9 100644
--- a/media/libstagefright/include/AwesomePlayer.h
+++ b/media/libstagefright/include/AwesomePlayer.h
@@ -32,6 +32,7 @@
namespace android {
struct AudioPlayer;
+struct ClockEstimator;
struct DataSource;
struct MediaBuffer;
struct MediaExtractor;
@@ -234,6 +235,7 @@ private:
MediaBuffer *mVideoBuffer;
+ sp<ClockEstimator> mClockEstimator;
sp<HTTPBase> mConnectingDataSource;
sp<NuCachedSource2> mCachedSource;
@@ -293,6 +295,7 @@ private:
bool getBitrate(int64_t *bitrate);
+ int64_t estimateRealTimeUs(TimeSource *ts, int64_t systemTimeUs);
void finishSeekIfNecessary(int64_t videoTimeUs);
void ensureCacheIsFetching_l();
diff --git a/media/libstagefright/include/ChromiumHTTPDataSource.h b/media/libstagefright/include/ChromiumHTTPDataSource.h
index 785f939..da188dd 100644
--- a/media/libstagefright/include/ChromiumHTTPDataSource.h
+++ b/media/libstagefright/include/ChromiumHTTPDataSource.h
@@ -113,6 +113,7 @@ private:
void onConnectionFailed(status_t err);
void onReadCompleted(ssize_t size);
void onDisconnectComplete();
+ void onRedirect(const char *url);
void clearDRMState_l();
diff --git a/media/libstagefright/include/ID3.h b/media/libstagefright/include/ID3.h
index cca83ab..e83f3ef 100644
--- a/media/libstagefright/include/ID3.h
+++ b/media/libstagefright/include/ID3.h
@@ -35,7 +35,7 @@ struct ID3 {
ID3_V2_4,
};
- ID3(const sp<DataSource> &source, bool ignoreV1 = false);
+ ID3(const sp<DataSource> &source, bool ignoreV1 = false, off64_t offset = 0);
ID3(const uint8_t *data, size_t size, bool ignoreV1 = false);
~ID3();
@@ -86,7 +86,7 @@ private:
size_t mRawSize;
bool parseV1(const sp<DataSource> &source);
- bool parseV2(const sp<DataSource> &source);
+ bool parseV2(const sp<DataSource> &source, off64_t offset);
void removeUnsynchronization();
bool removeUnsynchronizationV2_4(bool iTunesHack);
diff --git a/media/libstagefright/include/MPEG4Extractor.h b/media/libstagefright/include/MPEG4Extractor.h
index bd5e4b9..7b4bc6d 100644
--- a/media/libstagefright/include/MPEG4Extractor.h
+++ b/media/libstagefright/include/MPEG4Extractor.h
@@ -97,6 +97,7 @@ private:
status_t parseChunk(off64_t *offset, int depth);
status_t parseITunesMetaData(off64_t offset, size_t size);
status_t parse3GPPMetaData(off64_t offset, size_t size, int depth);
+ void parseID3v2MetaData(off64_t offset);
status_t updateAudioTrackInfoFromESDS_MPEG4Audio(
const void *esds_data, size_t esds_size);
diff --git a/media/libstagefright/include/OMX.h b/media/libstagefright/include/OMX.h
index 31a5077..cd51bbf 100644
--- a/media/libstagefright/include/OMX.h
+++ b/media/libstagefright/include/OMX.h
@@ -134,10 +134,10 @@ public:
OMX_IN OMX_PTR pEventData);
OMX_ERRORTYPE OnEmptyBufferDone(
- node_id node, OMX_IN OMX_BUFFERHEADERTYPE *pBuffer);
+ node_id node, buffer_id buffer, OMX_IN OMX_BUFFERHEADERTYPE *pBuffer);
OMX_ERRORTYPE OnFillBufferDone(
- node_id node, OMX_IN OMX_BUFFERHEADERTYPE *pBuffer);
+ node_id node, buffer_id buffer, OMX_IN OMX_BUFFERHEADERTYPE *pBuffer);
void invalidateNodeID(node_id node);
diff --git a/media/libstagefright/include/OMXNodeInstance.h b/media/libstagefright/include/OMXNodeInstance.h
index 339179e..3967dc6 100644
--- a/media/libstagefright/include/OMXNodeInstance.h
+++ b/media/libstagefright/include/OMXNodeInstance.h
@@ -138,12 +138,25 @@ private:
OMX::buffer_id mID;
};
Vector<ActiveBuffer> mActiveBuffers;
+#ifdef __LP64__
+ Mutex mBufferIDLock;
+ uint32_t mBufferIDCount;
+ KeyedVector<OMX::buffer_id, OMX_BUFFERHEADERTYPE *> mBufferIDToBufferHeader;
+ KeyedVector<OMX_BUFFERHEADERTYPE *, OMX::buffer_id> mBufferHeaderToBufferID;
+#endif
~OMXNodeInstance();
void addActiveBuffer(OMX_U32 portIndex, OMX::buffer_id id);
void removeActiveBuffer(OMX_U32 portIndex, OMX::buffer_id id);
void freeActiveBuffers();
+
+ // For buffer id management
+ OMX::buffer_id makeBufferID(OMX_BUFFERHEADERTYPE *bufferHeader);
+ OMX_BUFFERHEADERTYPE *findBufferHeader(OMX::buffer_id buffer);
+ OMX::buffer_id findBufferID(OMX_BUFFERHEADERTYPE *bufferHeader);
+ void invalidateBufferID(OMX::buffer_id buffer);
+
status_t useGraphicBuffer2_l(
OMX_U32 portIndex, const sp<GraphicBuffer> &graphicBuffer,
OMX::buffer_id *buffer);
diff --git a/media/libstagefright/include/SampleTable.h b/media/libstagefright/include/SampleTable.h
index 847dff7..ed91adc 100644
--- a/media/libstagefright/include/SampleTable.h
+++ b/media/libstagefright/include/SampleTable.h
@@ -74,7 +74,8 @@ public:
kFlagClosest
};
status_t findSampleAtTime(
- uint32_t req_time, uint32_t *sample_index, uint32_t flags);
+ uint64_t req_time, uint64_t scale_num, uint64_t scale_den,
+ uint32_t *sample_index, uint32_t flags);
status_t findSyncSampleNear(
uint32_t start_sample_index, uint32_t *sample_index,
@@ -137,6 +138,13 @@ private:
friend struct SampleIterator;
+ // normally we don't round
+ inline uint64_t getSampleTime(
+ size_t sample_index, uint64_t scale_num, uint64_t scale_den) const {
+ return (mSampleTimeEntries[sample_index].mCompositionTime
+ * scale_num) / scale_den;
+ }
+
status_t getSampleSize_l(uint32_t sample_index, size_t *sample_size);
uint32_t getCompositionTimeOffset(uint32_t sampleIndex);
diff --git a/media/libstagefright/include/TimedEventQueue.h b/media/libstagefright/include/TimedEventQueue.h
index 38a08b1..2963150 100644
--- a/media/libstagefright/include/TimedEventQueue.h
+++ b/media/libstagefright/include/TimedEventQueue.h
@@ -122,7 +122,7 @@ private:
};
struct StopEvent : public TimedEventQueue::Event {
- virtual void fire(TimedEventQueue *queue, int64_t now_us) {
+ virtual void fire(TimedEventQueue *queue, int64_t /* now_us */) {
queue->mStopped = true;
}
};
@@ -145,7 +145,7 @@ private:
static void *ThreadWrapper(void *me);
void threadEntry();
- sp<Event> removeEventFromQueue_l(event_id id);
+ sp<Event> removeEventFromQueue_l(event_id id, bool *wakeLocked);
void acquireWakeLock_l();
void releaseWakeLock_l(bool force = false);
diff --git a/media/libstagefright/matroska/Android.mk b/media/libstagefright/matroska/Android.mk
index 2d8c1e1..446ff8c 100644
--- a/media/libstagefright/matroska/Android.mk
+++ b/media/libstagefright/matroska/Android.mk
@@ -8,7 +8,7 @@ LOCAL_C_INCLUDES:= \
$(TOP)/external/libvpx/libwebm \
$(TOP)/frameworks/native/include/media/openmax \
-LOCAL_CFLAGS += -Wno-multichar
+LOCAL_CFLAGS += -Wno-multichar -Werror
LOCAL_MODULE:= libstagefright_matroska
diff --git a/media/libstagefright/matroska/MatroskaExtractor.cpp b/media/libstagefright/matroska/MatroskaExtractor.cpp
index d260d0f..0e4dd2b 100644
--- a/media/libstagefright/matroska/MatroskaExtractor.cpp
+++ b/media/libstagefright/matroska/MatroskaExtractor.cpp
@@ -33,6 +33,8 @@
#include <media/stagefright/Utils.h>
#include <utils/String8.h>
+#include <inttypes.h>
+
namespace android {
struct DataSourceReader : public mkvparser::IMkvReader {
@@ -103,7 +105,7 @@ struct BlockIterator {
private:
MatroskaExtractor *mExtractor;
- unsigned long mTrackNum;
+ long long mTrackNum;
const mkvparser::Cluster *mCluster;
const mkvparser::BlockEntry *mBlockEntry;
@@ -183,7 +185,7 @@ MatroskaSource::MatroskaSource(
CHECK_GE(avccSize, 5u);
mNALSizeLen = 1 + (avcc[4] & 3);
- ALOGV("mNALSizeLen = %d", mNALSizeLen);
+ ALOGV("mNALSizeLen = %zu", mNALSizeLen);
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
mType = AAC;
}
@@ -193,7 +195,7 @@ MatroskaSource::~MatroskaSource() {
clearPendingFrames();
}
-status_t MatroskaSource::start(MetaData *params) {
+status_t MatroskaSource::start(MetaData * /* params */) {
mBlockIter.reset();
return OK;
@@ -320,7 +322,7 @@ void BlockIterator::seek(
// Special case the 0 seek to avoid loading Cues when the application
// extraneously seeks to 0 before playing.
if (seekTimeNs <= 0) {
- ALOGV("Seek to beginning: %lld", seekTimeUs);
+ ALOGV("Seek to beginning: %" PRId64, seekTimeUs);
mCluster = pSegment->GetFirst();
mBlockEntryIndex = 0;
do {
@@ -329,7 +331,7 @@ void BlockIterator::seek(
return;
}
- ALOGV("Seeking to: %lld", seekTimeUs);
+ ALOGV("Seeking to: %" PRId64, seekTimeUs);
// If the Cues have not been located then find them.
const mkvparser::Cues* pCues = pSegment->GetCues();
@@ -378,7 +380,7 @@ void BlockIterator::seek(
for (size_t index = 0; index < pTracks->GetTracksCount(); ++index) {
pTrack = pTracks->GetTrackByIndex(index);
if (pTrack && pTrack->GetType() == 1) { // VIDEO_TRACK
- ALOGV("Video track located at %d", index);
+ ALOGV("Video track located at %zu", index);
break;
}
}
@@ -409,8 +411,8 @@ void BlockIterator::seek(
if (isAudio || block()->IsKey()) {
// Accept the first key frame
*actualFrameTimeUs = (block()->GetTime(mCluster) + 500LL) / 1000LL;
- ALOGV("Requested seek point: %lld actual: %lld",
- seekTimeUs, actualFrameTimeUs);
+ ALOGV("Requested seek point: %" PRId64 " actual: %" PRId64,
+ seekTimeUs, *actualFrameTimeUs);
break;
}
}
@@ -716,41 +718,61 @@ bool MatroskaExtractor::isLiveStreaming() const {
return mIsLiveStreaming;
}
+static int bytesForSize(size_t size) {
+ // use at most 28 bits (4 times 7)
+ CHECK(size <= 0xfffffff);
+
+ if (size > 0x1fffff) {
+ return 4;
+ } else if (size > 0x3fff) {
+ return 3;
+ } else if (size > 0x7f) {
+ return 2;
+ }
+ return 1;
+}
+
+static void storeSize(uint8_t *data, size_t &idx, size_t size) {
+ int numBytes = bytesForSize(size);
+ idx += numBytes;
+
+ data += idx;
+ size_t next = 0;
+ while (numBytes--) {
+ *--data = (size & 0x7f) | next;
+ size >>= 7;
+ next = 0x80;
+ }
+}
+
static void addESDSFromCodecPrivate(
const sp<MetaData> &meta,
bool isAudio, const void *priv, size_t privSize) {
- static const uint8_t kStaticESDS[] = {
- 0x03, 22,
- 0x00, 0x00, // ES_ID
- 0x00, // streamDependenceFlag, URL_Flag, OCRstreamFlag
-
- 0x04, 17,
- 0x40, // ObjectTypeIndication
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00,
-
- 0x05,
- // CodecSpecificInfo (with size prefix) follows
- };
- // Make sure all sizes can be coded in a single byte.
- CHECK(privSize + 22 - 2 < 128);
- size_t esdsSize = sizeof(kStaticESDS) + privSize + 1;
+ int privSizeBytesRequired = bytesForSize(privSize);
+ int esdsSize2 = 14 + privSizeBytesRequired + privSize;
+ int esdsSize2BytesRequired = bytesForSize(esdsSize2);
+ int esdsSize1 = 4 + esdsSize2BytesRequired + esdsSize2;
+ int esdsSize1BytesRequired = bytesForSize(esdsSize1);
+ size_t esdsSize = 1 + esdsSize1BytesRequired + esdsSize1;
uint8_t *esds = new uint8_t[esdsSize];
- memcpy(esds, kStaticESDS, sizeof(kStaticESDS));
- uint8_t *ptr = esds + sizeof(kStaticESDS);
- *ptr++ = privSize;
- memcpy(ptr, priv, privSize);
-
- // Increment by codecPrivateSize less 2 bytes that are accounted for
- // already in lengths of 22/17
- esds[1] += privSize - 2;
- esds[6] += privSize - 2;
-
- // Set ObjectTypeIndication.
- esds[7] = isAudio ? 0x40 // Audio ISO/IEC 14496-3
- : 0x20; // Visual ISO/IEC 14496-2
+
+ size_t idx = 0;
+ esds[idx++] = 0x03;
+ storeSize(esds, idx, esdsSize1);
+ esds[idx++] = 0x00; // ES_ID
+ esds[idx++] = 0x00; // ES_ID
+ esds[idx++] = 0x00; // streamDependenceFlag, URL_Flag, OCRstreamFlag
+ esds[idx++] = 0x04;
+ storeSize(esds, idx, esdsSize2);
+ esds[idx++] = isAudio ? 0x40 // Audio ISO/IEC 14496-3
+ : 0x20; // Visual ISO/IEC 14496-2
+ for (int i = 0; i < 12; i++) {
+ esds[idx++] = 0x00;
+ }
+ esds[idx++] = 0x05;
+ storeSize(esds, idx, privSize);
+ memcpy(esds + idx, priv, privSize);
meta->setData(kKeyESDS, 0, esds, esdsSize);
diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp
index 175a263..2c8cf8d 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.cpp
+++ b/media/libstagefright/mpeg2ts/ATSParser.cpp
@@ -36,6 +36,8 @@
#include <media/IStreamSource.h>
#include <utils/KeyedVector.h>
+#include <inttypes.h>
+
namespace android {
// I want the expression "y" evaluated even if verbose logging is off.
@@ -581,7 +583,7 @@ status_t ATSParser::Stream::parse(
// Increment in multiples of 64K.
neededSize = (neededSize + 65535) & ~65535;
- ALOGI("resizing buffer to %d bytes", neededSize);
+ ALOGI("resizing buffer to %zu bytes", neededSize);
sp<ABuffer> newBuffer = new ABuffer(neededSize);
memcpy(newBuffer->data(), mBuffer->data(), mBuffer->size());
@@ -742,7 +744,7 @@ status_t ATSParser::Stream::parsePES(ABitReader *br) {
PTS |= br->getBits(15);
CHECK_EQ(br->getBits(1), 1u);
- ALOGV("PTS = 0x%016llx (%.2f)", PTS, PTS / 90000.0);
+ ALOGV("PTS = 0x%016" PRIx64 " (%.2f)", PTS, PTS / 90000.0);
optional_bytes_remaining -= 5;
@@ -758,7 +760,7 @@ status_t ATSParser::Stream::parsePES(ABitReader *br) {
DTS |= br->getBits(15);
CHECK_EQ(br->getBits(1), 1u);
- ALOGV("DTS = %llu", DTS);
+ ALOGV("DTS = %" PRIu64, DTS);
optional_bytes_remaining -= 5;
}
@@ -776,7 +778,7 @@ status_t ATSParser::Stream::parsePES(ABitReader *br) {
ESCR |= br->getBits(15);
CHECK_EQ(br->getBits(1), 1u);
- ALOGV("ESCR = %llu", ESCR);
+ ALOGV("ESCR = %" PRIu64, ESCR);
MY_LOGV("ESCR_extension = %u", br->getBits(9));
CHECK_EQ(br->getBits(1), 1u);
@@ -806,7 +808,7 @@ status_t ATSParser::Stream::parsePES(ABitReader *br) {
if (br->numBitsLeft() < dataLength * 8) {
ALOGE("PES packet does not carry enough data to contain "
- "payload. (numBitsLeft = %d, required = %d)",
+ "payload. (numBitsLeft = %zu, required = %u)",
br->numBitsLeft(), dataLength * 8);
return ERROR_MALFORMED;
@@ -826,7 +828,7 @@ status_t ATSParser::Stream::parsePES(ABitReader *br) {
size_t payloadSizeBits = br->numBitsLeft();
CHECK_EQ(payloadSizeBits % 8, 0u);
- ALOGV("There's %d bytes of payload.", payloadSizeBits / 8);
+ ALOGV("There's %zu bytes of payload.", payloadSizeBits / 8);
}
} else if (stream_id == 0xbe) { // padding_stream
CHECK_NE(PES_packet_length, 0u);
@@ -844,7 +846,7 @@ status_t ATSParser::Stream::flush() {
return OK;
}
- ALOGV("flushing stream 0x%04x size = %d", mElementaryPID, mBuffer->size());
+ ALOGV("flushing stream 0x%04x size = %zu", mElementaryPID, mBuffer->size());
ABitReader br(mBuffer->data(), mBuffer->size());
@@ -856,7 +858,7 @@ status_t ATSParser::Stream::flush() {
}
void ATSParser::Stream::onPayloadData(
- unsigned PTS_DTS_flags, uint64_t PTS, uint64_t DTS,
+ unsigned PTS_DTS_flags, uint64_t PTS, uint64_t /* DTS */,
const uint8_t *data, size_t size) {
#if 0
ALOGI("payload streamType 0x%02x, PTS = 0x%016llx, dPTS = %lld",
@@ -1166,7 +1168,7 @@ void ATSParser::parseAdaptationField(ABitReader *br, unsigned PID) {
uint64_t PCR = PCR_base * 300 + PCR_ext;
- ALOGV("PID 0x%04x: PCR = 0x%016llx (%.2f)",
+ ALOGV("PID 0x%04x: PCR = 0x%016" PRIx64 " (%.2f)",
PID, PCR, PCR / 27E6);
// The number of bytes received by this parser up to and
@@ -1261,8 +1263,8 @@ bool ATSParser::PTSTimeDeltaEstablished() {
}
void ATSParser::updatePCR(
- unsigned PID, uint64_t PCR, size_t byteOffsetFromStart) {
- ALOGV("PCR 0x%016llx @ %d", PCR, byteOffsetFromStart);
+ unsigned /* PID */, uint64_t PCR, size_t byteOffsetFromStart) {
+ ALOGV("PCR 0x%016" PRIx64 " @ %zu", PCR, byteOffsetFromStart);
if (mNumPCRs == 2) {
mPCR[0] = mPCR[1];
diff --git a/media/libstagefright/mpeg2ts/ATSParser.h b/media/libstagefright/mpeg2ts/ATSParser.h
index a10edc9..8a80069 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.h
+++ b/media/libstagefright/mpeg2ts/ATSParser.h
@@ -71,8 +71,9 @@ struct ATSParser : public RefBase {
void signalEOS(status_t finalResult);
enum SourceType {
- VIDEO,
- AUDIO
+ VIDEO = 0,
+ AUDIO = 1,
+ NUM_SOURCE_TYPES = 2
};
sp<MediaSource> getSource(SourceType type);
diff --git a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
index 3153c8b..6dfaa94 100644
--- a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
+++ b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
@@ -34,7 +34,8 @@ AnotherPacketSource::AnotherPacketSource(const sp<MetaData> &meta)
: mIsAudio(false),
mFormat(NULL),
mLastQueuedTimeUs(0),
- mEOSResult(OK) {
+ mEOSResult(OK),
+ mLatestEnqueuedMeta(NULL) {
setFormat(meta);
}
@@ -61,7 +62,7 @@ void AnotherPacketSource::setFormat(const sp<MetaData> &meta) {
AnotherPacketSource::~AnotherPacketSource() {
}
-status_t AnotherPacketSource::start(MetaData *params) {
+status_t AnotherPacketSource::start(MetaData * /* params */) {
return OK;
}
@@ -70,7 +71,27 @@ status_t AnotherPacketSource::stop() {
}
sp<MetaData> AnotherPacketSource::getFormat() {
- return mFormat;
+ Mutex::Autolock autoLock(mLock);
+ if (mFormat != NULL) {
+ return mFormat;
+ }
+
+ List<sp<ABuffer> >::iterator it = mBuffers.begin();
+ while (it != mBuffers.end()) {
+ sp<ABuffer> buffer = *it;
+ int32_t discontinuity;
+ if (buffer->meta()->findInt32("discontinuity", &discontinuity)) {
+ break;
+ }
+
+ sp<RefBase> object;
+ if (buffer->meta()->findObject("format", &object)) {
+ return static_cast<MetaData*>(object.get());
+ }
+
+ ++it;
+ }
+ return NULL;
}
status_t AnotherPacketSource::dequeueAccessUnit(sp<ABuffer> *buffer) {
@@ -94,6 +115,11 @@ status_t AnotherPacketSource::dequeueAccessUnit(sp<ABuffer> *buffer) {
return INFO_DISCONTINUITY;
}
+ sp<RefBase> object;
+ if ((*buffer)->meta()->findObject("format", &object)) {
+ mFormat = static_cast<MetaData*>(object.get());
+ }
+
return OK;
}
@@ -120,17 +146,22 @@ status_t AnotherPacketSource::read(
}
return INFO_DISCONTINUITY;
- } else {
- int64_t timeUs;
- CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
+ }
+
+ sp<RefBase> object;
+ if (buffer->meta()->findObject("format", &object)) {
+ mFormat = static_cast<MetaData*>(object.get());
+ }
- MediaBuffer *mediaBuffer = new MediaBuffer(buffer);
+ int64_t timeUs;
+ CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
- mediaBuffer->meta_data()->setInt64(kKeyTime, timeUs);
+ MediaBuffer *mediaBuffer = new MediaBuffer(buffer);
- *out = mediaBuffer;
- return OK;
- }
+ mediaBuffer->meta_data()->setInt64(kKeyTime, timeUs);
+
+ *out = mediaBuffer;
+ return OK;
}
return mEOSResult;
@@ -152,12 +183,24 @@ void AnotherPacketSource::queueAccessUnit(const sp<ABuffer> &buffer) {
return;
}
- CHECK(buffer->meta()->findInt64("timeUs", &mLastQueuedTimeUs));
+ int64_t lastQueuedTimeUs;
+ CHECK(buffer->meta()->findInt64("timeUs", &lastQueuedTimeUs));
+ mLastQueuedTimeUs = lastQueuedTimeUs;
ALOGV("queueAccessUnit timeUs=%lld us (%.2f secs)", mLastQueuedTimeUs, mLastQueuedTimeUs / 1E6);
Mutex::Autolock autoLock(mLock);
mBuffers.push_back(buffer);
mCondition.signal();
+
+ if (!mLatestEnqueuedMeta.get()) {
+ mLatestEnqueuedMeta = buffer->meta();
+ } else {
+ int64_t latestTimeUs = 0;
+ CHECK(mLatestEnqueuedMeta->findInt64("timeUs", &latestTimeUs));
+ if (lastQueuedTimeUs > latestTimeUs) {
+ mLatestEnqueuedMeta = buffer->meta();
+ }
+ }
}
void AnotherPacketSource::clear() {
@@ -167,6 +210,7 @@ void AnotherPacketSource::clear() {
mEOSResult = OK;
mFormat = NULL;
+ mLatestEnqueuedMeta = NULL;
}
void AnotherPacketSource::queueDiscontinuity(
@@ -191,6 +235,7 @@ void AnotherPacketSource::queueDiscontinuity(
mEOSResult = OK;
mLastQueuedTimeUs = 0;
+ mLatestEnqueuedMeta = NULL;
sp<ABuffer> buffer = new ABuffer(0);
buffer->meta()->setInt32("discontinuity", static_cast<int32_t>(type));
@@ -278,4 +323,9 @@ bool AnotherPacketSource::isFinished(int64_t duration) const {
return (mEOSResult != OK);
}
+sp<AMessage> AnotherPacketSource::getLatestMeta() {
+ Mutex::Autolock autoLock(mLock);
+ return mLatestEnqueuedMeta;
+}
+
} // namespace android
diff --git a/media/libstagefright/mpeg2ts/AnotherPacketSource.h b/media/libstagefright/mpeg2ts/AnotherPacketSource.h
index e16cf78..9b193a2 100644
--- a/media/libstagefright/mpeg2ts/AnotherPacketSource.h
+++ b/media/libstagefright/mpeg2ts/AnotherPacketSource.h
@@ -62,6 +62,8 @@ struct AnotherPacketSource : public MediaSource {
bool isFinished(int64_t duration) const;
+ sp<AMessage> getLatestMeta();
+
protected:
virtual ~AnotherPacketSource();
@@ -74,6 +76,7 @@ private:
int64_t mLastQueuedTimeUs;
List<sp<ABuffer> > mBuffers;
status_t mEOSResult;
+ sp<AMessage> mLatestEnqueuedMeta;
bool wasFormatChange(int32_t discontinuityType) const;
diff --git a/media/libstagefright/mpeg2ts/ESQueue.cpp b/media/libstagefright/mpeg2ts/ESQueue.cpp
index 8f9c9c8..1960b27 100644
--- a/media/libstagefright/mpeg2ts/ESQueue.cpp
+++ b/media/libstagefright/mpeg2ts/ESQueue.cpp
@@ -31,6 +31,7 @@
#include "include/avc_utils.h"
+#include <inttypes.h>
#include <netinet/in.h>
namespace android {
@@ -181,7 +182,7 @@ status_t ElementaryStreamQueue::appendData(
if (startOffset > 0) {
ALOGI("found something resembling an H.264/MPEG syncword "
- "at offset %d",
+ "at offset %zd",
startOffset);
}
@@ -214,7 +215,7 @@ status_t ElementaryStreamQueue::appendData(
if (startOffset > 0) {
ALOGI("found something resembling an AAC syncword at "
- "offset %d",
+ "offset %zd",
startOffset);
}
@@ -242,7 +243,7 @@ status_t ElementaryStreamQueue::appendData(
if (startOffset > 0) {
ALOGI("found something resembling an MPEG audio "
- "syncword at offset %d",
+ "syncword at offset %zd",
startOffset);
}
@@ -266,7 +267,7 @@ status_t ElementaryStreamQueue::appendData(
if (mBuffer == NULL || neededSize > mBuffer->capacity()) {
neededSize = (neededSize + 65535) & ~65535;
- ALOGV("resizing buffer to size %d", neededSize);
+ ALOGV("resizing buffer to size %zu", neededSize);
sp<ABuffer> buffer = new ABuffer(neededSize);
if (mBuffer != NULL) {
@@ -289,7 +290,7 @@ status_t ElementaryStreamQueue::appendData(
#if 0
if (mMode == AAC) {
- ALOGI("size = %d, timeUs = %.2f secs", size, timeUs / 1E6);
+ ALOGI("size = %zu, timeUs = %.2f secs", size, timeUs / 1E6);
hexdump(data, size);
}
#endif
@@ -604,7 +605,9 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitH264() {
dstOffset += pos.nalSize + 4;
}
+#if !LOG_NDEBUG
ALOGV("accessUnit contains nal types %s", out.c_str());
+#endif
const NALPosition &pos = nals.itemAt(nals.size() - 1);
size_t nextScan = pos.nalOffset + pos.nalSize;
@@ -835,7 +838,7 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitMPEGVideo() {
accessUnit->meta()->setInt64("timeUs", timeUs);
- ALOGV("returning MPEG video access unit at time %lld us",
+ ALOGV("returning MPEG video access unit at time %" PRId64 " us",
timeUs);
// hexdump(accessUnit->data(), accessUnit->size());
@@ -994,7 +997,7 @@ sp<ABuffer> ElementaryStreamQueue::dequeueAccessUnitMPEG4Video() {
accessUnit->meta()->setInt64("timeUs", timeUs);
- ALOGV("returning MPEG4 video access unit at time %lld us",
+ ALOGV("returning MPEG4 video access unit at time %" PRId64 " us",
timeUs);
// hexdump(accessUnit->data(), accessUnit->size());
diff --git a/media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp b/media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp
index dd714c9..85859f7 100644
--- a/media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp
+++ b/media/libstagefright/mpeg2ts/MPEG2PSExtractor.cpp
@@ -36,6 +36,8 @@
#include <media/stagefright/Utils.h>
#include <utils/String8.h>
+#include <inttypes.h>
+
namespace android {
struct MPEG2PSExtractor::Track : public MediaSource {
@@ -130,7 +132,8 @@ sp<MediaSource> MPEG2PSExtractor::getTrack(size_t index) {
return new WrappedTrack(this, mTracks.valueAt(index));
}
-sp<MetaData> MPEG2PSExtractor::getTrackMetaData(size_t index, uint32_t flags) {
+sp<MetaData> MPEG2PSExtractor::getTrackMetaData(
+ size_t index, uint32_t /* flags */) {
if (index >= mTracks.size()) {
return NULL;
}
@@ -408,7 +411,7 @@ ssize_t MPEG2PSExtractor::dequeuePES() {
PTS |= br.getBits(15);
CHECK_EQ(br.getBits(1), 1u);
- ALOGV("PTS = %llu", PTS);
+ ALOGV("PTS = %" PRIu64, PTS);
// ALOGI("PTS = %.2f secs", PTS / 90000.0f);
optional_bytes_remaining -= 5;
@@ -425,7 +428,7 @@ ssize_t MPEG2PSExtractor::dequeuePES() {
DTS |= br.getBits(15);
CHECK_EQ(br.getBits(1), 1u);
- ALOGV("DTS = %llu", DTS);
+ ALOGV("DTS = %" PRIu64, DTS);
optional_bytes_remaining -= 5;
}
@@ -443,7 +446,7 @@ ssize_t MPEG2PSExtractor::dequeuePES() {
ESCR |= br.getBits(15);
CHECK_EQ(br.getBits(1), 1u);
- ALOGV("ESCR = %llu", ESCR);
+ ALOGV("ESCR = %" PRIu64, ESCR);
/* unsigned ESCR_extension = */br.getBits(9);
CHECK_EQ(br.getBits(1), 1u);
@@ -472,7 +475,7 @@ ssize_t MPEG2PSExtractor::dequeuePES() {
if (br.numBitsLeft() < dataLength * 8) {
ALOGE("PES packet does not carry enough data to contain "
- "payload. (numBitsLeft = %d, required = %d)",
+ "payload. (numBitsLeft = %zu, required = %u)",
br.numBitsLeft(), dataLength * 8);
return ERROR_MALFORMED;
@@ -625,7 +628,7 @@ status_t MPEG2PSExtractor::Track::read(
status_t MPEG2PSExtractor::Track::appendPESData(
unsigned PTS_DTS_flags,
- uint64_t PTS, uint64_t DTS,
+ uint64_t PTS, uint64_t /* DTS */,
const uint8_t *data, size_t size) {
if (mQueue == NULL) {
return OK;
diff --git a/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp b/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
index d449c34..35ca118 100644
--- a/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
+++ b/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
@@ -141,7 +141,7 @@ sp<MediaSource> MPEG2TSExtractor::getTrack(size_t index) {
}
sp<MetaData> MPEG2TSExtractor::getTrackMetaData(
- size_t index, uint32_t flags) {
+ size_t index, uint32_t /* flags */) {
return index < mSourceImpls.size()
? mSourceImpls.editItemAt(index)->getFormat() : NULL;
}
diff --git a/media/libstagefright/omx/GraphicBufferSource.cpp b/media/libstagefright/omx/GraphicBufferSource.cpp
index b8970ad..3fe9c23 100644
--- a/media/libstagefright/omx/GraphicBufferSource.cpp
+++ b/media/libstagefright/omx/GraphicBufferSource.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include <inttypes.h>
+
#define LOG_TAG "GraphicBufferSource"
//#define LOG_NDEBUG 0
#include <utils/Log.h>
@@ -42,7 +44,11 @@ GraphicBufferSource::GraphicBufferSource(OMXNodeInstance* nodeInstance,
mEndOfStream(false),
mEndOfStreamSent(false),
mRepeatAfterUs(-1ll),
+ mMaxTimestampGapUs(-1ll),
+ mPrevOriginalTimeUs(-1ll),
+ mPrevModifiedTimeUs(-1ll),
mRepeatLastFrameGeneration(0),
+ mRepeatLastFrameTimestamp(-1ll),
mLatestSubmittedBufferId(-1),
mLatestSubmittedBufferFrameNum(0),
mLatestSubmittedBufferUseCount(0),
@@ -196,7 +202,7 @@ void GraphicBufferSource::addCodecBuffer(OMX_BUFFERHEADERTYPE* header) {
return;
}
- ALOGV("addCodecBuffer h=%p size=%lu p=%p",
+ ALOGV("addCodecBuffer h=%p size=%" PRIu32 " p=%p",
header, header->nAllocLen, header->pBuffer);
CodecBuffer codecBuffer;
codecBuffer.mHeader = header;
@@ -217,7 +223,7 @@ void GraphicBufferSource::codecBufferEmptied(OMX_BUFFERHEADERTYPE* header) {
return;
}
- ALOGV("codecBufferEmptied h=%p size=%lu filled=%lu p=%p",
+ ALOGV("codecBufferEmptied h=%p size=%" PRIu32 " filled=%" PRIu32 " p=%p",
header, header->nAllocLen, header->nFilledLen,
header->pBuffer);
CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi));
@@ -299,6 +305,32 @@ void GraphicBufferSource::codecBufferEmptied(OMX_BUFFERHEADERTYPE* header) {
return;
}
+void GraphicBufferSource::codecBufferFilled(OMX_BUFFERHEADERTYPE* header) {
+ Mutex::Autolock autoLock(mMutex);
+
+ if (mMaxTimestampGapUs > 0ll
+ && !(header->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
+ ssize_t index = mOriginalTimeUs.indexOfKey(header->nTimeStamp);
+ if (index >= 0) {
+ ALOGV("OUT timestamp: %lld -> %lld",
+ header->nTimeStamp, mOriginalTimeUs[index]);
+ header->nTimeStamp = mOriginalTimeUs[index];
+ mOriginalTimeUs.removeItemsAt(index);
+ } else {
+ // giving up the effort as encoder doesn't appear to preserve pts
+ ALOGW("giving up limiting timestamp gap (pts = %lld)",
+ header->nTimeStamp);
+ mMaxTimestampGapUs = -1ll;
+ }
+ if (mOriginalTimeUs.size() > BufferQueue::NUM_BUFFER_SLOTS) {
+ // something terribly wrong must have happened, giving up...
+ ALOGE("mOriginalTimeUs has too many entries (%d)",
+ mOriginalTimeUs.size());
+ mMaxTimestampGapUs = -1ll;
+ }
+ }
+}
+
void GraphicBufferSource::suspend(bool suspend) {
Mutex::Autolock autoLock(mMutex);
@@ -431,6 +463,7 @@ bool GraphicBufferSource::repeatLatestSubmittedBuffer_l() {
BufferQueue::BufferItem item;
item.mBuf = mLatestSubmittedBufferId;
item.mFrameNumber = mLatestSubmittedBufferFrameNum;
+ item.mTimestamp = mRepeatLastFrameTimestamp;
status_t err = submitBuffer_l(item, cbi);
@@ -440,6 +473,20 @@ bool GraphicBufferSource::repeatLatestSubmittedBuffer_l() {
++mLatestSubmittedBufferUseCount;
+ /* repeat last frame up to kRepeatLastFrameCount times.
+ * in case of static scene, a single repeat might not get rid of encoder
+ * ghosting completely, refresh a couple more times to get better quality
+ */
+ if (--mRepeatLastFrameCount > 0) {
+ mRepeatLastFrameTimestamp = item.mTimestamp + mRepeatAfterUs * 1000;
+
+ if (mReflector != NULL) {
+ sp<AMessage> msg = new AMessage(kWhatRepeatLastFrame, mReflector->id());
+ msg->setInt32("generation", ++mRepeatLastFrameGeneration);
+ msg->post(mRepeatAfterUs);
+ }
+ }
+
return true;
}
@@ -460,8 +507,11 @@ void GraphicBufferSource::setLatestSubmittedBuffer_l(
mLatestSubmittedBufferId = item.mBuf;
mLatestSubmittedBufferFrameNum = item.mFrameNumber;
+ mRepeatLastFrameTimestamp = item.mTimestamp + mRepeatAfterUs * 1000;
+
mLatestSubmittedBufferUseCount = 1;
mRepeatBufferDeferred = false;
+ mRepeatLastFrameCount = kRepeatLastFrameCount;
if (mReflector != NULL) {
sp<AMessage> msg = new AMessage(kWhatRepeatLastFrame, mReflector->id());
@@ -497,9 +547,48 @@ status_t GraphicBufferSource::signalEndOfInputStream() {
return OK;
}
+int64_t GraphicBufferSource::getTimestamp(const BufferQueue::BufferItem &item) {
+ int64_t timeUs = item.mTimestamp / 1000;
+
+ if (mMaxTimestampGapUs > 0ll) {
+ /* Cap timestamp gap between adjacent frames to specified max
+ *
+ * In the scenario of cast mirroring, encoding could be suspended for
+ * prolonged periods. Limiting the pts gap to workaround the problem
+ * where encoder's rate control logic produces huge frames after a
+ * long period of suspension.
+ */
+
+ int64_t originalTimeUs = timeUs;
+ if (mPrevOriginalTimeUs >= 0ll) {
+ if (originalTimeUs < mPrevOriginalTimeUs) {
+ // Drop the frame if it's going backward in time. Bad timestamp
+ // could disrupt encoder's rate control completely.
+ ALOGW("Dropping frame that's going backward in time");
+ return -1;
+ }
+ int64_t timestampGapUs = originalTimeUs - mPrevOriginalTimeUs;
+ timeUs = (timestampGapUs < mMaxTimestampGapUs ?
+ timestampGapUs : mMaxTimestampGapUs) + mPrevModifiedTimeUs;
+ }
+ mPrevOriginalTimeUs = originalTimeUs;
+ mPrevModifiedTimeUs = timeUs;
+ mOriginalTimeUs.add(timeUs, originalTimeUs);
+ ALOGV("IN timestamp: %lld -> %lld", originalTimeUs, timeUs);
+ }
+
+ return timeUs;
+}
+
status_t GraphicBufferSource::submitBuffer_l(
const BufferQueue::BufferItem &item, int cbi) {
ALOGV("submitBuffer_l cbi=%d", cbi);
+
+ int64_t timeUs = getTimestamp(item);
+ if (timeUs < 0ll) {
+ return UNKNOWN_ERROR;
+ }
+
CodecBuffer& codecBuffer(mCodecBuffers.editItemAt(cbi));
codecBuffer.mGraphicBuffer = mBufferSlot[item.mBuf];
codecBuffer.mBuf = item.mBuf;
@@ -515,7 +604,7 @@ status_t GraphicBufferSource::submitBuffer_l(
status_t err = mNodeInstance->emptyDirectBuffer(header, 0,
4 + sizeof(buffer_handle_t), OMX_BUFFERFLAG_ENDOFFRAME,
- item.mTimestamp / 1000);
+ timeUs);
if (err != OK) {
ALOGW("WARNING: emptyDirectBuffer failed: 0x%x", err);
codecBuffer.mGraphicBuffer = NULL;
@@ -609,6 +698,12 @@ void GraphicBufferSource::onFrameAvailable() {
BufferQueue::BufferItem item;
status_t err = mBufferQueue->acquireBuffer(&item, 0);
if (err == OK) {
+ // If this is the first time we're seeing this buffer, add it to our
+ // slot table.
+ if (item.mGraphicBuffer != NULL) {
+ ALOGV("fillCodecBuffer_l: setting mBufferSlot %d", item.mBuf);
+ mBufferSlot[item.mBuf] = item.mGraphicBuffer;
+ }
mBufferQueue->releaseBuffer(item.mBuf, item.mFrameNumber,
EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, item.mFence);
}
@@ -658,6 +753,17 @@ status_t GraphicBufferSource::setRepeatPreviousFrameDelayUs(
return OK;
}
+status_t GraphicBufferSource::setMaxTimestampGapUs(int64_t maxGapUs) {
+ Mutex::Autolock autoLock(mMutex);
+
+ if (mExecuting || maxGapUs <= 0ll) {
+ return INVALID_OPERATION;
+ }
+
+ mMaxTimestampGapUs = maxGapUs;
+
+ return OK;
+}
void GraphicBufferSource::onMessageReceived(const sp<AMessage> &msg) {
switch (msg->what()) {
case kWhatRepeatLastFrame:
diff --git a/media/libstagefright/omx/GraphicBufferSource.h b/media/libstagefright/omx/GraphicBufferSource.h
index 9e5eee6..3b0e454 100644
--- a/media/libstagefright/omx/GraphicBufferSource.h
+++ b/media/libstagefright/omx/GraphicBufferSource.h
@@ -87,6 +87,10 @@ public:
// fill it with a new frame of data; otherwise, just mark it as available.
void codecBufferEmptied(OMX_BUFFERHEADERTYPE* header);
+ // Called when omx_message::FILL_BUFFER_DONE is received. (Currently the
+ // buffer source will fix timestamp in the header if needed.)
+ void codecBufferFilled(OMX_BUFFERHEADERTYPE* header);
+
// This is called after the last input frame has been submitted. We
// need to submit an empty buffer with the EOS flag set. If we don't
// have a codec buffer ready, we just set the mEndOfStream flag.
@@ -105,6 +109,15 @@ public:
// state and once this behaviour is specified it cannot be reset.
status_t setRepeatPreviousFrameDelayUs(int64_t repeatAfterUs);
+ // When set, the timestamp fed to the encoder will be modified such that
+ // the gap between two adjacent frames is capped at maxGapUs. Timestamp
+ // will be restored to the original when the encoded frame is returned to
+ // the client.
+ // This is to solve a problem in certain real-time streaming case, where
+ // encoder's rate control logic produces huge frames after a long period
+ // of suspension on input.
+ status_t setMaxTimestampGapUs(int64_t maxGapUs);
+
protected:
// BufferQueue::ConsumerListener interface, called when a new frame of
// data is available. If we're executing and a codec buffer is
@@ -165,6 +178,7 @@ private:
void setLatestSubmittedBuffer_l(const BufferQueue::BufferItem &item);
bool repeatLatestSubmittedBuffer_l();
+ int64_t getTimestamp(const BufferQueue::BufferItem &item);
// Lock, covers all member variables.
mutable Mutex mMutex;
@@ -206,13 +220,22 @@ private:
enum {
kWhatRepeatLastFrame,
};
-
+ enum {
+ kRepeatLastFrameCount = 10,
+ };
int64_t mRepeatAfterUs;
+ int64_t mMaxTimestampGapUs;
+
+ KeyedVector<int64_t, int64_t> mOriginalTimeUs;
+ int64_t mPrevOriginalTimeUs;
+ int64_t mPrevModifiedTimeUs;
sp<ALooper> mLooper;
sp<AHandlerReflector<GraphicBufferSource> > mReflector;
int32_t mRepeatLastFrameGeneration;
+ int64_t mRepeatLastFrameTimestamp;
+ int32_t mRepeatLastFrameCount;
int mLatestSubmittedBufferId;
uint64_t mLatestSubmittedBufferFrameNum;
diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp
index 84a0e10..7819fc3 100644
--- a/media/libstagefright/omx/OMX.cpp
+++ b/media/libstagefright/omx/OMX.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include <inttypes.h>
+
//#define LOG_NDEBUG 0
#define LOG_TAG "OMX"
#include <utils/Log.h>
@@ -185,7 +187,7 @@ void OMX::binderDied(const wp<IBinder> &the_late_who) {
instance->onObserverDied(mMaster);
}
-bool OMX::livesLocally(node_id node, pid_t pid) {
+bool OMX::livesLocally(node_id /* node */, pid_t pid) {
return pid == getpid();
}
@@ -285,6 +287,7 @@ status_t OMX::sendCommand(
status_t OMX::getParameter(
node_id node, OMX_INDEXTYPE index,
void *params, size_t size) {
+ ALOGV("getParameter(%u %#x %p %zd)", node, index, params, size);
return findInstance(node)->getParameter(
index, params, size);
}
@@ -292,6 +295,7 @@ status_t OMX::getParameter(
status_t OMX::setParameter(
node_id node, OMX_INDEXTYPE index,
const void *params, size_t size) {
+ ALOGV("setParameter(%u %#x %p %zd)", node, index, params, size);
return findInstance(node)->setParameter(
index, params, size);
}
@@ -424,8 +428,8 @@ OMX_ERRORTYPE OMX::OnEvent(
OMX_IN OMX_EVENTTYPE eEvent,
OMX_IN OMX_U32 nData1,
OMX_IN OMX_U32 nData2,
- OMX_IN OMX_PTR pEventData) {
- ALOGV("OnEvent(%d, %ld, %ld)", eEvent, nData1, nData2);
+ OMX_IN OMX_PTR /* pEventData */) {
+ ALOGV("OnEvent(%d, %" PRIu32", %" PRIu32 ")", eEvent, nData1, nData2);
// Forward to OMXNodeInstance.
findInstance(node)->onEvent(eEvent, nData1, nData2);
@@ -443,13 +447,13 @@ OMX_ERRORTYPE OMX::OnEvent(
}
OMX_ERRORTYPE OMX::OnEmptyBufferDone(
- node_id node, OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) {
+ node_id node, buffer_id buffer, OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) {
ALOGV("OnEmptyBufferDone buffer=%p", pBuffer);
omx_message msg;
msg.type = omx_message::EMPTY_BUFFER_DONE;
msg.node = node;
- msg.u.buffer_data.buffer = pBuffer;
+ msg.u.buffer_data.buffer = buffer;
findDispatcher(node)->post(msg);
@@ -457,13 +461,13 @@ OMX_ERRORTYPE OMX::OnEmptyBufferDone(
}
OMX_ERRORTYPE OMX::OnFillBufferDone(
- node_id node, OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) {
+ node_id node, buffer_id buffer, OMX_IN OMX_BUFFERHEADERTYPE *pBuffer) {
ALOGV("OnFillBufferDone buffer=%p", pBuffer);
omx_message msg;
msg.type = omx_message::FILL_BUFFER_DONE;
msg.node = node;
- msg.u.extended_buffer_data.buffer = pBuffer;
+ msg.u.extended_buffer_data.buffer = buffer;
msg.u.extended_buffer_data.range_offset = pBuffer->nOffset;
msg.u.extended_buffer_data.range_length = pBuffer->nFilledLen;
msg.u.extended_buffer_data.flags = pBuffer->nFlags;
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index 5f104fc..c64dcf0 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -92,10 +92,14 @@ OMX_CALLBACKTYPE OMXNodeInstance::kCallbacks = {
OMXNodeInstance::OMXNodeInstance(
OMX *owner, const sp<IOMXObserver> &observer)
: mOwner(owner),
- mNodeID(NULL),
+ mNodeID(0),
mHandle(NULL),
mObserver(observer),
- mDying(false) {
+ mDying(false)
+#ifdef __LP64__
+ , mBufferIDCount(0)
+#endif
+{
}
OMXNodeInstance::~OMXNodeInstance() {
@@ -232,7 +236,7 @@ status_t OMXNodeInstance::freeNode(OMXMaster *master) {
}
mOwner->invalidateNodeID(mNodeID);
- mNodeID = NULL;
+ mNodeID = 0;
ALOGV("OMXNodeInstance going away.");
delete this;
@@ -266,26 +270,26 @@ status_t OMXNodeInstance::sendCommand(
}
status_t OMXNodeInstance::getParameter(
- OMX_INDEXTYPE index, void *params, size_t size) {
+ OMX_INDEXTYPE index, void *params, size_t /* size */) {
Mutex::Autolock autoLock(mLock);
OMX_ERRORTYPE err = OMX_GetParameter(mHandle, index, params);
-
+ ALOGE_IF(err != OMX_ErrorNone, "getParameter(%d) ERROR: %#x", index, err);
return StatusFromOMXError(err);
}
status_t OMXNodeInstance::setParameter(
- OMX_INDEXTYPE index, const void *params, size_t size) {
+ OMX_INDEXTYPE index, const void *params, size_t /* size */) {
Mutex::Autolock autoLock(mLock);
OMX_ERRORTYPE err = OMX_SetParameter(
mHandle, index, const_cast<void *>(params));
-
+ ALOGE_IF(err != OMX_ErrorNone, "setParameter(%d) ERROR: %#x", index, err);
return StatusFromOMXError(err);
}
status_t OMXNodeInstance::getConfig(
- OMX_INDEXTYPE index, void *params, size_t size) {
+ OMX_INDEXTYPE index, void *params, size_t /* size */) {
Mutex::Autolock autoLock(mLock);
OMX_ERRORTYPE err = OMX_GetConfig(mHandle, index, params);
@@ -293,7 +297,7 @@ status_t OMXNodeInstance::getConfig(
}
status_t OMXNodeInstance::setConfig(
- OMX_INDEXTYPE index, const void *params, size_t size) {
+ OMX_INDEXTYPE index, const void *params, size_t /* size */) {
Mutex::Autolock autoLock(mLock);
OMX_ERRORTYPE err = OMX_SetConfig(
@@ -482,7 +486,7 @@ status_t OMXNodeInstance::useBuffer(
CHECK_EQ(header->pAppPrivate, buffer_meta);
- *buffer = header;
+ *buffer = makeBufferID(header);
addActiveBuffer(portIndex, *buffer);
@@ -538,7 +542,7 @@ status_t OMXNodeInstance::useGraphicBuffer2_l(
CHECK_EQ(header->pBuffer, bufferHandle);
CHECK_EQ(header->pAppPrivate, bufferMeta);
- *buffer = header;
+ *buffer = makeBufferID(header);
addActiveBuffer(portIndex, *buffer);
@@ -602,7 +606,7 @@ status_t OMXNodeInstance::useGraphicBuffer(
CHECK_EQ(header->pAppPrivate, bufferMeta);
- *buffer = header;
+ *buffer = makeBufferID(header);
addActiveBuffer(portIndex, *buffer);
@@ -610,11 +614,11 @@ status_t OMXNodeInstance::useGraphicBuffer(
}
status_t OMXNodeInstance::updateGraphicBufferInMeta(
- OMX_U32 portIndex, const sp<GraphicBuffer>& graphicBuffer,
+ OMX_U32 /* portIndex */, const sp<GraphicBuffer>& graphicBuffer,
OMX::buffer_id buffer) {
Mutex::Autolock autoLock(mLock);
- OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)(buffer);
+ OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer);
VideoDecoderOutputMetaData *metadata =
(VideoDecoderOutputMetaData *)(header->pBuffer);
BufferMeta *bufferMeta = (BufferMeta *)(header->pAppPrivate);
@@ -710,7 +714,7 @@ status_t OMXNodeInstance::allocateBuffer(
CHECK_EQ(header->pAppPrivate, buffer_meta);
- *buffer = header;
+ *buffer = makeBufferID(header);
*buffer_data = header->pBuffer;
addActiveBuffer(portIndex, *buffer);
@@ -748,7 +752,7 @@ status_t OMXNodeInstance::allocateBufferWithBackup(
CHECK_EQ(header->pAppPrivate, buffer_meta);
- *buffer = header;
+ *buffer = makeBufferID(header);
addActiveBuffer(portIndex, *buffer);
@@ -766,13 +770,14 @@ status_t OMXNodeInstance::freeBuffer(
removeActiveBuffer(portIndex, buffer);
- OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)buffer;
+ OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer);
BufferMeta *buffer_meta = static_cast<BufferMeta *>(header->pAppPrivate);
OMX_ERRORTYPE err = OMX_FreeBuffer(mHandle, portIndex, header);
delete buffer_meta;
buffer_meta = NULL;
+ invalidateBufferID(buffer);
return StatusFromOMXError(err);
}
@@ -780,7 +785,7 @@ status_t OMXNodeInstance::freeBuffer(
status_t OMXNodeInstance::fillBuffer(OMX::buffer_id buffer) {
Mutex::Autolock autoLock(mLock);
- OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)buffer;
+ OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer);
header->nFilledLen = 0;
header->nOffset = 0;
header->nFlags = 0;
@@ -796,7 +801,7 @@ status_t OMXNodeInstance::emptyBuffer(
OMX_U32 flags, OMX_TICKS timestamp) {
Mutex::Autolock autoLock(mLock);
- OMX_BUFFERHEADERTYPE *header = (OMX_BUFFERHEADERTYPE *)buffer;
+ OMX_BUFFERHEADERTYPE *header = findBufferHeader(buffer);
header->nFilledLen = rangeLength;
header->nOffset = rangeOffset;
header->nFlags = flags;
@@ -849,6 +854,7 @@ status_t OMXNodeInstance::setInternalOption(
switch (type) {
case IOMX::INTERNAL_OPTION_SUSPEND:
case IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY:
+ case IOMX::INTERNAL_OPTION_MAX_TIMESTAMP_GAP:
{
const sp<GraphicBufferSource> &bufferSource =
getGraphicBufferSource();
@@ -864,7 +870,8 @@ status_t OMXNodeInstance::setInternalOption(
bool suspend = *(bool *)data;
bufferSource->suspend(suspend);
- } else {
+ } else if (type ==
+ IOMX::INTERNAL_OPTION_REPEAT_PREVIOUS_FRAME_DELAY){
if (size != sizeof(int64_t)) {
return INVALID_OPERATION;
}
@@ -872,6 +879,14 @@ status_t OMXNodeInstance::setInternalOption(
int64_t delayUs = *(int64_t *)data;
return bufferSource->setRepeatPreviousFrameDelayUs(delayUs);
+ } else {
+ if (size != sizeof(int64_t)) {
+ return INVALID_OPERATION;
+ }
+
+ int64_t maxGapUs = *(int64_t *)data;
+
+ return bufferSource->setMaxTimestampGapUs(maxGapUs);
}
return OK;
@@ -883,19 +898,28 @@ status_t OMXNodeInstance::setInternalOption(
}
void OMXNodeInstance::onMessage(const omx_message &msg) {
+ const sp<GraphicBufferSource>& bufferSource(getGraphicBufferSource());
+
if (msg.type == omx_message::FILL_BUFFER_DONE) {
OMX_BUFFERHEADERTYPE *buffer =
- static_cast<OMX_BUFFERHEADERTYPE *>(
- msg.u.extended_buffer_data.buffer);
+ findBufferHeader(msg.u.extended_buffer_data.buffer);
BufferMeta *buffer_meta =
static_cast<BufferMeta *>(buffer->pAppPrivate);
buffer_meta->CopyFromOMX(buffer);
- } else if (msg.type == omx_message::EMPTY_BUFFER_DONE) {
- const sp<GraphicBufferSource>& bufferSource(getGraphicBufferSource());
if (bufferSource != NULL) {
+ // fix up the buffer info (especially timestamp) if needed
+ bufferSource->codecBufferFilled(buffer);
+
+ omx_message newMsg = msg;
+ newMsg.u.extended_buffer_data.timestamp = buffer->nTimeStamp;
+ mObserver->onMessage(newMsg);
+ return;
+ }
+ } else if (msg.type == omx_message::EMPTY_BUFFER_DONE) {
+ if (bufferSource != NULL) {
// This is one of the buffers used exclusively by
// GraphicBufferSource.
// Don't dispatch a message back to ACodec, since it doesn't
@@ -903,8 +927,7 @@ void OMXNodeInstance::onMessage(const omx_message &msg) {
// be very confused.
OMX_BUFFERHEADERTYPE *buffer =
- static_cast<OMX_BUFFERHEADERTYPE *>(
- msg.u.buffer_data.buffer);
+ findBufferHeader(msg.u.buffer_data.buffer);
bufferSource->codecBufferEmptied(buffer);
return;
@@ -941,7 +964,7 @@ void OMXNodeInstance::onEvent(
// static
OMX_ERRORTYPE OMXNodeInstance::OnEvent(
- OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_IN OMX_HANDLETYPE /* hComponent */,
OMX_IN OMX_PTR pAppData,
OMX_IN OMX_EVENTTYPE eEvent,
OMX_IN OMX_U32 nData1,
@@ -957,26 +980,28 @@ OMX_ERRORTYPE OMXNodeInstance::OnEvent(
// static
OMX_ERRORTYPE OMXNodeInstance::OnEmptyBufferDone(
- OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_IN OMX_HANDLETYPE /* hComponent */,
OMX_IN OMX_PTR pAppData,
OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) {
OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
if (instance->mDying) {
return OMX_ErrorNone;
}
- return instance->owner()->OnEmptyBufferDone(instance->nodeID(), pBuffer);
+ return instance->owner()->OnEmptyBufferDone(instance->nodeID(),
+ instance->findBufferID(pBuffer), pBuffer);
}
// static
OMX_ERRORTYPE OMXNodeInstance::OnFillBufferDone(
- OMX_IN OMX_HANDLETYPE hComponent,
+ OMX_IN OMX_HANDLETYPE /* hComponent */,
OMX_IN OMX_PTR pAppData,
OMX_IN OMX_BUFFERHEADERTYPE* pBuffer) {
OMXNodeInstance *instance = static_cast<OMXNodeInstance *>(pAppData);
if (instance->mDying) {
return OMX_ErrorNone;
}
- return instance->owner()->OnFillBufferDone(instance->nodeID(), pBuffer);
+ return instance->owner()->OnFillBufferDone(instance->nodeID(),
+ instance->findBufferID(pBuffer), pBuffer);
}
void OMXNodeInstance::addActiveBuffer(OMX_U32 portIndex, OMX::buffer_id id) {
@@ -1011,4 +1036,67 @@ void OMXNodeInstance::freeActiveBuffers() {
}
}
+#ifdef __LP64__
+
+OMX::buffer_id OMXNodeInstance::makeBufferID(OMX_BUFFERHEADERTYPE *bufferHeader) {
+ if (bufferHeader == NULL) {
+ return 0;
+ }
+ Mutex::Autolock autoLock(mBufferIDLock);
+ OMX::buffer_id buffer;
+ do { // handle the very unlikely case of ID overflow
+ if (++mBufferIDCount == 0) {
+ ++mBufferIDCount;
+ }
+ buffer = (OMX::buffer_id)mBufferIDCount;
+ } while (mBufferIDToBufferHeader.indexOfKey(buffer) >= 0);
+ mBufferIDToBufferHeader.add(buffer, bufferHeader);
+ mBufferHeaderToBufferID.add(bufferHeader, buffer);
+ return buffer;
+}
+
+OMX_BUFFERHEADERTYPE *OMXNodeInstance::findBufferHeader(OMX::buffer_id buffer) {
+ if (buffer == 0) {
+ return NULL;
+ }
+ Mutex::Autolock autoLock(mBufferIDLock);
+ return mBufferIDToBufferHeader.valueFor(buffer);
+}
+
+OMX::buffer_id OMXNodeInstance::findBufferID(OMX_BUFFERHEADERTYPE *bufferHeader) {
+ if (bufferHeader == NULL) {
+ return 0;
+ }
+ Mutex::Autolock autoLock(mBufferIDLock);
+ return mBufferHeaderToBufferID.valueFor(bufferHeader);
+}
+
+void OMXNodeInstance::invalidateBufferID(OMX::buffer_id buffer) {
+ if (buffer == 0) {
+ return;
+ }
+ Mutex::Autolock autoLock(mBufferIDLock);
+ mBufferHeaderToBufferID.removeItem(mBufferIDToBufferHeader.valueFor(buffer));
+ mBufferIDToBufferHeader.removeItem(buffer);
+}
+
+#else
+
+OMX::buffer_id OMXNodeInstance::makeBufferID(OMX_BUFFERHEADERTYPE *bufferHeader) {
+ return (OMX::buffer_id)bufferHeader;
+}
+
+OMX_BUFFERHEADERTYPE *OMXNodeInstance::findBufferHeader(OMX::buffer_id buffer) {
+ return (OMX_BUFFERHEADERTYPE *)buffer;
+}
+
+OMX::buffer_id OMXNodeInstance::findBufferID(OMX_BUFFERHEADERTYPE *bufferHeader) {
+ return (OMX::buffer_id)bufferHeader;
+}
+
+void OMXNodeInstance::invalidateBufferID(OMX::buffer_id buffer __unused) {
+}
+
+#endif
+
} // namespace android
diff --git a/media/libstagefright/omx/SoftOMXComponent.cpp b/media/libstagefright/omx/SoftOMXComponent.cpp
index b1c34dc..646cd32 100644
--- a/media/libstagefright/omx/SoftOMXComponent.cpp
+++ b/media/libstagefright/omx/SoftOMXComponent.cpp
@@ -257,69 +257,69 @@ OMX_ERRORTYPE SoftOMXComponent::GetStateWrapper(
////////////////////////////////////////////////////////////////////////////////
OMX_ERRORTYPE SoftOMXComponent::sendCommand(
- OMX_COMMANDTYPE cmd, OMX_U32 param, OMX_PTR data) {
+ OMX_COMMANDTYPE /* cmd */, OMX_U32 /* param */, OMX_PTR /* data */) {
return OMX_ErrorUndefined;
}
OMX_ERRORTYPE SoftOMXComponent::getParameter(
- OMX_INDEXTYPE index, OMX_PTR params) {
+ OMX_INDEXTYPE /* index */, OMX_PTR /* params */) {
return OMX_ErrorUndefined;
}
OMX_ERRORTYPE SoftOMXComponent::setParameter(
- OMX_INDEXTYPE index, const OMX_PTR params) {
+ OMX_INDEXTYPE /* index */, const OMX_PTR /* params */) {
return OMX_ErrorUndefined;
}
OMX_ERRORTYPE SoftOMXComponent::getConfig(
- OMX_INDEXTYPE index, OMX_PTR params) {
+ OMX_INDEXTYPE /* index */, OMX_PTR /* params */) {
return OMX_ErrorUndefined;
}
OMX_ERRORTYPE SoftOMXComponent::setConfig(
- OMX_INDEXTYPE index, const OMX_PTR params) {
+ OMX_INDEXTYPE /* index */, const OMX_PTR /* params */) {
return OMX_ErrorUndefined;
}
OMX_ERRORTYPE SoftOMXComponent::getExtensionIndex(
- const char *name, OMX_INDEXTYPE *index) {
+ const char * /* name */, OMX_INDEXTYPE * /* index */) {
return OMX_ErrorUndefined;
}
OMX_ERRORTYPE SoftOMXComponent::useBuffer(
- OMX_BUFFERHEADERTYPE **buffer,
- OMX_U32 portIndex,
- OMX_PTR appPrivate,
- OMX_U32 size,
- OMX_U8 *ptr) {
+ OMX_BUFFERHEADERTYPE ** /* buffer */,
+ OMX_U32 /* portIndex */,
+ OMX_PTR /* appPrivate */,
+ OMX_U32 /* size */,
+ OMX_U8 * /* ptr */) {
return OMX_ErrorUndefined;
}
OMX_ERRORTYPE SoftOMXComponent::allocateBuffer(
- OMX_BUFFERHEADERTYPE **buffer,
- OMX_U32 portIndex,
- OMX_PTR appPrivate,
- OMX_U32 size) {
+ OMX_BUFFERHEADERTYPE ** /* buffer */,
+ OMX_U32 /* portIndex */,
+ OMX_PTR /* appPrivate */,
+ OMX_U32 /* size */) {
return OMX_ErrorUndefined;
}
OMX_ERRORTYPE SoftOMXComponent::freeBuffer(
- OMX_U32 portIndex,
- OMX_BUFFERHEADERTYPE *buffer) {
+ OMX_U32 /* portIndex */,
+ OMX_BUFFERHEADERTYPE * /* buffer */) {
return OMX_ErrorUndefined;
}
OMX_ERRORTYPE SoftOMXComponent::emptyThisBuffer(
- OMX_BUFFERHEADERTYPE *buffer) {
+ OMX_BUFFERHEADERTYPE * /* buffer */) {
return OMX_ErrorUndefined;
}
OMX_ERRORTYPE SoftOMXComponent::fillThisBuffer(
- OMX_BUFFERHEADERTYPE *buffer) {
+ OMX_BUFFERHEADERTYPE * /* buffer */) {
return OMX_ErrorUndefined;
}
-OMX_ERRORTYPE SoftOMXComponent::getState(OMX_STATETYPE *state) {
+OMX_ERRORTYPE SoftOMXComponent::getState(OMX_STATETYPE * /* state */) {
return OMX_ErrorUndefined;
}
diff --git a/media/libstagefright/omx/SoftOMXPlugin.cpp b/media/libstagefright/omx/SoftOMXPlugin.cpp
index d6cde73..d49e50b 100644
--- a/media/libstagefright/omx/SoftOMXPlugin.cpp
+++ b/media/libstagefright/omx/SoftOMXPlugin.cpp
@@ -154,7 +154,7 @@ OMX_ERRORTYPE SoftOMXPlugin::destroyComponentInstance(
OMX_ERRORTYPE SoftOMXPlugin::enumerateComponents(
OMX_STRING name,
- size_t size,
+ size_t /* size */,
OMX_U32 index) {
if (index >= kNumComponents) {
return OMX_ErrorNoMore;
diff --git a/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp b/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp
index 08a3d42..20a7076 100644
--- a/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp
+++ b/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include <inttypes.h>
+
//#define LOG_NDEBUG 0
#define LOG_TAG "SoftVideoDecoderOMXComponent"
#include <utils/Log.h>
@@ -175,18 +177,19 @@ OMX_ERRORTYPE SoftVideoDecoderOMXComponent::internalGetParameter(
{
OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevel =
(OMX_VIDEO_PARAM_PROFILELEVELTYPE *) params;
+ OMX_U32 profileIndex = profileLevel->nProfileIndex;
if (profileLevel->nPortIndex != kInputPortIndex) {
- ALOGE("Invalid port index: %ld", profileLevel->nPortIndex);
+ ALOGE("Invalid port index: %" PRIu32, profileLevel->nPortIndex);
return OMX_ErrorUnsupportedIndex;
}
- if (index >= mNumProfileLevels) {
+ if (profileIndex >= mNumProfileLevels) {
return OMX_ErrorNoMore;
}
- profileLevel->eProfile = mProfileLevels[index].mProfile;
- profileLevel->eLevel = mProfileLevels[index].mLevel;
+ profileLevel->eProfile = mProfileLevels[profileIndex].mProfile;
+ profileLevel->eLevel = mProfileLevels[profileIndex].mLevel;
return OMX_ErrorNone;
}
diff --git a/media/libstagefright/omx/tests/Android.mk b/media/libstagefright/omx/tests/Android.mk
index 1061c39..e368134 100644
--- a/media/libstagefright/omx/tests/Android.mk
+++ b/media/libstagefright/omx/tests/Android.mk
@@ -15,4 +15,6 @@ LOCAL_MODULE := omx_tests
LOCAL_MODULE_TAGS := tests
+LOCAL_32_BIT_ONLY := true
+
include $(BUILD_EXECUTABLE)
diff --git a/media/libstagefright/omx/tests/OMXHarness.cpp b/media/libstagefright/omx/tests/OMXHarness.cpp
index 4bee808..44e4f9d 100644
--- a/media/libstagefright/omx/tests/OMXHarness.cpp
+++ b/media/libstagefright/omx/tests/OMXHarness.cpp
@@ -16,6 +16,7 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "OMXHarness"
+#include <inttypes.h>
#include <utils/Log.h>
#include "OMXHarness.h"
@@ -711,11 +712,11 @@ status_t Harness::testSeek(
int64_t bufferTimeUs;
CHECK(buffer->meta_data()->findInt64(kKeyTime, &bufferTimeUs));
if (!CloseEnough(bufferTimeUs, actualSeekTimeUs)) {
- printf("\n * Attempted seeking to %lld us (%.2f secs)",
+ printf("\n * Attempted seeking to %" PRId64 " us (%.2f secs)",
requestedSeekTimeUs, requestedSeekTimeUs / 1E6);
- printf("\n * Nearest keyframe is at %lld us (%.2f secs)",
+ printf("\n * Nearest keyframe is at %" PRId64 " us (%.2f secs)",
actualSeekTimeUs, actualSeekTimeUs / 1E6);
- printf("\n * Returned buffer was at %lld us (%.2f secs)\n\n",
+ printf("\n * Returned buffer was at %" PRId64 " us (%.2f secs)\n\n",
bufferTimeUs, bufferTimeUs / 1E6);
buffer->release();
diff --git a/media/libstagefright/rtsp/AAVCAssembler.cpp b/media/libstagefright/rtsp/AAVCAssembler.cpp
index a6825eb..4bc67e8 100644
--- a/media/libstagefright/rtsp/AAVCAssembler.cpp
+++ b/media/libstagefright/rtsp/AAVCAssembler.cpp
@@ -124,7 +124,7 @@ ARTPAssembler::AssemblyStatus AAVCAssembler::addNALUnit(
}
void AAVCAssembler::addSingleNALUnit(const sp<ABuffer> &buffer) {
- ALOGV("addSingleNALUnit of size %d", buffer->size());
+ ALOGV("addSingleNALUnit of size %zu", buffer->size());
#if !LOG_NDEBUG
hexdump(buffer->data(), buffer->size());
#endif
@@ -191,7 +191,7 @@ ARTPAssembler::AssemblyStatus AAVCAssembler::addFragmentedNALUnit(
CHECK((indicator & 0x1f) == 28);
if (size < 2) {
- ALOGV("Ignoring malformed FU buffer (size = %d)", size);
+ ALOGV("Ignoring malformed FU buffer (size = %zu)", size);
queue->erase(queue->begin());
++mNextExpectedSeqNo;
@@ -225,7 +225,7 @@ ARTPAssembler::AssemblyStatus AAVCAssembler::addFragmentedNALUnit(
} else {
List<sp<ABuffer> >::iterator it = ++queue->begin();
while (it != queue->end()) {
- ALOGV("sequence length %d", totalCount);
+ ALOGV("sequence length %zu", totalCount);
const sp<ABuffer> &buffer = *it;
@@ -294,7 +294,7 @@ ARTPAssembler::AssemblyStatus AAVCAssembler::addFragmentedNALUnit(
for (size_t i = 0; i < totalCount; ++i) {
const sp<ABuffer> &buffer = *it;
- ALOGV("piece #%d/%d", i + 1, totalCount);
+ ALOGV("piece #%zu/%zu", i + 1, totalCount);
#if !LOG_NDEBUG
hexdump(buffer->data(), buffer->size());
#endif
@@ -317,7 +317,7 @@ ARTPAssembler::AssemblyStatus AAVCAssembler::addFragmentedNALUnit(
void AAVCAssembler::submitAccessUnit() {
CHECK(!mNALUnits.empty());
- ALOGV("Access unit complete (%d nal units)", mNALUnits.size());
+ ALOGV("Access unit complete (%zu nal units)", mNALUnits.size());
size_t totalSize = 0;
for (List<sp<ABuffer> >::iterator it = mNALUnits.begin();
diff --git a/media/libstagefright/rtsp/AMPEG2TSAssembler.cpp b/media/libstagefright/rtsp/AMPEG2TSAssembler.cpp
index 4c9bf5b..dca5c89 100644
--- a/media/libstagefright/rtsp/AMPEG2TSAssembler.cpp
+++ b/media/libstagefright/rtsp/AMPEG2TSAssembler.cpp
@@ -34,7 +34,9 @@
namespace android {
AMPEG2TSAssembler::AMPEG2TSAssembler(
- const sp<AMessage> &notify, const char *desc, const AString &params)
+ const sp<AMessage> &notify,
+ const char * /* desc */,
+ const AString & /* params */)
: mNotifyMsg(notify),
mNextExpectedSeqNoValid(false),
mNextExpectedSeqNo(0) {
diff --git a/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.cpp b/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.cpp
index eefceba..98b50dd 100644
--- a/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.cpp
+++ b/media/libstagefright/rtsp/AMPEG4ElementaryAssembler.cpp
@@ -365,7 +365,7 @@ ARTPAssembler::AssemblyStatus AMPEG4ElementaryAssembler::addPacket(
void AMPEG4ElementaryAssembler::submitAccessUnit() {
CHECK(!mPackets.empty());
- ALOGV("Access unit complete (%d nal units)", mPackets.size());
+ ALOGV("Access unit complete (%zu nal units)", mPackets.size());
sp<ABuffer> accessUnit;
diff --git a/media/libstagefright/rtsp/ARTPConnection.cpp b/media/libstagefright/rtsp/ARTPConnection.cpp
index af369b5..372fbe9 100644
--- a/media/libstagefright/rtsp/ARTPConnection.cpp
+++ b/media/libstagefright/rtsp/ARTPConnection.cpp
@@ -563,7 +563,7 @@ status_t ARTPConnection::parseRTCP(StreamInfo *s, const sp<ABuffer> &buffer) {
default:
{
- ALOGW("Unknown RTCP packet type %u of size %d",
+ ALOGW("Unknown RTCP packet type %u of size %zu",
(unsigned)data[1], headerLength);
break;
}
diff --git a/media/libstagefright/rtsp/ARTPWriter.cpp b/media/libstagefright/rtsp/ARTPWriter.cpp
index 0d07043..793d116 100644
--- a/media/libstagefright/rtsp/ARTPWriter.cpp
+++ b/media/libstagefright/rtsp/ARTPWriter.cpp
@@ -114,7 +114,7 @@ bool ARTPWriter::reachedEOS() {
return (mFlags & kFlagEOS) != 0;
}
-status_t ARTPWriter::start(MetaData *params) {
+status_t ARTPWriter::start(MetaData * /* params */) {
Mutex::Autolock autoLock(mLock);
if (mFlags & kFlagStarted) {
return INVALID_OPERATION;
@@ -277,7 +277,7 @@ void ARTPWriter::onRead(const sp<AMessage> &msg) {
}
if (mediaBuf->range_length() > 0) {
- ALOGV("read buffer of size %d", mediaBuf->range_length());
+ ALOGV("read buffer of size %zu", mediaBuf->range_length());
if (mMode == H264) {
StripStartcode(mediaBuf);
diff --git a/media/libstagefright/rtsp/ARTSPConnection.cpp b/media/libstagefright/rtsp/ARTSPConnection.cpp
index efde7a9..492bd4a 100644
--- a/media/libstagefright/rtsp/ARTSPConnection.cpp
+++ b/media/libstagefright/rtsp/ARTSPConnection.cpp
@@ -239,7 +239,7 @@ void ARTSPConnection::onConnect(const sp<AMessage> &msg) {
// right here, since we currently have no way of asking the user
// for this information.
- ALOGE("Malformed rtsp url %s", url.c_str());
+ ALOGE("Malformed rtsp url <URL suppressed>");
reply->setInt32("result", ERROR_MALFORMED);
reply->post();
diff --git a/media/libstagefright/rtsp/ARawAudioAssembler.cpp b/media/libstagefright/rtsp/ARawAudioAssembler.cpp
index 0da5dd2..167f7a4 100644
--- a/media/libstagefright/rtsp/ARawAudioAssembler.cpp
+++ b/media/libstagefright/rtsp/ARawAudioAssembler.cpp
@@ -34,7 +34,9 @@
namespace android {
ARawAudioAssembler::ARawAudioAssembler(
- const sp<AMessage> &notify, const char *desc, const AString &params)
+ const sp<AMessage> &notify,
+ const char * /* desc */,
+ const AString & /* params */)
: mNotifyMsg(notify),
mNextExpectedSeqNoValid(false),
mNextExpectedSeqNo(0) {
diff --git a/media/libstagefright/rtsp/Android.mk b/media/libstagefright/rtsp/Android.mk
index e77c69c..36e8d82 100644
--- a/media/libstagefright/rtsp/Android.mk
+++ b/media/libstagefright/rtsp/Android.mk
@@ -30,6 +30,8 @@ ifeq ($(TARGET_ARCH),arm)
LOCAL_CFLAGS += -Wno-psabi
endif
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+
include $(BUILD_STATIC_LIBRARY)
################################################################################
@@ -55,4 +57,6 @@ LOCAL_MODULE_TAGS := optional
LOCAL_MODULE:= rtp_test
+LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
+
# include $(BUILD_EXECUTABLE)
diff --git a/media/libstagefright/rtsp/MyHandler.h b/media/libstagefright/rtsp/MyHandler.h
index cd77aa0..e7580c2 100644
--- a/media/libstagefright/rtsp/MyHandler.h
+++ b/media/libstagefright/rtsp/MyHandler.h
@@ -149,7 +149,7 @@ struct MyHandler : public AHandler {
mSessionURL.append(StringPrintf("%u", port));
mSessionURL.append(path);
- ALOGI("rewritten session url: '%s'", mSessionURL.c_str());
+ ALOGV("rewritten session url: '%s'", mSessionURL.c_str());
}
mSessionHost = host;
@@ -478,21 +478,32 @@ struct MyHandler : public AHandler {
sp<ARTSPResponse> response =
static_cast<ARTSPResponse *>(obj.get());
- if (response->mStatusCode == 302) {
+ if (response->mStatusCode == 301 || response->mStatusCode == 302) {
ssize_t i = response->mHeaders.indexOfKey("location");
CHECK_GE(i, 0);
- mSessionURL = response->mHeaders.valueAt(i);
-
- AString request;
- request = "DESCRIBE ";
- request.append(mSessionURL);
- request.append(" RTSP/1.0\r\n");
- request.append("Accept: application/sdp\r\n");
- request.append("\r\n");
+ mOriginalSessionURL = response->mHeaders.valueAt(i);
+ mSessionURL = mOriginalSessionURL;
+
+ // Strip any authentication info from the session url, we don't
+ // want to transmit user/pass in cleartext.
+ AString host, path, user, pass;
+ unsigned port;
+ if (ARTSPConnection::ParseURL(
+ mSessionURL.c_str(), &host, &port, &path, &user, &pass)
+ && user.size() > 0) {
+ mSessionURL.clear();
+ mSessionURL.append("rtsp://");
+ mSessionURL.append(host);
+ mSessionURL.append(":");
+ mSessionURL.append(StringPrintf("%u", port));
+ mSessionURL.append(path);
+
+ ALOGI("rewritten session url: '%s'", mSessionURL.c_str());
+ }
- sp<AMessage> reply = new AMessage('desc', id());
- mConn->sendRequest(request.c_str(), reply);
+ sp<AMessage> reply = new AMessage('conn', id());
+ mConn->connect(mOriginalSessionURL.c_str(), reply);
break;
}
diff --git a/media/libstagefright/rtsp/SDPLoader.cpp b/media/libstagefright/rtsp/SDPLoader.cpp
index ed3fa7e..89ff17d 100644
--- a/media/libstagefright/rtsp/SDPLoader.cpp
+++ b/media/libstagefright/rtsp/SDPLoader.cpp
@@ -95,7 +95,7 @@ void SDPLoader::onLoad(const sp<AMessage> &msg) {
msg->findPointer("headers", (void **)&headers);
if (!(mFlags & kFlagIncognito)) {
- ALOGI("onLoad '%s'", url.c_str());
+ ALOGV("onLoad '%s'", url.c_str());
} else {
ALOGI("onLoad <URL suppressed>");
}
@@ -130,7 +130,7 @@ void SDPLoader::onLoad(const sp<AMessage> &msg) {
ssize_t readSize = mHTTPDataSource->readAt(0, buffer->data(), sdpSize);
if (readSize < 0) {
- ALOGE("Failed to read SDP, error code = %ld", readSize);
+ ALOGE("Failed to read SDP, error code = %zu", readSize);
err = UNKNOWN_ERROR;
} else {
desc = new ASessionDescription;
diff --git a/media/libstagefright/tests/Android.mk b/media/libstagefright/tests/Android.mk
index 06ce16b..903af49 100644
--- a/media/libstagefright/tests/Android.mk
+++ b/media/libstagefright/tests/Android.mk
@@ -41,6 +41,8 @@ LOCAL_C_INCLUDES := \
frameworks/av/media/libstagefright/include \
$(TOP)/frameworks/native/include/media/openmax \
+LOCAL_32_BIT_ONLY := true
+
include $(BUILD_EXECUTABLE)
endif
diff --git a/media/libstagefright/tests/DummyRecorder.cpp b/media/libstagefright/tests/DummyRecorder.cpp
index ac37b28..8f17088 100644
--- a/media/libstagefright/tests/DummyRecorder.cpp
+++ b/media/libstagefright/tests/DummyRecorder.cpp
@@ -61,7 +61,7 @@ status_t DummyRecorder::stop() {
mSource->stop();
void *dummy;
pthread_join(mThread, &dummy);
- status_t err = (status_t) dummy;
+ status_t err = static_cast<status_t>(reinterpret_cast<uintptr_t>(dummy));
ALOGV("Ending the reading thread");
return err;
diff --git a/media/libstagefright/timedtext/Android.mk b/media/libstagefright/timedtext/Android.mk
index f099bbd..6a8b9fc 100644
--- a/media/libstagefright/timedtext/Android.mk
+++ b/media/libstagefright/timedtext/Android.mk
@@ -9,7 +9,8 @@ LOCAL_SRC_FILES:= \
TimedTextSRTSource.cpp \
TimedTextPlayer.cpp
-LOCAL_CFLAGS += -Wno-multichar
+LOCAL_CFLAGS += -Wno-multichar -Werror
+
LOCAL_C_INCLUDES:= \
$(TOP)/frameworks/av/include/media/stagefright/timedtext \
$(TOP)/frameworks/av/media/libstagefright
diff --git a/media/libstagefright/timedtext/TimedTextPlayer.cpp b/media/libstagefright/timedtext/TimedTextPlayer.cpp
index 9fb0afe..a070487 100644
--- a/media/libstagefright/timedtext/TimedTextPlayer.cpp
+++ b/media/libstagefright/timedtext/TimedTextPlayer.cpp
@@ -18,6 +18,7 @@
#define LOG_TAG "TimedTextPlayer"
#include <utils/Log.h>
+#include <inttypes.h>
#include <limits.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
@@ -271,7 +272,7 @@ int64_t TimedTextPlayer::delayUsFromCurrentTime(int64_t fireTimeUs) {
sp<MediaPlayerBase> listener = mListener.promote();
if (listener == NULL) {
// TODO: it may be better to return kInvalidTimeUs
- ALOGE("%s: Listener is NULL. (fireTimeUs = %lld)",
+ ALOGE("%s: Listener is NULL. (fireTimeUs = %" PRId64" )",
__FUNCTION__, fireTimeUs);
return 0;
}
diff --git a/media/libstagefright/timedtext/TimedTextSource.h b/media/libstagefright/timedtext/TimedTextSource.h
index 756cc31..8c1c1cd 100644
--- a/media/libstagefright/timedtext/TimedTextSource.h
+++ b/media/libstagefright/timedtext/TimedTextSource.h
@@ -47,7 +47,7 @@ class TimedTextSource : public RefBase {
int64_t *endTimeUs,
Parcel *parcel,
const MediaSource::ReadOptions *options = NULL) = 0;
- virtual status_t extractGlobalDescriptions(Parcel *parcel) {
+ virtual status_t extractGlobalDescriptions(Parcel * /* parcel */) {
return INVALID_OPERATION;
}
virtual sp<MetaData> getFormat();
diff --git a/media/libstagefright/wifi-display/rtp/RTPSender.cpp b/media/libstagefright/wifi-display/rtp/RTPSender.cpp
index 1887b8b..e88a3bd 100644
--- a/media/libstagefright/wifi-display/rtp/RTPSender.cpp
+++ b/media/libstagefright/wifi-display/rtp/RTPSender.cpp
@@ -685,9 +685,8 @@ status_t RTPSender::onRTCPData(const sp<ABuffer> &buffer) {
return OK;
}
-status_t RTPSender::parseReceiverReport(const uint8_t *data, size_t size) {
- // hexdump(data, size);
-
+status_t RTPSender::parseReceiverReport(
+ const uint8_t *data, size_t /* size */) {
float fractionLost = data[12] / 256.0f;
ALOGI("lost %.2f %% of packets during report interval.",
diff --git a/media/libstagefright/wifi-display/source/TSPacketizer.cpp b/media/libstagefright/wifi-display/source/TSPacketizer.cpp
index c674700..50d317a 100644
--- a/media/libstagefright/wifi-display/source/TSPacketizer.cpp
+++ b/media/libstagefright/wifi-display/source/TSPacketizer.cpp
@@ -216,7 +216,7 @@ sp<ABuffer> TSPacketizer::Track::prependADTSHeader(
uint8_t *ptr = dup->data();
*ptr++ = 0xff;
- *ptr++ = 0xf1; // b11110001, ID=0, layer=0, protection_absent=1
+ *ptr++ = 0xf9; // b11111001, ID=1(MPEG-2), layer=0, protection_absent=1
*ptr++ =
profile << 6
@@ -565,7 +565,7 @@ status_t TSPacketizer::packetize(
}
}
- // size_t numPaddingBytes = sizeAvailableForPayload - numBytesOfPayload;
+ size_t numPaddingBytes = sizeAvailableForPayload - numBytesOfPayload;
ALOGV("packet 1 contains %zd padding bytes and %zd bytes of payload",
numPaddingBytes, numBytesOfPayload);
diff --git a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
index 05e4018..da405e2 100644
--- a/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
+++ b/media/libstagefright/wifi-display/source/WifiDisplaySource.cpp
@@ -746,7 +746,7 @@ status_t WifiDisplaySource::sendM16(int32_t sessionID) {
}
status_t WifiDisplaySource::onReceiveM1Response(
- int32_t sessionID, const sp<ParsedMessage> &msg) {
+ int32_t /* sessionID */, const sp<ParsedMessage> &msg) {
int32_t statusCode;
if (!msg->getStatusCode(&statusCode)) {
return ERROR_MALFORMED;
@@ -991,7 +991,7 @@ status_t WifiDisplaySource::onReceiveM4Response(
}
status_t WifiDisplaySource::onReceiveM5Response(
- int32_t sessionID, const sp<ParsedMessage> &msg) {
+ int32_t /* sessionID */, const sp<ParsedMessage> &msg) {
int32_t statusCode;
if (!msg->getStatusCode(&statusCode)) {
return ERROR_MALFORMED;
@@ -1005,7 +1005,7 @@ status_t WifiDisplaySource::onReceiveM5Response(
}
status_t WifiDisplaySource::onReceiveM16Response(
- int32_t sessionID, const sp<ParsedMessage> &msg) {
+ int32_t sessionID, const sp<ParsedMessage> & /* msg */) {
// If only the response was required to include a "Session:" header...
CHECK_EQ(sessionID, mClientSessionID);
@@ -1680,7 +1680,7 @@ WifiDisplaySource::HDCPObserver::HDCPObserver(
}
void WifiDisplaySource::HDCPObserver::notify(
- int msg, int ext1, int ext2, const Parcel *obj) {
+ int msg, int ext1, int ext2, const Parcel * /* obj */) {
sp<AMessage> notify = mNotify->dup();
notify->setInt32("msg", msg);
notify->setInt32("ext1", ext1);
diff --git a/media/mediaserver/Android.mk b/media/mediaserver/Android.mk
index 1ac647a..d07bc99 100644
--- a/media/mediaserver/Android.mk
+++ b/media/mediaserver/Android.mk
@@ -35,5 +35,6 @@ LOCAL_C_INCLUDES := \
frameworks/av/services/camera/libcameraservice
LOCAL_MODULE:= mediaserver
+LOCAL_32_BIT_ONLY := true
include $(BUILD_EXECUTABLE)
diff --git a/media/mtp/Android.mk b/media/mtp/Android.mk
index ac608a1..3af0956 100644
--- a/media/mtp/Android.mk
+++ b/media/mtp/Android.mk
@@ -39,9 +39,6 @@ LOCAL_MODULE:= libmtp
LOCAL_CFLAGS := -DMTP_DEVICE -DMTP_HOST
-# Needed for <bionic_time.h>
-LOCAL_C_INCLUDES := bionic/libc/private
-
LOCAL_SHARED_LIBRARIES := libutils libcutils liblog libusbhost libbinder
include $(BUILD_SHARED_LIBRARY)
diff --git a/media/mtp/MtpDataPacket.cpp b/media/mtp/MtpDataPacket.cpp
index 930f0b0..e6e19e3 100644
--- a/media/mtp/MtpDataPacket.cpp
+++ b/media/mtp/MtpDataPacket.cpp
@@ -331,7 +331,7 @@ void MtpDataPacket::putString(const char* s) {
void MtpDataPacket::putString(const uint16_t* string) {
int count = 0;
- for (int i = 0; i < 256; i++) {
+ for (int i = 0; i <= MTP_STRING_MAX_CHARACTER_NUMBER; i++) {
if (string[i])
count++;
else
@@ -363,7 +363,7 @@ int MtpDataPacket::write(int fd) {
}
int MtpDataPacket::writeData(int fd, void* data, uint32_t length) {
- allocate(length);
+ allocate(length + MTP_CONTAINER_HEADER_SIZE);
memcpy(mBuffer + MTP_CONTAINER_HEADER_SIZE, data, length);
length += MTP_CONTAINER_HEADER_SIZE;
MtpPacket::putUInt32(MTP_CONTAINER_LENGTH_OFFSET, length);
diff --git a/media/mtp/MtpDevice.cpp b/media/mtp/MtpDevice.cpp
index d672dff..d6d5dd5 100644
--- a/media/mtp/MtpDevice.cpp
+++ b/media/mtp/MtpDevice.cpp
@@ -195,7 +195,7 @@ MtpDevice::MtpDevice(struct usb_device* device, int interface,
MtpDevice::~MtpDevice() {
close();
- for (int i = 0; i < mDeviceProperties.size(); i++)
+ for (size_t i = 0; i < mDeviceProperties.size(); i++)
delete mDeviceProperties[i];
usb_request_free(mRequestIn1);
usb_request_free(mRequestIn2);
@@ -253,7 +253,7 @@ void MtpDevice::print() {
ALOGI("*** FORMAT: %s\n", MtpDebug::getFormatCodeName(format));
MtpObjectPropertyList* props = getObjectPropsSupported(format);
if (props) {
- for (int j = 0; j < props->size(); j++) {
+ for (size_t j = 0; j < props->size(); j++) {
MtpObjectProperty prop = (*props)[j];
MtpProperty* property = getObjectPropDesc(prop, format);
if (property) {
diff --git a/media/mtp/MtpProperty.cpp b/media/mtp/MtpProperty.cpp
index 64dd45b..375ed9a 100644
--- a/media/mtp/MtpProperty.cpp
+++ b/media/mtp/MtpProperty.cpp
@@ -16,6 +16,7 @@
#define LOG_TAG "MtpProperty"
+#include <inttypes.h>
#include "MtpDataPacket.h"
#include "MtpDebug.h"
#include "MtpProperty.h"
@@ -385,10 +386,10 @@ void MtpProperty::print(MtpPropertyValue& value, MtpString& buffer) {
buffer.appendFormat("%d", value.u.u32);
break;
case MTP_TYPE_INT64:
- buffer.appendFormat("%lld", value.u.i64);
+ buffer.appendFormat("%" PRId64, value.u.i64);
break;
case MTP_TYPE_UINT64:
- buffer.appendFormat("%lld", value.u.u64);
+ buffer.appendFormat("%" PRIu64, value.u.u64);
break;
case MTP_TYPE_INT128:
buffer.appendFormat("%08X%08X%08X%08X", value.u.i128[0], value.u.i128[1],
diff --git a/media/mtp/MtpServer.cpp b/media/mtp/MtpServer.cpp
index df87db4..155f645 100644
--- a/media/mtp/MtpServer.cpp
+++ b/media/mtp/MtpServer.cpp
@@ -20,6 +20,7 @@
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <fcntl.h>
+#include <inttypes.h>
#include <errno.h>
#include <sys/stat.h>
#include <dirent.h>
@@ -124,7 +125,7 @@ void MtpServer::addStorage(MtpStorage* storage) {
void MtpServer::removeStorage(MtpStorage* storage) {
Mutex::Autolock autoLock(mMutex);
- for (int i = 0; i < mStorages.size(); i++) {
+ for (size_t i = 0; i < mStorages.size(); i++) {
if (mStorages[i] == storage) {
mStorages.removeAt(i);
sendStoreRemoved(storage->getStorageID());
@@ -136,7 +137,7 @@ void MtpServer::removeStorage(MtpStorage* storage) {
MtpStorage* MtpServer::getStorage(MtpStorageID id) {
if (id == 0)
return mStorages[0];
- for (int i = 0; i < mStorages.size(); i++) {
+ for (size_t i = 0; i < mStorages.size(); i++) {
MtpStorage* storage = mStorages[i];
if (storage->getStorageID() == id)
return storage;
@@ -1110,7 +1111,7 @@ MtpResponseCode MtpServer::doSendPartialObject() {
}
const char* filePath = (const char *)edit->mPath;
- ALOGV("receiving partial %s %lld %lld\n", filePath, offset, length);
+ ALOGV("receiving partial %s %lld %" PRIu32 "\n", filePath, offset, length);
// read the header, and possibly some data
int ret = mData.read(mFD);
diff --git a/media/mtp/MtpStringBuffer.cpp b/media/mtp/MtpStringBuffer.cpp
index fe8cf04..f3420a4 100644
--- a/media/mtp/MtpStringBuffer.cpp
+++ b/media/mtp/MtpStringBuffer.cpp
@@ -56,42 +56,47 @@ MtpStringBuffer::~MtpStringBuffer() {
}
void MtpStringBuffer::set(const char* src) {
- int length = strlen(src);
- if (length >= sizeof(mBuffer))
- length = sizeof(mBuffer) - 1;
- memcpy(mBuffer, src, length);
-
// count the characters
int count = 0;
char ch;
- while ((ch = *src++) != 0) {
+ char* dest = (char*)mBuffer;
+
+ while ((ch = *src++) != 0 && count < MTP_STRING_MAX_CHARACTER_NUMBER) {
if ((ch & 0x80) == 0) {
// single byte character
+ *dest++ = ch;
} else if ((ch & 0xE0) == 0xC0) {
// two byte character
- if (! *src++) {
+ char ch1 = *src++;
+ if (! ch1) {
// last character was truncated, so ignore last byte
- length--;
break;
}
+
+ *dest++ = ch;
+ *dest++ = ch1;
} else if ((ch & 0xF0) == 0xE0) {
// 3 byte char
- if (! *src++) {
+ char ch1 = *src++;
+ if (! ch1) {
// last character was truncated, so ignore last byte
- length--;
break;
}
- if (! *src++) {
- // last character was truncated, so ignore last two bytes
- length -= 2;
+ char ch2 = *src++;
+ if (! ch2) {
+ // last character was truncated, so ignore last byte
break;
}
+
+ *dest++ = ch;
+ *dest++ = ch1;
+ *dest++ = ch2;
}
count++;
}
- mByteCount = length + 1;
- mBuffer[length] = 0;
+ *dest++ = 0;
+ mByteCount = dest - (char*)mBuffer;
mCharCount = count;
}
@@ -100,7 +105,7 @@ void MtpStringBuffer::set(const uint16_t* src) {
uint16_t ch;
uint8_t* dest = mBuffer;
- while ((ch = *src++) != 0 && count < 255) {
+ while ((ch = *src++) != 0 && count < MTP_STRING_MAX_CHARACTER_NUMBER) {
if (ch >= 0x0800) {
*dest++ = (uint8_t)(0xE0 | (ch >> 12));
*dest++ = (uint8_t)(0x80 | ((ch >> 6) & 0x3F));
diff --git a/media/mtp/MtpStringBuffer.h b/media/mtp/MtpStringBuffer.h
index cbc8307..e5150df 100644
--- a/media/mtp/MtpStringBuffer.h
+++ b/media/mtp/MtpStringBuffer.h
@@ -19,6 +19,9 @@
#include <stdint.h>
+// Max Character number of a MTP String
+#define MTP_STRING_MAX_CHARACTER_NUMBER 255
+
namespace android {
class MtpDataPacket;
@@ -29,7 +32,7 @@ class MtpStringBuffer {
private:
// mBuffer contains string in UTF8 format
// maximum 3 bytes/character, with 1 extra for zero termination
- uint8_t mBuffer[255 * 3 + 1];
+ uint8_t mBuffer[MTP_STRING_MAX_CHARACTER_NUMBER * 3 + 1];
int mCharCount;
int mByteCount;
diff --git a/media/mtp/MtpUtils.cpp b/media/mtp/MtpUtils.cpp
index 6ec8876..0667bdd 100644
--- a/media/mtp/MtpUtils.cpp
+++ b/media/mtp/MtpUtils.cpp
@@ -19,7 +19,8 @@
#include <stdio.h>
#include <time.h>
-#include <cutils/tztime.h>
+#include <../private/bionic_time.h> /* TODO: switch this code to icu4c! */
+
#include "MtpUtils.h"
namespace android {
diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk
index 54377f1..b895027 100644
--- a/services/audioflinger/Android.mk
+++ b/services/audioflinger/Android.mk
@@ -19,11 +19,8 @@ LOCAL_SRC_FILES:= \
Tracks.cpp \
Effects.cpp \
AudioMixer.cpp.arm \
- AudioResampler.cpp.arm \
AudioPolicyService.cpp \
ServiceUtilities.cpp \
- AudioResamplerCubic.cpp.arm \
- AudioResamplerSinc.cpp.arm
LOCAL_SRC_FILES += StateQueue.cpp
@@ -32,6 +29,7 @@ LOCAL_C_INCLUDES := \
$(call include-path-for, audio-utils)
LOCAL_SHARED_LIBRARIES := \
+ libaudioresampler \
libaudioutils \
libcommon_time_client \
libcutils \
@@ -43,7 +41,6 @@ LOCAL_SHARED_LIBRARIES := \
libhardware \
libhardware_legacy \
libeffects \
- libdl \
libpowermanager
LOCAL_STATIC_LIBRARIES := \
@@ -52,6 +49,7 @@ LOCAL_STATIC_LIBRARIES := \
libmedia_helper
LOCAL_MODULE:= libaudioflinger
+LOCAL_32_BIT_ONLY := true
LOCAL_SRC_FILES += FastMixer.cpp FastMixerState.cpp AudioWatchdog.cpp
@@ -75,15 +73,9 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
test-resample.cpp \
- AudioResampler.cpp.arm \
- AudioResamplerCubic.cpp.arm \
- AudioResamplerSinc.cpp.arm
LOCAL_SHARED_LIBRARIES := \
- libdl \
- libcutils \
- libutils \
- liblog
+ libaudioresampler \
LOCAL_MODULE:= test-resample
@@ -91,4 +83,20 @@ LOCAL_MODULE_TAGS := optional
include $(BUILD_EXECUTABLE)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+ AudioResampler.cpp.arm \
+ AudioResamplerCubic.cpp.arm \
+ AudioResamplerSinc.cpp.arm
+
+LOCAL_SHARED_LIBRARIES := \
+ libcutils \
+ libdl \
+ liblog
+
+LOCAL_MODULE := libaudioresampler
+
+include $(BUILD_SHARED_LIBRARY)
+
include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 3132e54..33b19a4 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -379,7 +379,7 @@ status_t AudioFlinger::dump(int fd, const Vector<String16>& args)
if (mLogMemoryDealer != 0) {
sp<IBinder> binder = defaultServiceManager()->getService(String16("media.log"));
if (binder != 0) {
- fdprintf(fd, "\nmedia.log:\n");
+ dprintf(fd, "\nmedia.log:\n");
Vector<String16> args;
binder->dump(fd, args);
}
@@ -513,6 +513,8 @@ sp<IAudioTrack> AudioFlinger::createTrack(
track = thread->createTrack_l(client, streamType, sampleRate, format,
channelMask, frameCount, sharedBuffer, lSessionId, flags, tid, clientUid, &lStatus);
+ LOG_ALWAYS_FATAL_IF((lStatus == NO_ERROR) && (track == 0));
+ // we don't abort yet if lStatus != NO_ERROR; there is still work to be done regardless
// move effect chain to this output thread if an effect on same session was waiting
// for a track to be created
@@ -523,7 +525,7 @@ sp<IAudioTrack> AudioFlinger::createTrack(
}
// Look for sync events awaiting for a session to be used.
- for (int i = 0; i < (int)mPendingSyncEvents.size(); i++) {
+ for (size_t i = 0; i < mPendingSyncEvents.size(); i++) {
if (mPendingSyncEvents[i]->triggerSession() == lSessionId) {
if (thread->isValidSyncEvent(mPendingSyncEvents[i])) {
if (lStatus == NO_ERROR) {
@@ -829,7 +831,7 @@ status_t AudioFlinger::setStreamMute(audio_stream_type_t stream, bool muted)
AutoMutex lock(mLock);
mStreamTypes[stream].mute = muted;
- for (uint32_t i = 0; i < mPlaybackThreads.size(); i++)
+ for (size_t i = 0; i < mPlaybackThreads.size(); i++)
mPlaybackThreads.valueAt(i)->setStreamMute(stream, muted);
return NO_ERROR;
@@ -1010,7 +1012,7 @@ size_t AudioFlinger::getInputBufferSize(uint32_t sampleRate, audio_format_t form
return size;
}
-unsigned int AudioFlinger::getInputFramesLost(audio_io_handle_t ioHandle) const
+uint32_t AudioFlinger::getInputFramesLost(audio_io_handle_t ioHandle) const
{
Mutex::Autolock _l(mLock);
@@ -1042,7 +1044,7 @@ status_t AudioFlinger::setVoiceVolume(float value)
return ret;
}
-status_t AudioFlinger::getRenderPosition(size_t *halFrames, size_t *dspFrames,
+status_t AudioFlinger::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames,
audio_io_handle_t output) const
{
status_t status;
@@ -1291,7 +1293,7 @@ sp<IAudioRecord> AudioFlinger::openRecord(
frameCount, lSessionId,
IPCThreadState::self()->getCallingUid(),
flags, tid, &lStatus);
- LOG_ALWAYS_FATAL_IF((recordTrack != 0) != (lStatus == NO_ERROR));
+ LOG_ALWAYS_FATAL_IF((lStatus == NO_ERROR) && (recordTrack == 0));
}
if (lStatus != NO_ERROR) {
// remove local strong reference to Client before deleting the RecordTrack so that the
@@ -2458,7 +2460,7 @@ void AudioFlinger::dumpTee(int fd, const sp<NBAIO_Source>& source, audio_io_hand
}
} else {
if (fd >= 0) {
- fdprintf(fd, "unable to rotate tees in %s: %s\n", teePath, strerror(errno));
+ dprintf(fd, "unable to rotate tees in %s: %s\n", teePath, strerror(errno));
}
}
char teeTime[16];
@@ -2512,11 +2514,11 @@ void AudioFlinger::dumpTee(int fd, const sp<NBAIO_Source>& source, audio_io_hand
write(teeFd, &temp, sizeof(temp));
close(teeFd);
if (fd >= 0) {
- fdprintf(fd, "tee copied to %s\n", teePath);
+ dprintf(fd, "tee copied to %s\n", teePath);
}
} else {
if (fd >= 0) {
- fdprintf(fd, "unable to create tee %s: %s\n", teePath, strerror(errno));
+ dprintf(fd, "unable to create tee %s: %s\n", teePath, strerror(errno));
}
}
}
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index 53e238e..7320144 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -186,10 +186,10 @@ public:
virtual status_t setVoiceVolume(float volume);
- virtual status_t getRenderPosition(size_t *halFrames, size_t *dspFrames,
+ virtual status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames,
audio_io_handle_t output) const;
- virtual unsigned int getInputFramesLost(audio_io_handle_t ioHandle) const;
+ virtual uint32_t getInputFramesLost(audio_io_handle_t ioHandle) const;
virtual int newAudioSessionId();
diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp
index df4e029..f92421e 100644
--- a/services/audioflinger/AudioMixer.cpp
+++ b/services/audioflinger/AudioMixer.cpp
@@ -421,15 +421,16 @@ void AudioMixer::setParameter(int name, int target, int param, void *value)
ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name);
track_t& track = mState.tracks[name];
- int valueInt = (int)value;
- int32_t *valueBuf = (int32_t *)value;
+ int valueInt = static_cast<int>(reinterpret_cast<uintptr_t>(value));
+ int32_t *valueBuf = reinterpret_cast<int32_t*>(value);
switch (target) {
case TRACK:
switch (param) {
case CHANNEL_MASK: {
- audio_channel_mask_t mask = (audio_channel_mask_t) value;
+ audio_channel_mask_t mask =
+ static_cast<audio_channel_mask_t>(reinterpret_cast<uintptr_t>(value));
if (track.channelMask != mask) {
uint32_t channelCount = popcount(mask);
ALOG_ASSERT((channelCount <= MAX_NUM_CHANNELS_TO_DOWNMIX) && channelCount);
@@ -1122,10 +1123,6 @@ void AudioMixer::process__genericNoResampling(state_t* state, int64_t pts)
t.bufferProvider->getNextBuffer(&t.buffer, pts);
t.frameCount = t.buffer.frameCount;
t.in = t.buffer.raw;
- // t.in == NULL can happen if the track was flushed just after having
- // been enabled for mixing.
- if (t.in == NULL)
- enabledTracks &= ~(1<<i);
}
e0 = enabledTracks;
@@ -1161,6 +1158,13 @@ void AudioMixer::process__genericNoResampling(state_t* state, int64_t pts)
aux = t.auxBuffer + numFrames;
}
while (outFrames) {
+ // t.in == NULL can happen if the track was flushed just after having
+ // been enabled for mixing.
+ if (t.in == NULL) {
+ enabledTracks &= ~(1<<i);
+ e1 &= ~(1<<i);
+ break;
+ }
size_t inFrames = (t.frameCount > outFrames)?outFrames:t.frameCount;
if (inFrames) {
t.hook(&t, outTemp + (BLOCKSIZE-outFrames)*MAX_NUM_CHANNELS, inFrames,
diff --git a/services/audioflinger/AudioPolicyService.cpp b/services/audioflinger/AudioPolicyService.cpp
index 35e816b..6ea5324 100644
--- a/services/audioflinger/AudioPolicyService.cpp
+++ b/services/audioflinger/AudioPolicyService.cpp
@@ -678,6 +678,10 @@ AudioPolicyService::AudioCommandThread::~AudioCommandThread()
if (!mAudioCommands.isEmpty()) {
release_wake_lock(mName.string());
}
+ for (size_t k=0; k < mAudioCommands.size(); k++) {
+ delete mAudioCommands[k]->mParam;
+ delete mAudioCommands[k];
+ }
mAudioCommands.clear();
delete mpToneGenerator;
}
@@ -849,7 +853,7 @@ void AudioPolicyService::AudioCommandThread::startToneCommand(ToneGenerator::ton
ToneData *data = new ToneData();
data->mType = type;
data->mStream = stream;
- command->mParam = (void *)data;
+ command->mParam = data;
Mutex::Autolock _l(mLock);
insertCommand_l(command);
ALOGV("AudioCommandThread() adding tone start type %d, stream %d", type, stream);
@@ -950,7 +954,7 @@ void AudioPolicyService::AudioCommandThread::stopOutputCommand(audio_io_handle_t
data->mIO = output;
data->mStream = stream;
data->mSession = session;
- command->mParam = (void *)data;
+ command->mParam = data;
Mutex::Autolock _l(mLock);
insertCommand_l(command);
ALOGV("AudioCommandThread() adding stop output %d", output);
@@ -963,7 +967,7 @@ void AudioPolicyService::AudioCommandThread::releaseOutputCommand(audio_io_handl
command->mCommand = RELEASE_OUTPUT;
ReleaseOutputData *data = new ReleaseOutputData();
data->mIO = output;
- command->mParam = (void *)data;
+ command->mParam = data;
Mutex::Autolock _l(mLock);
insertCommand_l(command);
ALOGV("AudioCommandThread() adding release output %d", output);
@@ -1052,6 +1056,10 @@ void AudioPolicyService::AudioCommandThread::insertCommand_l(AudioCommand *comma
for (size_t k = i + 1; k < mAudioCommands.size(); k++) {
if (mAudioCommands[k] == removedCommands[j]) {
ALOGV("suppressing command: %d", mAudioCommands[k]->mCommand);
+ // for commands that are not filtered,
+ // command->mParam is deleted in threadLoop
+ delete mAudioCommands[k]->mParam;
+ delete mAudioCommands[k];
mAudioCommands.removeAt(k);
break;
}
@@ -1301,7 +1309,7 @@ effect_param_t *AudioPolicyService::loadEffectParameter(cnode *root)
return fx_param;
error:
- delete fx_param;
+ free(fx_param);
return NULL;
}
@@ -1433,6 +1441,14 @@ status_t AudioPolicyService::loadPreProcessorConfig(const char *path)
loadEffects(root, effects);
loadInputSources(root, effects);
+ // delete effects to fix memory leak.
+ // as effects is local var and valgrind would treat this as memory leak
+ // and although it only did in mediaserver init, but free it in case mediaserver reboot
+ size_t i;
+ for (i = 0; i < effects.size(); i++) {
+ delete effects[i];
+ }
+
config_free(root);
free(root);
free(data);
diff --git a/services/audioflinger/AudioPolicyService.h b/services/audioflinger/AudioPolicyService.h
index ae053a9..a38160f 100644
--- a/services/audioflinger/AudioPolicyService.h
+++ b/services/audioflinger/AudioPolicyService.h
@@ -197,6 +197,8 @@ private:
void insertCommand_l(AudioCommand *command, int delayMs = 0);
private:
+ class AudioCommandData;
+
// descriptor for requested tone playback event
class AudioCommand {
@@ -211,41 +213,48 @@ private:
Condition mCond; // condition for status return
status_t mStatus; // command status
bool mWaitStatus; // true if caller is waiting for status
- void *mParam; // command parameter (ToneData, VolumeData, ParametersData)
+ AudioCommandData *mParam; // command specific parameter data
+ };
+
+ class AudioCommandData {
+ public:
+ virtual ~AudioCommandData() {}
+ protected:
+ AudioCommandData() {}
};
- class ToneData {
+ class ToneData : public AudioCommandData {
public:
ToneGenerator::tone_type mType; // tone type (START_TONE only)
audio_stream_type_t mStream; // stream type (START_TONE only)
};
- class VolumeData {
+ class VolumeData : public AudioCommandData {
public:
audio_stream_type_t mStream;
float mVolume;
audio_io_handle_t mIO;
};
- class ParametersData {
+ class ParametersData : public AudioCommandData {
public:
audio_io_handle_t mIO;
String8 mKeyValuePairs;
};
- class VoiceVolumeData {
+ class VoiceVolumeData : public AudioCommandData {
public:
float mVolume;
};
- class StopOutputData {
+ class StopOutputData : public AudioCommandData {
public:
audio_io_handle_t mIO;
audio_stream_type_t mStream;
int mSession;
};
- class ReleaseOutputData {
+ class ReleaseOutputData : public AudioCommandData {
public:
audio_io_handle_t mIO;
};
diff --git a/services/audioflinger/AudioResamplerSinc.cpp b/services/audioflinger/AudioResamplerSinc.cpp
index 207f26b..e50b192 100644
--- a/services/audioflinger/AudioResamplerSinc.cpp
+++ b/services/audioflinger/AudioResamplerSinc.cpp
@@ -17,6 +17,7 @@
#define LOG_TAG "AudioResamplerSinc"
//#define LOG_NDEBUG 0
+#define __STDC_CONSTANT_MACROS
#include <malloc.h>
#include <string.h>
#include <stdlib.h>
@@ -37,12 +38,14 @@
#define USE_INLINE_ASSEMBLY (false)
#endif
-#if USE_INLINE_ASSEMBLY && defined(__ARM_NEON__)
-#define USE_NEON (true)
+#if defined(__aarch64__) || defined(__ARM_NEON__)
+#include <arm_neon.h>
+#define USE_NEON
#else
-#define USE_NEON (false)
+#undef USE_NEON
#endif
+#define UNUSED(x) ((void)(x))
namespace android {
// ----------------------------------------------------------------------------
@@ -634,8 +637,8 @@ void AudioResamplerSinc::read(
}
template<int CHANNELS>
-void AudioResamplerSinc::filterCoefficient(
- int32_t* out, uint32_t phase, const int16_t *samples, uint32_t vRL)
+void AudioResamplerSinc::filterCoefficient(int32_t* out, uint32_t phase,
+ const int16_t *samples, uint32_t vRL)
{
// NOTE: be very careful when modifying the code here. register
// pressure is very high and a small change might cause the compiler
@@ -662,160 +665,171 @@ void AudioResamplerSinc::filterCoefficient(
size_t count = offset;
- if (!USE_NEON) {
- int32_t l = 0;
- int32_t r = 0;
- for (size_t i=0 ; i<count ; i++) {
- interpolate<CHANNELS>(l, r, coefsP++, offset, lerpP, sP);
- sP -= CHANNELS;
- interpolate<CHANNELS>(l, r, coefsN++, offset, lerpN, sN);
- sN += CHANNELS;
- }
- out[0] += 2 * mulRL(1, l, vRL);
- out[1] += 2 * mulRL(0, r, vRL);
- } else if (CHANNELS == 1) {
+#ifndef USE_NEON
+ int32_t l = 0;
+ int32_t r = 0;
+ for (size_t i=0 ; i<count ; i++) {
+ interpolate<CHANNELS>(l, r, coefsP++, offset, lerpP, sP);
+ sP -= CHANNELS;
+ interpolate<CHANNELS>(l, r, coefsN++, offset, lerpN, sN);
+ sN += CHANNELS;
+ }
+ out[0] += 2 * mulRL(1, l, vRL);
+ out[1] += 2 * mulRL(0, r, vRL);
+#else
+ UNUSED(vRL);
+ if (CHANNELS == 1) {
int32_t const* coefsP1 = coefsP + offset;
int32_t const* coefsN1 = coefsN + offset;
sP -= CHANNELS*3;
- asm (
- "vmov.32 d2[0], %[lerpP] \n" // load the positive phase
- "vmov.32 d2[1], %[lerpN] \n" // load the negative phase
- "veor q0, q0, q0 \n" // result, initialize to 0
- "vshl.s32 d2, d2, #16 \n" // convert to 32 bits
-
- "1: \n"
- "vld1.16 { d4}, [%[sP]] \n" // load 4 16-bits stereo samples
- "vld1.32 { q8}, [%[coefsP0]:128]! \n" // load 4 32-bits coefs
- "vld1.32 { q9}, [%[coefsP1]:128]! \n" // load 4 32-bits coefs for interpolation
- "vld1.16 { d6}, [%[sN]]! \n" // load 4 16-bits stereo samples
- "vld1.32 {q10}, [%[coefsN0]:128]! \n" // load 4 32-bits coefs
- "vld1.32 {q11}, [%[coefsN1]:128]! \n" // load 4 32-bits coefs for interpolation
-
- "vrev64.16 d4, d4 \n" // reverse 2 frames of the positive side
-
- "vsub.s32 q9, q9, q8 \n" // interpolate (step1) 1st set of coefs
- "vsub.s32 q11, q11, q10 \n" // interpolate (step1) 2nd set of coets
- "vshll.s16 q12, d4, #15 \n" // extend samples to 31 bits
-
- "vqrdmulh.s32 q9, q9, d2[0] \n" // interpolate (step2) 1st set of coefs
- "vqrdmulh.s32 q11, q11, d2[1] \n" // interpolate (step3) 2nd set of coefs
- "vshll.s16 q14, d6, #15 \n" // extend samples to 31 bits
-
- "vadd.s32 q8, q8, q9 \n" // interpolate (step3) 1st set
- "vadd.s32 q10, q10, q11 \n" // interpolate (step4) 2nd set
- "subs %[count], %[count], #4 \n" // update loop counter
-
- "vqrdmulh.s32 q12, q12, q8 \n" // multiply samples by interpolated coef
- "vqrdmulh.s32 q14, q14, q10 \n" // multiply samples by interpolated coef
- "sub %[sP], %[sP], #8 \n" // move pointer to next set of samples
-
- "vadd.s32 q0, q0, q12 \n" // accumulate result
- "vadd.s32 q0, q0, q14 \n" // accumulate result
-
- "bne 1b \n" // loop
-
- "vld1.s32 {d2}, [%[vLR]] \n" // load volumes
- "vld1.s32 {d3}, %[out] \n" // load the output
- "vpadd.s32 d0, d0, d1 \n" // add all 4 partial sums
- "vpadd.s32 d0, d0, d0 \n" // together
- "vdup.i32 d0, d0[0] \n" // interleave L,R channels
- "vqrdmulh.s32 d0, d0, d2 \n" // apply volume
- "vadd.s32 d3, d3, d0 \n" // accumulate result
- "vst1.s32 {d3}, %[out] \n" // store result
-
- : [out] "=Uv" (out[0]),
- [count] "+r" (count),
- [coefsP0] "+r" (coefsP),
- [coefsP1] "+r" (coefsP1),
- [coefsN0] "+r" (coefsN),
- [coefsN1] "+r" (coefsN1),
- [sP] "+r" (sP),
- [sN] "+r" (sN)
- : [lerpP] "r" (lerpP),
- [lerpN] "r" (lerpN),
- [vLR] "r" (mVolumeSIMD)
- : "cc", "memory",
- "q0", "q1", "q2", "q3",
- "q8", "q9", "q10", "q11",
- "q12", "q14"
- );
+
+ int32x4_t sum;
+ int32x2_t lerpPN;
+ lerpPN = vdup_n_s32(0);
+ lerpPN = vld1_lane_s32((int32_t *)&lerpP, lerpPN, 0);
+ lerpPN = vld1_lane_s32((int32_t *)&lerpN, lerpPN, 1);
+ lerpPN = vshl_n_s32(lerpPN, 16);
+ sum = vdupq_n_s32(0);
+
+ int16x4_t sampleP, sampleN;
+ int32x4_t samplePExt, sampleNExt;
+ int32x4_t coefsPV0, coefsPV1, coefsNV0, coefsNV1;
+
+ coefsP = (const int32_t*)__builtin_assume_aligned(coefsP, 16);
+ coefsN = (const int32_t*)__builtin_assume_aligned(coefsN, 16);
+ coefsP1 = (const int32_t*)__builtin_assume_aligned(coefsP1, 16);
+ coefsN1 = (const int32_t*)__builtin_assume_aligned(coefsN1, 16);
+ for (; count > 0; count -= 4) {
+ sampleP = vld1_s16(sP);
+ sampleN = vld1_s16(sN);
+ coefsPV0 = vld1q_s32(coefsP);
+ coefsNV0 = vld1q_s32(coefsN);
+ coefsPV1 = vld1q_s32(coefsP1);
+ coefsNV1 = vld1q_s32(coefsN1);
+ sP -= 4;
+ sN += 4;
+ coefsP += 4;
+ coefsN += 4;
+ coefsP1 += 4;
+ coefsN1 += 4;
+
+ sampleP = vrev64_s16(sampleP);
+
+ // interpolate (step1)
+ coefsPV1 = vsubq_s32(coefsPV1, coefsPV0);
+ coefsNV1 = vsubq_s32(coefsNV1, coefsNV0);
+ samplePExt = vshll_n_s16(sampleP, 15);
+ // interpolate (step2)
+ coefsPV1 = vqrdmulhq_lane_s32(coefsPV1, lerpPN, 0);
+ coefsNV1 = vqrdmulhq_lane_s32(coefsNV1, lerpPN, 1);
+ sampleNExt = vshll_n_s16(sampleN, 15);
+ // interpolate (step3)
+ coefsPV0 = vaddq_s32(coefsPV0, coefsPV1);
+ coefsNV0 = vaddq_s32(coefsNV0, coefsNV1);
+
+ samplePExt = vqrdmulhq_s32(samplePExt, coefsPV0);
+ sampleNExt = vqrdmulhq_s32(sampleNExt, coefsNV0);
+ sum = vaddq_s32(sum, samplePExt);
+ sum = vaddq_s32(sum, sampleNExt);
+ }
+ int32x2_t volumesV, outV;
+ volumesV = vld1_s32(mVolumeSIMD);
+ outV = vld1_s32(out);
+
+ //add all 4 partial sums
+ int32x2_t sumLow, sumHigh;
+ sumLow = vget_low_s32(sum);
+ sumHigh = vget_high_s32(sum);
+ sumLow = vpadd_s32(sumLow, sumHigh);
+ sumLow = vpadd_s32(sumLow, sumLow);
+
+ sumLow = vqrdmulh_s32(sumLow, volumesV);
+ outV = vadd_s32(outV, sumLow);
+ vst1_s32(out, outV);
} else if (CHANNELS == 2) {
int32_t const* coefsP1 = coefsP + offset;
int32_t const* coefsN1 = coefsN + offset;
sP -= CHANNELS*3;
- asm (
- "vmov.32 d2[0], %[lerpP] \n" // load the positive phase
- "vmov.32 d2[1], %[lerpN] \n" // load the negative phase
- "veor q0, q0, q0 \n" // result, initialize to 0
- "veor q4, q4, q4 \n" // result, initialize to 0
- "vshl.s32 d2, d2, #16 \n" // convert to 32 bits
-
- "1: \n"
- "vld2.16 {d4,d5}, [%[sP]] \n" // load 4 16-bits stereo samples
- "vld1.32 { q8}, [%[coefsP0]:128]! \n" // load 4 32-bits coefs
- "vld1.32 { q9}, [%[coefsP1]:128]! \n" // load 4 32-bits coefs for interpolation
- "vld2.16 {d6,d7}, [%[sN]]! \n" // load 4 16-bits stereo samples
- "vld1.32 {q10}, [%[coefsN0]:128]! \n" // load 4 32-bits coefs
- "vld1.32 {q11}, [%[coefsN1]:128]! \n" // load 4 32-bits coefs for interpolation
-
- "vrev64.16 d4, d4 \n" // reverse 2 frames of the positive side
- "vrev64.16 d5, d5 \n" // reverse 2 frames of the positive side
-
- "vsub.s32 q9, q9, q8 \n" // interpolate (step1) 1st set of coefs
- "vsub.s32 q11, q11, q10 \n" // interpolate (step1) 2nd set of coets
- "vshll.s16 q12, d4, #15 \n" // extend samples to 31 bits
- "vshll.s16 q13, d5, #15 \n" // extend samples to 31 bits
-
- "vqrdmulh.s32 q9, q9, d2[0] \n" // interpolate (step2) 1st set of coefs
- "vqrdmulh.s32 q11, q11, d2[1] \n" // interpolate (step3) 2nd set of coefs
- "vshll.s16 q14, d6, #15 \n" // extend samples to 31 bits
- "vshll.s16 q15, d7, #15 \n" // extend samples to 31 bits
-
- "vadd.s32 q8, q8, q9 \n" // interpolate (step3) 1st set
- "vadd.s32 q10, q10, q11 \n" // interpolate (step4) 2nd set
- "subs %[count], %[count], #4 \n" // update loop counter
-
- "vqrdmulh.s32 q12, q12, q8 \n" // multiply samples by interpolated coef
- "vqrdmulh.s32 q13, q13, q8 \n" // multiply samples by interpolated coef
- "vqrdmulh.s32 q14, q14, q10 \n" // multiply samples by interpolated coef
- "vqrdmulh.s32 q15, q15, q10 \n" // multiply samples by interpolated coef
- "sub %[sP], %[sP], #16 \n" // move pointer to next set of samples
-
- "vadd.s32 q0, q0, q12 \n" // accumulate result
- "vadd.s32 q4, q4, q13 \n" // accumulate result
- "vadd.s32 q0, q0, q14 \n" // accumulate result
- "vadd.s32 q4, q4, q15 \n" // accumulate result
-
- "bne 1b \n" // loop
-
- "vld1.s32 {d2}, [%[vLR]] \n" // load volumes
- "vld1.s32 {d3}, %[out] \n" // load the output
- "vpadd.s32 d0, d0, d1 \n" // add all 4 partial sums from q0
- "vpadd.s32 d8, d8, d9 \n" // add all 4 partial sums from q4
- "vpadd.s32 d0, d0, d0 \n" // together
- "vpadd.s32 d8, d8, d8 \n" // together
- "vtrn.s32 d0, d8 \n" // interlace L,R channels
- "vqrdmulh.s32 d0, d0, d2 \n" // apply volume
- "vadd.s32 d3, d3, d0 \n" // accumulate result
- "vst1.s32 {d3}, %[out] \n" // store result
-
- : [out] "=Uv" (out[0]),
- [count] "+r" (count),
- [coefsP0] "+r" (coefsP),
- [coefsP1] "+r" (coefsP1),
- [coefsN0] "+r" (coefsN),
- [coefsN1] "+r" (coefsN1),
- [sP] "+r" (sP),
- [sN] "+r" (sN)
- : [lerpP] "r" (lerpP),
- [lerpN] "r" (lerpN),
- [vLR] "r" (mVolumeSIMD)
- : "cc", "memory",
- "q0", "q1", "q2", "q3", "q4",
- "q8", "q9", "q10", "q11",
- "q12", "q13", "q14", "q15"
- );
+
+ int32x4_t sum0, sum1;
+ int32x2_t lerpPN;
+
+ lerpPN = vdup_n_s32(0);
+ lerpPN = vld1_lane_s32((int32_t *)&lerpP, lerpPN, 0);
+ lerpPN = vld1_lane_s32((int32_t *)&lerpN, lerpPN, 1);
+ lerpPN = vshl_n_s32(lerpPN, 16);
+ sum0 = vdupq_n_s32(0);
+ sum1 = vdupq_n_s32(0);
+
+ int16x4x2_t sampleP, sampleN;
+ int32x4x2_t samplePExt, sampleNExt;
+ int32x4_t coefsPV0, coefsPV1, coefsNV0, coefsNV1;
+
+ coefsP = (const int32_t*)__builtin_assume_aligned(coefsP, 16);
+ coefsN = (const int32_t*)__builtin_assume_aligned(coefsN, 16);
+ coefsP1 = (const int32_t*)__builtin_assume_aligned(coefsP1, 16);
+ coefsN1 = (const int32_t*)__builtin_assume_aligned(coefsN1, 16);
+ for (; count > 0; count -= 4) {
+ sampleP = vld2_s16(sP);
+ sampleN = vld2_s16(sN);
+ coefsPV0 = vld1q_s32(coefsP);
+ coefsNV0 = vld1q_s32(coefsN);
+ coefsPV1 = vld1q_s32(coefsP1);
+ coefsNV1 = vld1q_s32(coefsN1);
+ sP -= 8;
+ sN += 8;
+ coefsP += 4;
+ coefsN += 4;
+ coefsP1 += 4;
+ coefsN1 += 4;
+
+ sampleP.val[0] = vrev64_s16(sampleP.val[0]);
+ sampleP.val[1] = vrev64_s16(sampleP.val[1]);
+
+ // interpolate (step1)
+ coefsPV1 = vsubq_s32(coefsPV1, coefsPV0);
+ coefsNV1 = vsubq_s32(coefsNV1, coefsNV0);
+ samplePExt.val[0] = vshll_n_s16(sampleP.val[0], 15);
+ samplePExt.val[1] = vshll_n_s16(sampleP.val[1], 15);
+ // interpolate (step2)
+ coefsPV1 = vqrdmulhq_lane_s32(coefsPV1, lerpPN, 0);
+ coefsNV1 = vqrdmulhq_lane_s32(coefsNV1, lerpPN, 1);
+ sampleNExt.val[0] = vshll_n_s16(sampleN.val[0], 15);
+ sampleNExt.val[1] = vshll_n_s16(sampleN.val[1], 15);
+ // interpolate (step3)
+ coefsPV0 = vaddq_s32(coefsPV0, coefsPV1);
+ coefsNV0 = vaddq_s32(coefsNV0, coefsNV1);
+
+ samplePExt.val[0] = vqrdmulhq_s32(samplePExt.val[0], coefsPV0);
+ samplePExt.val[1] = vqrdmulhq_s32(samplePExt.val[1], coefsPV0);
+ sampleNExt.val[0] = vqrdmulhq_s32(sampleNExt.val[0], coefsNV0);
+ sampleNExt.val[1] = vqrdmulhq_s32(sampleNExt.val[1], coefsNV0);
+ sum0 = vaddq_s32(sum0, samplePExt.val[0]);
+ sum1 = vaddq_s32(sum1, samplePExt.val[1]);
+ sum0 = vaddq_s32(sum0, sampleNExt.val[0]);
+ sum1 = vaddq_s32(sum1, sampleNExt.val[1]);
+ }
+ int32x2_t volumesV, outV;
+ volumesV = vld1_s32(mVolumeSIMD);
+ outV = vld1_s32(out);
+
+ //add all 4 partial sums
+ int32x2_t sumLow0, sumHigh0, sumLow1, sumHigh1;
+ sumLow0 = vget_low_s32(sum0);
+ sumHigh0 = vget_high_s32(sum0);
+ sumLow1 = vget_low_s32(sum1);
+ sumHigh1 = vget_high_s32(sum1);
+ sumLow0 = vpadd_s32(sumLow0, sumHigh0);
+ sumLow0 = vpadd_s32(sumLow0, sumLow0);
+ sumLow1 = vpadd_s32(sumLow1, sumHigh1);
+ sumLow1 = vpadd_s32(sumLow1, sumLow1);
+
+ sumLow0 = vtrn_s32(sumLow0, sumLow1).val[0];
+ sumLow0 = vqrdmulh_s32(sumLow0, volumesV);
+ outV = vadd_s32(outV, sumLow0);
+ vst1_s32(out, outV);
}
+#endif
}
template<int CHANNELS>
diff --git a/services/audioflinger/AudioWatchdog.cpp b/services/audioflinger/AudioWatchdog.cpp
index 93d185e..877e776 100644
--- a/services/audioflinger/AudioWatchdog.cpp
+++ b/services/audioflinger/AudioWatchdog.cpp
@@ -34,7 +34,7 @@ void AudioWatchdogDump::dump(int fd)
} else {
strcpy(buf, "N/A\n");
}
- fdprintf(fd, "Watchdog: underruns=%u, logs=%u, most recent underrun log at %s",
+ dprintf(fd, "Watchdog: underruns=%u, logs=%u, most recent underrun log at %s",
mUnderruns, mLogs, buf);
}
diff --git a/services/audioflinger/Configuration.h b/services/audioflinger/Configuration.h
index bc2038a..0754d9d 100644
--- a/services/audioflinger/Configuration.h
+++ b/services/audioflinger/Configuration.h
@@ -32,9 +32,6 @@
// uncomment to enable fast mixer to take performance samples for later statistical analysis
#define FAST_MIXER_STATISTICS
-// uncomment to allow fast tracks at non-native sample rate
-//#define FAST_TRACKS_AT_NON_NATIVE_SAMPLE_RATE
-
// uncomment for debugging timing problems related to StateQueue::push()
//#define STATE_QUEUE_DUMP
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index a8a5169..010e233 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -820,8 +820,8 @@ void AudioFlinger::EffectModule::dump(int fd, const Vector<String16>& args)
}
result.append("\t\tSession Status State Engine:\n");
- snprintf(buffer, SIZE, "\t\t%05d %03d %03d 0x%08x\n",
- mSessionId, mStatus, mState, (uint32_t)mEffectInterface);
+ snprintf(buffer, SIZE, "\t\t%05d %03d %03d %p\n",
+ mSessionId, mStatus, mState, mEffectInterface);
result.append(buffer);
result.append("\t\tDescriptor:\n");
@@ -850,26 +850,26 @@ void AudioFlinger::EffectModule::dump(int fd, const Vector<String16>& args)
result.append(buffer);
result.append("\t\t- Input configuration:\n");
- result.append("\t\t\tBuffer Frames Smp rate Channels Format\n");
- snprintf(buffer, SIZE, "\t\t\t0x%08x %05d %05d %08x %d\n",
- (uint32_t)mConfig.inputCfg.buffer.raw,
+ result.append("\t\t\tFrames Smp rate Channels Format Buffer\n");
+ snprintf(buffer, SIZE, "\t\t\t%05zu %05d %08x %6d %p\n",
mConfig.inputCfg.buffer.frameCount,
mConfig.inputCfg.samplingRate,
mConfig.inputCfg.channels,
- mConfig.inputCfg.format);
+ mConfig.inputCfg.format,
+ mConfig.inputCfg.buffer.raw);
result.append(buffer);
result.append("\t\t- Output configuration:\n");
result.append("\t\t\tBuffer Frames Smp rate Channels Format\n");
- snprintf(buffer, SIZE, "\t\t\t0x%08x %05d %05d %08x %d\n",
- (uint32_t)mConfig.outputCfg.buffer.raw,
+ snprintf(buffer, SIZE, "\t\t\t%p %05zu %05d %08x %d\n",
+ mConfig.outputCfg.buffer.raw,
mConfig.outputCfg.buffer.frameCount,
mConfig.outputCfg.samplingRate,
mConfig.outputCfg.channels,
mConfig.outputCfg.format);
result.append(buffer);
- snprintf(buffer, SIZE, "\t\t%d Clients:\n", mHandles.size());
+ snprintf(buffer, SIZE, "\t\t%zu Clients:\n", mHandles.size());
result.append(buffer);
result.append("\t\t\tPid Priority Ctrl Locked client server\n");
for (size_t i = 0; i < mHandles.size(); ++i) {
@@ -1578,10 +1578,10 @@ void AudioFlinger::EffectChain::dump(int fd, const Vector<String16>& args)
}
result.append("\tNum fx In buffer Out buffer Active tracks:\n");
- snprintf(buffer, SIZE, "\t%02d 0x%08x 0x%08x %d\n",
+ snprintf(buffer, SIZE, "\t%02zu %p %p %d\n",
mEffects.size(),
- (uint32_t)mInBuffer,
- (uint32_t)mOutBuffer,
+ mInBuffer,
+ mOutBuffer,
mActiveTrackCnt);
result.append(buffer);
write(fd, result.string(), result.size());
diff --git a/services/audioflinger/FastMixer.cpp b/services/audioflinger/FastMixer.cpp
index f27ea17..6d87838 100644
--- a/services/audioflinger/FastMixer.cpp
+++ b/services/audioflinger/FastMixer.cpp
@@ -26,7 +26,6 @@
#define ATRACE_TAG ATRACE_TAG_AUDIO
#include "Configuration.h"
-#include <sys/atomics.h>
#include <time.h>
#include <utils/Log.h>
#include <utils/Trace.h>
@@ -179,7 +178,7 @@ bool FastMixer::threadLoop()
ALOG_ASSERT(coldFutexAddr != NULL);
int32_t old = android_atomic_dec(coldFutexAddr);
if (old <= 0) {
- __futex_syscall4(coldFutexAddr, FUTEX_WAIT_PRIVATE, old - 1, NULL);
+ (void) syscall(__NR_futex, coldFutexAddr, FUTEX_WAIT_PRIVATE, old - 1, NULL);
}
int policy = sched_getscheduler(0);
if (!(policy == SCHED_FIFO || policy == SCHED_RR)) {
@@ -236,7 +235,6 @@ bool FastMixer::threadLoop()
sampleRate = Format_sampleRate(format);
ALOG_ASSERT(Format_channelCount(format) == FCC_2);
}
- dumpState->mSampleRate = sampleRate;
}
if ((format != previousFormat) || (frameCount != previous->mFrameCount)) {
@@ -321,12 +319,8 @@ bool FastMixer::threadLoop()
mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::MAIN_BUFFER,
(void *) mixBuffer);
// newly allocated track names default to full scale volume
- if (fastTrack->mSampleRate != 0 && fastTrack->mSampleRate != sampleRate) {
- mixer->setParameter(name, AudioMixer::RESAMPLE,
- AudioMixer::SAMPLE_RATE, (void*) fastTrack->mSampleRate);
- }
mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::CHANNEL_MASK,
- (void *) fastTrack->mChannelMask);
+ (void *)(uintptr_t)fastTrack->mChannelMask);
mixer->enable(name);
}
generations[i] = fastTrack->mGeneration;
@@ -353,16 +347,10 @@ bool FastMixer::threadLoop()
mixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME1,
(void *)0x1000);
}
- if (fastTrack->mSampleRate != 0 &&
- fastTrack->mSampleRate != sampleRate) {
- mixer->setParameter(name, AudioMixer::RESAMPLE,
- AudioMixer::SAMPLE_RATE, (void*) fastTrack->mSampleRate);
- } else {
- mixer->setParameter(name, AudioMixer::RESAMPLE,
- AudioMixer::REMOVE, NULL);
- }
+ mixer->setParameter(name, AudioMixer::RESAMPLE,
+ AudioMixer::REMOVE, NULL);
mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::CHANNEL_MASK,
- (void *) fastTrack->mChannelMask);
+ (void *)(uintptr_t) fastTrack->mChannelMask);
// already enabled
}
generations[i] = fastTrack->mGeneration;
@@ -392,16 +380,8 @@ bool FastMixer::threadLoop()
// Refresh the per-track timestamp
if (timestampStatus == NO_ERROR) {
- uint32_t trackFramesWrittenButNotPresented;
- uint32_t trackSampleRate = fastTrack->mSampleRate;
- // There is currently no sample rate conversion for fast tracks currently
- if (trackSampleRate != 0 && trackSampleRate != sampleRate) {
- trackFramesWrittenButNotPresented =
- ((int64_t) nativeFramesWrittenButNotPresented * trackSampleRate) /
- sampleRate;
- } else {
- trackFramesWrittenButNotPresented = nativeFramesWrittenButNotPresented;
- }
+ uint32_t trackFramesWrittenButNotPresented =
+ nativeFramesWrittenButNotPresented;
uint32_t trackFramesWritten = fastTrack->mBufferProvider->framesReleased();
// Can't provide an AudioTimestamp before first frame presented,
// or during the brief 32-bit wraparound window
@@ -419,9 +399,9 @@ bool FastMixer::threadLoop()
if (fastTrack->mVolumeProvider != NULL) {
uint32_t vlr = fastTrack->mVolumeProvider->getVolumeLR();
mixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME0,
- (void *)(vlr & 0xFFFF));
+ (void *)(uintptr_t)(vlr & 0xFFFF));
mixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME1,
- (void *)(vlr >> 16));
+ (void *)(uintptr_t)(vlr >> 16));
}
// FIXME The current implementation of framesReady() for fast tracks
// takes a tryLock, which can block
@@ -714,7 +694,7 @@ static int compare_uint32_t(const void *pa, const void *pb)
void FastMixerDumpState::dump(int fd) const
{
if (mCommand == FastMixerState::INITIAL) {
- fdprintf(fd, "FastMixer not initialized\n");
+ dprintf(fd, "FastMixer not initialized\n");
return;
}
#define COMMAND_MAX 32
@@ -748,9 +728,9 @@ void FastMixerDumpState::dump(int fd) const
double measuredWarmupMs = (mMeasuredWarmupTs.tv_sec * 1000.0) +
(mMeasuredWarmupTs.tv_nsec / 1000000.0);
double mixPeriodSec = (double) mFrameCount / (double) mSampleRate;
- fdprintf(fd, "FastMixer command=%s writeSequence=%u framesWritten=%u\n"
+ dprintf(fd, "FastMixer command=%s writeSequence=%u framesWritten=%u\n"
" numTracks=%u writeErrors=%u underruns=%u overruns=%u\n"
- " sampleRate=%u frameCount=%u measuredWarmup=%.3g ms, warmupCycles=%u\n"
+ " sampleRate=%u frameCount=%zu measuredWarmup=%.3g ms, warmupCycles=%u\n"
" mixPeriod=%.2f ms\n",
string, mWriteSequence, mFramesWritten,
mNumTracks, mWriteErrors, mUnderruns, mOverruns,
@@ -802,21 +782,21 @@ void FastMixerDumpState::dump(int fd) const
previousCpukHz = sampleCpukHz;
#endif
}
- fdprintf(fd, "Simple moving statistics over last %.1f seconds:\n", wall.n() * mixPeriodSec);
- fdprintf(fd, " wall clock time in ms per mix cycle:\n"
- " mean=%.2f min=%.2f max=%.2f stddev=%.2f\n",
- wall.mean()*1e-6, wall.minimum()*1e-6, wall.maximum()*1e-6, wall.stddev()*1e-6);
- fdprintf(fd, " raw CPU load in us per mix cycle:\n"
- " mean=%.0f min=%.0f max=%.0f stddev=%.0f\n",
- loadNs.mean()*1e-3, loadNs.minimum()*1e-3, loadNs.maximum()*1e-3,
- loadNs.stddev()*1e-3);
+ dprintf(fd, "Simple moving statistics over last %.1f seconds:\n", wall.n() * mixPeriodSec);
+ dprintf(fd, " wall clock time in ms per mix cycle:\n"
+ " mean=%.2f min=%.2f max=%.2f stddev=%.2f\n",
+ wall.mean()*1e-6, wall.minimum()*1e-6, wall.maximum()*1e-6, wall.stddev()*1e-6);
+ dprintf(fd, " raw CPU load in us per mix cycle:\n"
+ " mean=%.0f min=%.0f max=%.0f stddev=%.0f\n",
+ loadNs.mean()*1e-3, loadNs.minimum()*1e-3, loadNs.maximum()*1e-3,
+ loadNs.stddev()*1e-3);
#ifdef CPU_FREQUENCY_STATISTICS
- fdprintf(fd, " CPU clock frequency in MHz:\n"
- " mean=%.0f min=%.0f max=%.0f stddev=%.0f\n",
- kHz.mean()*1e-3, kHz.minimum()*1e-3, kHz.maximum()*1e-3, kHz.stddev()*1e-3);
- fdprintf(fd, " adjusted CPU load in MHz (i.e. normalized for CPU clock frequency):\n"
- " mean=%.1f min=%.1f max=%.1f stddev=%.1f\n",
- loadMHz.mean(), loadMHz.minimum(), loadMHz.maximum(), loadMHz.stddev());
+ dprintf(fd, " CPU clock frequency in MHz:\n"
+ " mean=%.0f min=%.0f max=%.0f stddev=%.0f\n",
+ kHz.mean()*1e-3, kHz.minimum()*1e-3, kHz.maximum()*1e-3, kHz.stddev()*1e-3);
+ dprintf(fd, " adjusted CPU load in MHz (i.e. normalized for CPU clock frequency):\n"
+ " mean=%.1f min=%.1f max=%.1f stddev=%.1f\n",
+ loadMHz.mean(), loadMHz.minimum(), loadMHz.maximum(), loadMHz.stddev());
#endif
if (tail != NULL) {
qsort(tail, n, sizeof(uint32_t), compare_uint32_t);
@@ -827,12 +807,12 @@ void FastMixerDumpState::dump(int fd) const
left.sample(tail[i]);
right.sample(tail[n - (i + 1)]);
}
- fdprintf(fd, "Distribution of mix cycle times in ms for the tails (> ~3 stddev outliers):\n"
- " left tail: mean=%.2f min=%.2f max=%.2f stddev=%.2f\n"
- " right tail: mean=%.2f min=%.2f max=%.2f stddev=%.2f\n",
- left.mean()*1e-6, left.minimum()*1e-6, left.maximum()*1e-6, left.stddev()*1e-6,
- right.mean()*1e-6, right.minimum()*1e-6, right.maximum()*1e-6,
- right.stddev()*1e-6);
+ dprintf(fd, "Distribution of mix cycle times in ms for the tails (> ~3 stddev outliers):\n"
+ " left tail: mean=%.2f min=%.2f max=%.2f stddev=%.2f\n"
+ " right tail: mean=%.2f min=%.2f max=%.2f stddev=%.2f\n",
+ left.mean()*1e-6, left.minimum()*1e-6, left.maximum()*1e-6, left.stddev()*1e-6,
+ right.mean()*1e-6, right.minimum()*1e-6, right.maximum()*1e-6,
+ right.stddev()*1e-6);
delete[] tail;
}
#endif
@@ -842,9 +822,9 @@ void FastMixerDumpState::dump(int fd) const
// Instead we always display all tracks, with an indication
// of whether we think the track is active.
uint32_t trackMask = mTrackMask;
- fdprintf(fd, "Fast tracks: kMaxFastTracks=%u activeMask=%#x\n",
+ dprintf(fd, "Fast tracks: kMaxFastTracks=%u activeMask=%#x\n",
FastMixerState::kMaxFastTracks, trackMask);
- fdprintf(fd, "Index Active Full Partial Empty Recent Ready\n");
+ dprintf(fd, "Index Active Full Partial Empty Recent Ready\n");
for (uint32_t i = 0; i < FastMixerState::kMaxFastTracks; ++i, trackMask >>= 1) {
bool isActive = trackMask & 1;
const FastTrackDump *ftDump = &mTracks[i];
@@ -864,7 +844,7 @@ void FastMixerDumpState::dump(int fd) const
mostRecent = "?";
break;
}
- fdprintf(fd, "%5u %6s %4u %7u %5u %7s %5u\n", i, isActive ? "yes" : "no",
+ dprintf(fd, "%5u %6s %4u %7u %5u %7s %5zu\n", i, isActive ? "yes" : "no",
(underruns.mBitFields.mFull) & UNDERRUN_MASK,
(underruns.mBitFields.mPartial) & UNDERRUN_MASK,
(underruns.mBitFields.mEmpty) & UNDERRUN_MASK,
diff --git a/services/audioflinger/FastMixer.h b/services/audioflinger/FastMixer.h
index 6158925..c356d31 100644
--- a/services/audioflinger/FastMixer.h
+++ b/services/audioflinger/FastMixer.h
@@ -17,11 +17,10 @@
#ifndef ANDROID_AUDIO_FAST_MIXER_H
#define ANDROID_AUDIO_FAST_MIXER_H
+#include <linux/futex.h>
+#include <sys/syscall.h>
#include <utils/Debug.h>
#include <utils/Thread.h>
-extern "C" {
-#include "../private/bionic_futex.h"
-}
#include "StateQueue.h"
#include "FastMixerState.h"
diff --git a/services/audioflinger/FastMixerState.cpp b/services/audioflinger/FastMixerState.cpp
index 737de97..43ff233 100644
--- a/services/audioflinger/FastMixerState.cpp
+++ b/services/audioflinger/FastMixerState.cpp
@@ -20,7 +20,7 @@
namespace android {
FastTrack::FastTrack() :
- mBufferProvider(NULL), mVolumeProvider(NULL), mSampleRate(0),
+ mBufferProvider(NULL), mVolumeProvider(NULL),
mChannelMask(AUDIO_CHANNEL_OUT_STEREO), mGeneration(0)
{
}
diff --git a/services/audioflinger/FastMixerState.h b/services/audioflinger/FastMixerState.h
index f6e7903..9739fe9 100644
--- a/services/audioflinger/FastMixerState.h
+++ b/services/audioflinger/FastMixerState.h
@@ -43,7 +43,6 @@ struct FastTrack {
ExtendedAudioBufferProvider* mBufferProvider; // must be NULL if inactive, or non-NULL if active
VolumeProvider* mVolumeProvider; // optional; if NULL then full-scale
- unsigned mSampleRate; // optional; if zero then use mixer sample rate
audio_channel_mask_t mChannelMask; // AUDIO_CHANNEL_OUT_MONO or AUDIO_CHANNEL_OUT_STEREO
int mGeneration; // increment when any field is assigned
};
diff --git a/services/audioflinger/StateQueue.cpp b/services/audioflinger/StateQueue.cpp
index c2d3bbd..40d7bcd 100644
--- a/services/audioflinger/StateQueue.cpp
+++ b/services/audioflinger/StateQueue.cpp
@@ -28,12 +28,12 @@ namespace android {
#ifdef STATE_QUEUE_DUMP
void StateQueueObserverDump::dump(int fd)
{
- fdprintf(fd, "State queue observer: stateChanges=%u\n", mStateChanges);
+ dprintf(fd, "State queue observer: stateChanges=%u\n", mStateChanges);
}
void StateQueueMutatorDump::dump(int fd)
{
- fdprintf(fd, "State queue mutator: pushDirty=%u pushAck=%u blockedSequence=%u\n",
+ dprintf(fd, "State queue mutator: pushDirty=%u pushAck=%u blockedSequence=%u\n",
mPushDirty, mPushAck, mBlockedSequence);
}
#endif
@@ -41,13 +41,14 @@ void StateQueueMutatorDump::dump(int fd)
// Constructor and destructor
template<typename T> StateQueue<T>::StateQueue() :
- mNext(NULL), mAck(NULL), mCurrent(NULL),
+ mAck(NULL), mCurrent(NULL),
mMutating(&mStates[0]), mExpecting(NULL),
mInMutation(false), mIsDirty(false), mIsInitialized(false)
#ifdef STATE_QUEUE_DUMP
, mObserverDump(&mObserverDummyDump), mMutatorDump(&mMutatorDummyDump)
#endif
{
+ atomic_init(&mNext, 0);
}
template<typename T> StateQueue<T>::~StateQueue()
@@ -58,7 +59,8 @@ template<typename T> StateQueue<T>::~StateQueue()
template<typename T> const T* StateQueue<T>::poll()
{
- const T *next = (const T *) android_atomic_acquire_load((volatile int32_t *) &mNext);
+ const T *next = (const T *) atomic_load_explicit(&mNext, memory_order_acquire);
+
if (next != mCurrent) {
mAck = next; // no additional barrier needed
mCurrent = next;
@@ -140,7 +142,7 @@ template<typename T> bool StateQueue<T>::push(StateQueue<T>::block_t block)
}
// publish
- android_atomic_release_store((int32_t) mMutating, (volatile int32_t *) &mNext);
+ atomic_store_explicit(&mNext, (uintptr_t)mMutating, memory_order_release);
mExpecting = mMutating;
// copy with circular wraparound
diff --git a/services/audioflinger/StateQueue.h b/services/audioflinger/StateQueue.h
index 9cde642..ef01df7 100644
--- a/services/audioflinger/StateQueue.h
+++ b/services/audioflinger/StateQueue.h
@@ -17,6 +17,8 @@
#ifndef ANDROID_AUDIO_STATE_QUEUE_H
#define ANDROID_AUDIO_STATE_QUEUE_H
+#include <stdatomic.h>
+
// The state queue template class was originally driven by this use case / requirements:
// There are two threads: a fast mixer, and a normal mixer, and they share state.
// The interesting part of the shared state is a set of active fast tracks,
@@ -184,7 +186,7 @@ private:
T mStates[kN]; // written by mutator, read by observer
// "volatile" is meaningless with SMP, but here it indicates that we're using atomic ops
- volatile const T* mNext; // written by mutator to advance next, read by observer
+ atomic_uintptr_t mNext; // written by mutator to advance next, read by observer
volatile const T* mAck; // written by observer to acknowledge advance of next, read by mutator
// only used by observer
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index bf85b51..23a2174 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -135,12 +135,12 @@ static const int kPriorityFastMixer = 3;
// IAudioFlinger::createTrack() reports back to client the total size of shared memory area
// for the track. The client then sub-divides this into smaller buffers for its use.
-// Currently the client uses double-buffering by default, but doesn't tell us about that.
-// So for now we just assume that client is double-buffered.
-// FIXME It would be better for client to tell AudioFlinger whether it wants double-buffering or
-// N-buffering, so AudioFlinger could allocate the right amount of memory.
+// Currently the client uses N-buffering by default, but doesn't tell us about the value of N.
+// So for now we just assume that client is double-buffered for fast tracks.
+// FIXME It would be better for client to tell AudioFlinger the value of N,
+// so AudioFlinger could allocate the right amount of memory.
// See the client's minBufCount and mNotificationFramesAct calculations for details.
-static const int kFastTrackMultiplier = 1;
+static const int kFastTrackMultiplier = 2;
// ----------------------------------------------------------------------------
@@ -425,7 +425,7 @@ void AudioFlinger::ThreadBase::dumpBase(int fd, const Vector<String16>& args)
result.append(buffer);
snprintf(buffer, SIZE, "Sample rate: %u\n", mSampleRate);
result.append(buffer);
- snprintf(buffer, SIZE, "HAL frame count: %d\n", mFrameCount);
+ snprintf(buffer, SIZE, "HAL frame count: %zu\n", mFrameCount);
result.append(buffer);
snprintf(buffer, SIZE, "Channel Count: %u\n", mChannelCount);
result.append(buffer);
@@ -433,14 +433,14 @@ void AudioFlinger::ThreadBase::dumpBase(int fd, const Vector<String16>& args)
result.append(buffer);
snprintf(buffer, SIZE, "Format: %d\n", mFormat);
result.append(buffer);
- snprintf(buffer, SIZE, "Frame size: %u\n", mFrameSize);
+ snprintf(buffer, SIZE, "Frame size: %zu\n", mFrameSize);
result.append(buffer);
snprintf(buffer, SIZE, "\nPending setParameters commands: \n");
result.append(buffer);
result.append(" Index Command");
for (size_t i = 0; i < mNewParameters.size(); ++i) {
- snprintf(buffer, SIZE, "\n %02d ", i);
+ snprintf(buffer, SIZE, "\n %02zu ", i);
result.append(buffer);
result.append(mNewParameters[i]);
}
@@ -466,7 +466,7 @@ void AudioFlinger::ThreadBase::dumpEffectChains(int fd, const Vector<String16>&
char buffer[SIZE];
String8 result;
- snprintf(buffer, SIZE, "\n- %d Effect Chains:\n", mEffectChains.size());
+ snprintf(buffer, SIZE, "\n- %zu Effect Chains:\n", mEffectChains.size());
write(fd, buffer, strlen(buffer));
for (size_t i = 0; i < mEffectChains.size(); ++i) {
@@ -1116,7 +1116,7 @@ void AudioFlinger::PlaybackThread::dumpTracks(int fd, const Vector<String16>& ar
// These values are "raw"; they will wrap around. See prepareTracks_l() for a better way.
FastTrackUnderruns underruns = getFastTrackUnderruns(0);
- fdprintf(fd, "Normal mixer raw underrun counters: partial=%u empty=%u\n",
+ dprintf(fd, "Normal mixer raw underrun counters: partial=%u empty=%u\n",
underruns.mBitFields.mPartial, underruns.mBitFields.mEmpty);
}
@@ -1128,7 +1128,7 @@ void AudioFlinger::PlaybackThread::dumpInternals(int fd, const Vector<String16>&
snprintf(buffer, SIZE, "\nOutput thread %p internals\n", this);
result.append(buffer);
- snprintf(buffer, SIZE, "Normal frame count: %d\n", mNormalFrameCount);
+ snprintf(buffer, SIZE, "Normal frame count: %zu\n", mNormalFrameCount);
result.append(buffer);
snprintf(buffer, SIZE, "last write occurred (msecs): %llu\n",
ns2ms(systemTime() - mLastWriteTime));
@@ -1144,7 +1144,7 @@ void AudioFlinger::PlaybackThread::dumpInternals(int fd, const Vector<String16>&
snprintf(buffer, SIZE, "mix buffer : %p\n", mMixBuffer);
result.append(buffer);
write(fd, result.string(), result.size());
- fdprintf(fd, "Fast track availMask=%#x\n", mFastTrackAvailMask);
+ dprintf(fd, "Fast track availMask=%#x\n", mFastTrackAvailMask);
dumpBase(fd, args);
}
@@ -1210,7 +1210,7 @@ sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTrac
(
(tid != -1) &&
((frameCount == 0) ||
- (frameCount >= (mFrameCount * kFastTrackMultiplier)))
+ (frameCount >= mFrameCount))
)
) &&
// PCM data
@@ -1218,10 +1218,8 @@ sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTrac
// mono or stereo
( (channelMask == AUDIO_CHANNEL_OUT_MONO) ||
(channelMask == AUDIO_CHANNEL_OUT_STEREO) ) &&
-#ifndef FAST_TRACKS_AT_NON_NATIVE_SAMPLE_RATE
// hardware sample rate
(sampleRate == mSampleRate) &&
-#endif
// normal mixer has an associated fast mixer
hasFastMixer() &&
// there are sufficient fast track slots available
@@ -1326,8 +1324,10 @@ sp<AudioFlinger::PlaybackThread::Track> AudioFlinger::PlaybackThread::createTrac
track = TimedTrack::create(this, client, streamType, sampleRate, format,
channelMask, frameCount, sharedBuffer, sessionId, uid);
}
+
if (track == 0 || track->getCblk() == NULL || track->name() < 0) {
lStatus = NO_MEMORY;
+ // track must be cleared from the caller as the caller has the AF lock
goto Exit;
}
@@ -1718,7 +1718,7 @@ void AudioFlinger::PlaybackThread::readOutputParameters()
}
-status_t AudioFlinger::PlaybackThread::getRenderPosition(size_t *halFrames, size_t *dspFrames)
+status_t AudioFlinger::PlaybackThread::getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames)
{
if (halFrames == NULL || dspFrames == NULL) {
return BAD_VALUE;
@@ -1736,7 +1736,11 @@ status_t AudioFlinger::PlaybackThread::getRenderPosition(size_t *halFrames, size
*dspFrames = framesWritten >= latencyFrames ? framesWritten - latencyFrames : 0;
return NO_ERROR;
} else {
- return mOutput->stream->get_render_position(mOutput->stream, dspFrames);
+ status_t status;
+ uint32_t frames;
+ status = mOutput->stream->get_render_position(mOutput->stream, &frames);
+ *dspFrames = (size_t)frames;
+ return status;
}
}
@@ -1913,7 +1917,7 @@ ssize_t AudioFlinger::PlaybackThread::threadLoop_write()
// otherwise use the HAL / AudioStreamOut directly
} else {
// Direct output and offload threads
- size_t offset = (mCurrentWriteLength - mBytesRemaining) / sizeof(int16_t);
+ size_t offset = (mCurrentWriteLength - mBytesRemaining);
if (mUseAsyncWrite) {
ALOGW_IF(mWriteAckSequence & 1, "threadLoop_write(): out of sequence write request");
mWriteAckSequence += 2;
@@ -1924,7 +1928,7 @@ ssize_t AudioFlinger::PlaybackThread::threadLoop_write()
// FIXME We should have an implementation of timestamps for direct output threads.
// They are used e.g for multichannel PCM playback over HDMI.
bytesWritten = mOutput->stream->write(mOutput->stream,
- mMixBuffer + offset, mBytesRemaining);
+ (char *)mMixBuffer + offset, mBytesRemaining);
if (mUseAsyncWrite &&
((bytesWritten < 0) || (bytesWritten == (ssize_t)mBytesRemaining))) {
// do not wait for async callback in case of error of full write
@@ -2600,7 +2604,7 @@ AudioFlinger::MixerThread::~MixerThread()
if (state->mCommand == FastMixerState::COLD_IDLE) {
int32_t old = android_atomic_inc(&mFastMixerFutex);
if (old == -1) {
- __futex_syscall3(&mFastMixerFutex, FUTEX_WAKE_PRIVATE, 1);
+ (void) syscall(__NR_futex, &mFastMixerFutex, FUTEX_WAKE_PRIVATE, 1);
}
}
state->mCommand = FastMixerState::EXIT;
@@ -2657,7 +2661,7 @@ ssize_t AudioFlinger::MixerThread::threadLoop_write()
if (state->mCommand == FastMixerState::COLD_IDLE) {
int32_t old = android_atomic_inc(&mFastMixerFutex);
if (old == -1) {
- __futex_syscall3(&mFastMixerFutex, FUTEX_WAKE_PRIVATE, 1);
+ (void) syscall(__NR_futex, &mFastMixerFutex, FUTEX_WAKE_PRIVATE, 1);
}
#ifdef AUDIO_WATCHDOG
if (mAudioWatchdog != 0) {
@@ -2973,7 +2977,6 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac
VolumeProvider *vp = track;
fastTrack->mBufferProvider = eabp;
fastTrack->mVolumeProvider = vp;
- fastTrack->mSampleRate = track->mSampleRate;
fastTrack->mChannelMask = track->mChannelMask;
fastTrack->mGeneration++;
state->mTrackMask |= 1 << j;
@@ -3036,15 +3039,8 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac
(mMixerStatusIgnoringFastTracks == MIXER_TRACKS_READY)) {
minFrames = desiredFrames;
}
- // It's not safe to call framesReady() for a static buffer track, so assume it's ready
- size_t framesReady;
- if (track->sharedBuffer() == 0) {
- framesReady = track->framesReady();
- } else if (track->isStopped()) {
- framesReady = 0;
- } else {
- framesReady = 1;
- }
+
+ size_t framesReady = track->framesReady();
if ((framesReady >= minFrames) && track->isReady() &&
!track->isPaused() && !track->isTerminated())
{
@@ -3157,9 +3153,9 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac
mAudioMixer->setBufferProvider(name, track);
mAudioMixer->enable(name);
- mAudioMixer->setParameter(name, param, AudioMixer::VOLUME0, (void *)vl);
- mAudioMixer->setParameter(name, param, AudioMixer::VOLUME1, (void *)vr);
- mAudioMixer->setParameter(name, param, AudioMixer::AUXLEVEL, (void *)va);
+ mAudioMixer->setParameter(name, param, AudioMixer::VOLUME0, (void *)(uintptr_t)vl);
+ mAudioMixer->setParameter(name, param, AudioMixer::VOLUME1, (void *)(uintptr_t)vr);
+ mAudioMixer->setParameter(name, param, AudioMixer::AUXLEVEL, (void *)(uintptr_t)va);
mAudioMixer->setParameter(
name,
AudioMixer::TRACK,
@@ -3167,7 +3163,7 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac
mAudioMixer->setParameter(
name,
AudioMixer::TRACK,
- AudioMixer::CHANNEL_MASK, (void *)track->channelMask());
+ AudioMixer::CHANNEL_MASK, (void *)(uintptr_t)track->channelMask());
// limit track sample rate to 2 x output sample rate, which changes at re-configuration
uint32_t maxSampleRate = mSampleRate * 2;
uint32_t reqSampleRate = track->mAudioTrackServerProxy->getSampleRate();
@@ -3180,7 +3176,7 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac
name,
AudioMixer::RESAMPLE,
AudioMixer::SAMPLE_RATE,
- (void *)reqSampleRate);
+ (void *)(uintptr_t)reqSampleRate);
mAudioMixer->setParameter(
name,
AudioMixer::TRACK,
@@ -3861,7 +3857,12 @@ bool AudioFlinger::AsyncCallbackThread::threadLoop()
{
Mutex::Autolock _l(mLock);
- mWaitWorkCV.wait(mLock);
+ while (!((mWriteAckSequence & 1) ||
+ (mDrainSequence & 1) ||
+ exitPending())) {
+ mWaitWorkCV.wait(mLock);
+ }
+
if (exitPending()) {
break;
}
@@ -3951,7 +3952,10 @@ void AudioFlinger::OffloadThread::threadLoop_exit()
mMixerStatus = MIXER_DRAIN_ALL;
threadLoop_drain();
}
- mCallbackThread->exit();
+ if (mUseAsyncWrite) {
+ ALOG_ASSERT(mCallbackThread != 0);
+ mCallbackThread->exit();
+ }
PlaybackThread::threadLoop_exit();
}
@@ -4687,7 +4691,7 @@ sp<AudioFlinger::RecordThread::RecordTrack> AudioFlinger::RecordThread::createR
(
(tid != -1) &&
((frameCount == 0) ||
- (frameCount >= (mFrameCount * kFastTrackMultiplier)))
+ (frameCount >= mFrameCount))
) &&
// FIXME when record supports non-PCM data, also check for audio_is_linear_pcm(format)
// mono or stereo
@@ -4742,7 +4746,7 @@ sp<AudioFlinger::RecordThread::RecordTrack> AudioFlinger::RecordThread::createR
if (track->getCblk() == 0) {
ALOGE("createRecordTrack_l() no control block");
lStatus = NO_MEMORY;
- track.clear();
+ // track must be cleared from the caller as the caller has the AF lock
goto Exit;
}
mTracks.add(track);
@@ -4959,9 +4963,9 @@ void AudioFlinger::RecordThread::dumpInternals(int fd, const Vector<String16>& a
result.append(buffer);
if (mActiveTrack != 0) {
- snprintf(buffer, SIZE, "In index: %d\n", mRsmpInIndex);
+ snprintf(buffer, SIZE, "In index: %zu\n", mRsmpInIndex);
result.append(buffer);
- snprintf(buffer, SIZE, "Buffer size: %u bytes\n", mBufferSize);
+ snprintf(buffer, SIZE, "Buffer size: %zu bytes\n", mBufferSize);
result.append(buffer);
snprintf(buffer, SIZE, "Resampling: %d\n", (mResampler != NULL));
result.append(buffer);
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 207f1eb..a2fb874 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -446,7 +446,7 @@ public:
virtual String8 getParameters(const String8& keys);
virtual void audioConfigChanged_l(int event, int param = 0);
- status_t getRenderPosition(size_t *halFrames, size_t *dspFrames);
+ status_t getRenderPosition(uint32_t *halFrames, uint32_t *dspFrames);
int16_t *mixBuffer() const { return mMixBuffer; };
virtual void detachAuxEffect_l(int effectId);
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index af04ce7..cbf56b5 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -21,6 +21,7 @@
#include "Configuration.h"
#include <math.h>
+#include <sys/syscall.h>
#include <utils/Log.h>
#include <private/media/AudioTrackShared.h>
@@ -487,8 +488,8 @@ void AudioFlinger::PlaybackThread::Track::dump(char* buffer, size_t size)
nowInUnderrun = '?';
break;
}
- snprintf(&buffer[7], size-7, " %6u %4u %08X %08X %7u %6u %1c %1d %5u %5.2g %5.2g "
- "%08X %08X %08X 0x%03X %9u%c\n",
+ snprintf(&buffer[7], size-7, " %6u %4u %08X %08X %7u %6zu %1c %1d %5u %5.2g %5.2g "
+ "%08X %p %p 0x%03X %9u%c\n",
(mClient == 0) ? getpid_cached : mClient->pid(),
mStreamType,
mFormat,
@@ -501,8 +502,8 @@ void AudioFlinger::PlaybackThread::Track::dump(char* buffer, size_t size)
20.0 * log10((vlr & 0xFFFF) / 4096.0),
20.0 * log10((vlr >> 16) / 4096.0),
mCblk->mServer,
- (int)mMainBuffer,
- (int)mAuxBuffer,
+ mMainBuffer,
+ mAuxBuffer,
mCblk->mFlags,
mAudioTrackServerProxy->getUnderrunFrames(),
nowInUnderrun);
@@ -551,7 +552,7 @@ size_t AudioFlinger::PlaybackThread::Track::framesReleased() const
// Don't call for fast tracks; the framesReady() could result in priority inversion
bool AudioFlinger::PlaybackThread::Track::isReady() const {
- if (mFillingUpStatus != FS_FILLING || isStopped() || isPausing()) {
+ if (mFillingUpStatus != FS_FILLING || isStopped() || isPausing() || isStopping()) {
return true;
}
@@ -895,7 +896,7 @@ bool AudioFlinger::PlaybackThread::Track::presentationComplete(size_t framesWrit
void AudioFlinger::PlaybackThread::Track::triggerEvents(AudioSystem::sync_event_t type)
{
- for (int i = 0; i < (int)mSyncEvents.size(); i++) {
+ for (size_t i = 0; i < mSyncEvents.size(); i++) {
if (mSyncEvents[i]->type() == type) {
mSyncEvents[i]->trigger();
mSyncEvents.removeAt(i);
@@ -952,7 +953,7 @@ void AudioFlinger::PlaybackThread::Track::invalidate()
android_atomic_or(CBLK_INVALID, &cblk->mFlags);
android_atomic_release_store(0x40000000, &cblk->mFutex);
// client is not in server, so FUTEX_WAKE is needed instead of FUTEX_WAKE_PRIVATE
- (void) __futex_syscall3(&cblk->mFutex, FUTEX_WAKE, INT_MAX);
+ (void) syscall(__NR_futex, &cblk->mFutex, FUTEX_WAKE, INT_MAX);
mIsInvalid = true;
}
@@ -1839,7 +1840,7 @@ void AudioFlinger::RecordThread::RecordTrack::invalidate()
android_atomic_or(CBLK_INVALID, &cblk->mFlags);
android_atomic_release_store(0x40000000, &cblk->mFutex);
// client is not in server, so FUTEX_WAKE is needed instead of FUTEX_WAKE_PRIVATE
- (void) __futex_syscall3(&cblk->mFutex, FUTEX_WAKE, INT_MAX);
+ (void) syscall(__NR_futex, &cblk->mFutex, FUTEX_WAKE, INT_MAX);
}
@@ -1850,7 +1851,7 @@ void AudioFlinger::RecordThread::RecordTrack::invalidate()
void AudioFlinger::RecordThread::RecordTrack::dump(char* buffer, size_t size)
{
- snprintf(buffer, size, "%6u %3u %08X %7u %1d %08X %6u\n",
+ snprintf(buffer, size, "%6u %3u %08X %7u %1d %08X %6zu\n",
(mClient == 0) ? getpid_cached : mClient->pid(),
mFormat,
mChannelMask,
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index eeedfc9..9ce7daf 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -196,7 +196,7 @@ void CameraService::onDeviceStatusChanged(int cameraId,
*/
}
- ALOGV("%s: After unplug, disconnected %d clients",
+ ALOGV("%s: After unplug, disconnected %zu clients",
__FUNCTION__, clientsToDisconnect.size());
}
@@ -655,6 +655,11 @@ status_t CameraService::addListener(
const sp<ICameraServiceListener>& listener) {
ALOGV("%s: Add listener %p", __FUNCTION__, listener.get());
+ if (listener == 0) {
+ ALOGE("%s: Listener must not be null", __FUNCTION__);
+ return BAD_VALUE;
+ }
+
Mutex::Autolock lock(mServiceLock);
Vector<sp<ICameraServiceListener> >::iterator it, end;
@@ -683,6 +688,11 @@ status_t CameraService::removeListener(
const sp<ICameraServiceListener>& listener) {
ALOGV("%s: Remove listener %p", __FUNCTION__, listener.get());
+ if (listener == 0) {
+ ALOGE("%s: Listener must not be null", __FUNCTION__);
+ return BAD_VALUE;
+ }
+
Mutex::Autolock lock(mServiceLock);
Vector<sp<ICameraServiceListener> >::iterator it;
@@ -1042,13 +1052,13 @@ void CameraService::BasicClient::opChanged(int32_t op, const String16& packageNa
// ----------------------------------------------------------------------------
Mutex* CameraService::Client::getClientLockFromCookie(void* user) {
- return gCameraService->getClientLockById((int) user);
+ return gCameraService->getClientLockById((int)(intptr_t) user);
}
// Provide client pointer for callbacks. Client lock returned from getClientLockFromCookie should
// be acquired for this to be safe
CameraService::Client* CameraService::Client::getClientFromCookie(void* user) {
- BasicClient *basicClient = gCameraService->getClientByIdUnsafe((int) user);
+ BasicClient *basicClient = gCameraService->getClientByIdUnsafe((int)(intptr_t) user);
// OK: only CameraClient calls this, and they already cast anyway.
Client* client = static_cast<Client*>(basicClient);
@@ -1159,6 +1169,7 @@ status_t CameraService::dump(int fd, const Vector<String16>& args) {
if (!mModule) {
result = String8::format("No camera module available!\n");
write(fd, result.string(), result.size());
+ if (locked) mServiceLock.unlock();
return NO_ERROR;
}
diff --git a/services/camera/libcameraservice/api1/Camera2Client.cpp b/services/camera/libcameraservice/api1/Camera2Client.cpp
index 0b6ca5c..af23557 100644
--- a/services/camera/libcameraservice/api1/Camera2Client.cpp
+++ b/services/camera/libcameraservice/api1/Camera2Client.cpp
@@ -18,6 +18,7 @@
#define ATRACE_TAG ATRACE_TAG_CAMERA
//#define LOG_NDEBUG 0
+#include <inttypes.h>
#include <utils/Log.h>
#include <utils/Trace.h>
@@ -193,7 +194,7 @@ status_t Camera2Client::dump(int fd, const Vector<String16>& args) {
result.appendFormat(" GPS lat x long x alt: %f x %f x %f\n",
p.gpsCoordinates[0], p.gpsCoordinates[1],
p.gpsCoordinates[2]);
- result.appendFormat(" GPS timestamp: %lld\n",
+ result.appendFormat(" GPS timestamp: %" PRId64 "\n",
p.gpsTimestamp);
result.appendFormat(" GPS processing method: %s\n",
p.gpsProcessingMethod.string());
@@ -406,12 +407,6 @@ void Camera2Client::disconnect() {
l.mParameters.state = Parameters::DISCONNECTED;
}
- mStreamingProcessor->deletePreviewStream();
- mStreamingProcessor->deleteRecordingStream();
- mJpegProcessor->deleteStream();
- mCallbackProcessor->deleteStream();
- mZslProcessor->deleteStream();
-
mStreamingProcessor->requestExit();
mFrameProcessor->requestExit();
mCaptureSequencer->requestExit();
@@ -428,6 +423,14 @@ void Camera2Client::disconnect() {
mZslProcessorThread->join();
mCallbackProcessor->join();
+ ALOGV("Camera %d: Deleting streams", mCameraId);
+
+ mStreamingProcessor->deletePreviewStream();
+ mStreamingProcessor->deleteRecordingStream();
+ mJpegProcessor->deleteStream();
+ mCallbackProcessor->deleteStream();
+ mZslProcessor->deleteStream();
+
ALOGV("Camera %d: Disconnecting device", mCameraId);
mDevice->disconnect();
@@ -731,6 +734,7 @@ status_t Camera2Client::startPreviewL(Parameters &params, bool restart) {
return OK;
}
params.state = Parameters::STOPPED;
+ int lastPreviewStreamId = mStreamingProcessor->getPreviewStreamId();
res = mStreamingProcessor->updatePreviewStream(params);
if (res != OK) {
@@ -739,6 +743,8 @@ status_t Camera2Client::startPreviewL(Parameters &params, bool restart) {
return res;
}
+ bool previewStreamChanged = mStreamingProcessor->getPreviewStreamId() != lastPreviewStreamId;
+
// We could wait to create the JPEG output stream until first actual use
// (first takePicture call). However, this would substantially increase the
// first capture latency on HAL3 devices, and potentially on some HAL2
@@ -788,6 +794,19 @@ status_t Camera2Client::startPreviewL(Parameters &params, bool restart) {
return res;
}
outputStreams.push(getCallbackStreamId());
+ } else if (previewStreamChanged && mCallbackProcessor->getStreamId() != NO_STREAM) {
+ /**
+ * Delete the unused callback stream when preview stream is changed and
+ * preview is not enabled. Don't need stop preview stream as preview is in
+ * STOPPED state now.
+ */
+ ALOGV("%s: Camera %d: Delete unused preview callback stream.", __FUNCTION__, mCameraId);
+ res = mCallbackProcessor->deleteStream();
+ if (res != OK) {
+ ALOGE("%s: Camera %d: Unable to delete callback stream %s (%d)",
+ __FUNCTION__, mCameraId, strerror(-res), res);
+ return res;
+ }
}
if (params.zslMode && !params.recordingHint) {
res = updateProcessorStream(mZslProcessor, params);
diff --git a/services/camera/libcameraservice/api1/CameraClient.cpp b/services/camera/libcameraservice/api1/CameraClient.cpp
index bd6805d..30b7bb8 100644
--- a/services/camera/libcameraservice/api1/CameraClient.cpp
+++ b/services/camera/libcameraservice/api1/CameraClient.cpp
@@ -85,7 +85,7 @@ status_t CameraClient::initialize(camera_module_t *module) {
mHardware->setCallbacks(notifyCallback,
dataCallback,
dataCallbackTimestamp,
- (void *)mCameraId);
+ (void *)(uintptr_t)mCameraId);
// Enable zoom, error, focus, and metadata messages by default
enableMsgType(CAMERA_MSG_ERROR | CAMERA_MSG_ZOOM | CAMERA_MSG_FOCUS |
diff --git a/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp b/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp
index 8a4ce4e..f5c28ed 100644
--- a/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp
+++ b/services/camera/libcameraservice/api1/client2/CaptureSequencer.cpp
@@ -18,6 +18,8 @@
#define ATRACE_TAG ATRACE_TAG_CAMERA
//#define LOG_NDEBUG 0
+#include <inttypes.h>
+
#include <utils/Log.h>
#include <utils/Trace.h>
#include <utils/Vector.h>
@@ -585,8 +587,8 @@ CaptureSequencer::CaptureState CaptureSequencer::manageStandardCaptureWait(
ALOGE("No timestamp field in capture frame!");
}
if (entry.data.i64[0] != mCaptureTimestamp) {
- ALOGW("Mismatched capture timestamps: Metadata frame %lld,"
- " captured buffer %lld",
+ ALOGW("Mismatched capture timestamps: Metadata frame %" PRId64 ","
+ " captured buffer %" PRId64,
entry.data.i64[0],
mCaptureTimestamp);
}
diff --git a/services/camera/libcameraservice/api1/client2/FrameProcessor.cpp b/services/camera/libcameraservice/api1/client2/FrameProcessor.cpp
index 19acae4..dd5b27c 100644
--- a/services/camera/libcameraservice/api1/client2/FrameProcessor.cpp
+++ b/services/camera/libcameraservice/api1/client2/FrameProcessor.cpp
@@ -168,7 +168,7 @@ status_t FrameProcessor::processFaceDetect(const CameraMetadata &frame,
continue;
}
if (faceScores[i] > 100) {
- ALOGW("%s: Face index %d with out of range score %d",
+ ALOGW("%s: Face index %zu with out of range score %d",
__FUNCTION__, i, faceScores[i]);
}
diff --git a/services/camera/libcameraservice/api1/client2/JpegCompressor.cpp b/services/camera/libcameraservice/api1/client2/JpegCompressor.cpp
index 2f0c67d..9ecab71 100644
--- a/services/camera/libcameraservice/api1/client2/JpegCompressor.cpp
+++ b/services/camera/libcameraservice/api1/client2/JpegCompressor.cpp
@@ -197,7 +197,7 @@ void JpegCompressor::jpegErrorHandler(j_common_ptr cinfo) {
void JpegCompressor::jpegInitDestination(j_compress_ptr cinfo) {
ALOGV("%s", __FUNCTION__);
JpegDestination *dest= static_cast<JpegDestination*>(cinfo->dest);
- ALOGV("%s: Setting destination to %p, size %d",
+ ALOGV("%s: Setting destination to %p, size %zu",
__FUNCTION__, dest->parent->mJpegBuffer->data, kMaxJpegSize);
dest->next_output_byte = (JOCTET*)(dest->parent->mJpegBuffer->data);
dest->free_in_buffer = kMaxJpegSize;
@@ -213,7 +213,7 @@ boolean JpegCompressor::jpegEmptyOutputBuffer(j_compress_ptr /*cinfo*/) {
void JpegCompressor::jpegTermDestination(j_compress_ptr cinfo) {
(void) cinfo; // TODO: clean up
ALOGV("%s", __FUNCTION__);
- ALOGV("%s: Done writing JPEG data. %d bytes left in buffer",
+ ALOGV("%s: Done writing JPEG data. %zu bytes left in buffer",
__FUNCTION__, cinfo->dest->free_in_buffer);
}
diff --git a/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp b/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp
index 77d5c8a..2de7a2b 100644
--- a/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp
+++ b/services/camera/libcameraservice/api1/client2/JpegProcessor.cpp
@@ -200,50 +200,59 @@ status_t JpegProcessor::processNewCapture() {
ATRACE_CALL();
status_t res;
sp<Camera2Heap> captureHeap;
+ sp<MemoryBase> captureBuffer;
CpuConsumer::LockedBuffer imgBuffer;
- res = mCaptureConsumer->lockNextBuffer(&imgBuffer);
- if (res != OK) {
- if (res != BAD_VALUE) {
- ALOGE("%s: Camera %d: Error receiving still image buffer: "
- "%s (%d)", __FUNCTION__,
- mId, strerror(-res), res);
+ {
+ Mutex::Autolock l(mInputMutex);
+ if (mCaptureStreamId == NO_STREAM) {
+ ALOGW("%s: Camera %d: No stream is available", __FUNCTION__, mId);
+ return INVALID_OPERATION;
}
- return res;
- }
- ALOGV("%s: Camera %d: Still capture available", __FUNCTION__,
- mId);
+ res = mCaptureConsumer->lockNextBuffer(&imgBuffer);
+ if (res != OK) {
+ if (res != BAD_VALUE) {
+ ALOGE("%s: Camera %d: Error receiving still image buffer: "
+ "%s (%d)", __FUNCTION__,
+ mId, strerror(-res), res);
+ }
+ return res;
+ }
- if (imgBuffer.format != HAL_PIXEL_FORMAT_BLOB) {
- ALOGE("%s: Camera %d: Unexpected format for still image: "
- "%x, expected %x", __FUNCTION__, mId,
- imgBuffer.format,
- HAL_PIXEL_FORMAT_BLOB);
- mCaptureConsumer->unlockBuffer(imgBuffer);
- return OK;
- }
+ ALOGV("%s: Camera %d: Still capture available", __FUNCTION__,
+ mId);
- // Find size of JPEG image
- size_t jpegSize = findJpegSize(imgBuffer.data, imgBuffer.width);
- if (jpegSize == 0) { // failed to find size, default to whole buffer
- jpegSize = imgBuffer.width;
- }
- size_t heapSize = mCaptureHeap->getSize();
- if (jpegSize > heapSize) {
- ALOGW("%s: JPEG image is larger than expected, truncating "
- "(got %d, expected at most %d bytes)",
- __FUNCTION__, jpegSize, heapSize);
- jpegSize = heapSize;
- }
+ if (imgBuffer.format != HAL_PIXEL_FORMAT_BLOB) {
+ ALOGE("%s: Camera %d: Unexpected format for still image: "
+ "%x, expected %x", __FUNCTION__, mId,
+ imgBuffer.format,
+ HAL_PIXEL_FORMAT_BLOB);
+ mCaptureConsumer->unlockBuffer(imgBuffer);
+ return OK;
+ }
- // TODO: Optimize this to avoid memcopy
- sp<MemoryBase> captureBuffer = new MemoryBase(mCaptureHeap, 0, jpegSize);
- void* captureMemory = mCaptureHeap->getBase();
- memcpy(captureMemory, imgBuffer.data, jpegSize);
+ // Find size of JPEG image
+ size_t jpegSize = findJpegSize(imgBuffer.data, imgBuffer.width);
+ if (jpegSize == 0) { // failed to find size, default to whole buffer
+ jpegSize = imgBuffer.width;
+ }
+ size_t heapSize = mCaptureHeap->getSize();
+ if (jpegSize > heapSize) {
+ ALOGW("%s: JPEG image is larger than expected, truncating "
+ "(got %zu, expected at most %zu bytes)",
+ __FUNCTION__, jpegSize, heapSize);
+ jpegSize = heapSize;
+ }
+
+ // TODO: Optimize this to avoid memcopy
+ captureBuffer = new MemoryBase(mCaptureHeap, 0, jpegSize);
+ void* captureMemory = mCaptureHeap->getBase();
+ memcpy(captureMemory, imgBuffer.data, jpegSize);
- mCaptureConsumer->unlockBuffer(imgBuffer);
+ mCaptureConsumer->unlockBuffer(imgBuffer);
+ }
sp<CaptureSequencer> sequencer = mSequencer.promote();
if (sequencer != 0) {
@@ -326,13 +335,13 @@ size_t JpegProcessor::findJpegSize(uint8_t* jpegBuffer, size_t maxSize) {
size_t offset = size - MARKER_LENGTH;
uint8_t *end = jpegBuffer + offset;
if (checkJpegStart(jpegBuffer) && checkJpegEnd(end)) {
- ALOGV("Found JPEG transport header, img size %d", size);
+ ALOGV("Found JPEG transport header, img size %zu", size);
return size;
} else {
ALOGW("Found JPEG transport header with bad Image Start/End");
}
} else {
- ALOGW("Found JPEG transport header with bad size %d", size);
+ ALOGW("Found JPEG transport header with bad size %zu", size);
}
}
@@ -348,15 +357,15 @@ size_t JpegProcessor::findJpegSize(uint8_t* jpegBuffer, size_t maxSize) {
segment_t *segment = (segment_t*)(jpegBuffer + size);
uint8_t type = checkJpegMarker(segment->marker);
if (type == 0) { // invalid marker, no more segments, begin JPEG data
- ALOGV("JPEG stream found beginning at offset %d", size);
+ ALOGV("JPEG stream found beginning at offset %zu", size);
break;
}
if (type == EOI || size > maxSize - sizeof(segment_t)) {
- ALOGE("Got premature End before JPEG data, offset %d", size);
+ ALOGE("Got premature End before JPEG data, offset %zu", size);
return 0;
}
size_t length = ntohs(segment->length);
- ALOGV("JFIF Segment, type %x length %x", type, length);
+ ALOGV("JFIF Segment, type %x length %zx", type, length);
size += length + MARKER_LENGTH;
}
@@ -376,10 +385,10 @@ size_t JpegProcessor::findJpegSize(uint8_t* jpegBuffer, size_t maxSize) {
}
if (size > maxSize) {
- ALOGW("JPEG size %d too large, reducing to maxSize %d", size, maxSize);
+ ALOGW("JPEG size %zu too large, reducing to maxSize %zu", size, maxSize);
size = maxSize;
}
- ALOGV("Final JPEG size %d", size);
+ ALOGV("Final JPEG size %zu", size);
return size;
}
diff --git a/services/camera/libcameraservice/api1/client2/Parameters.cpp b/services/camera/libcameraservice/api1/client2/Parameters.cpp
index 08af566..081a6e6 100644
--- a/services/camera/libcameraservice/api1/client2/Parameters.cpp
+++ b/services/camera/libcameraservice/api1/client2/Parameters.cpp
@@ -16,7 +16,7 @@
#define LOG_TAG "Camera2-Parameters"
#define ATRACE_TAG ATRACE_TAG_CAMERA
-//#define LOG_NDEBUG 0
+// #define LOG_NDEBUG 0
#include <utils/Log.h>
#include <utils/Trace.h>
@@ -92,26 +92,6 @@ status_t Parameters::initialize(const CameraMetadata *info) {
staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
if (!availableFpsRanges.count) return NO_INIT;
- previewFpsRange[0] = availableFpsRanges.data.i32[0];
- previewFpsRange[1] = availableFpsRanges.data.i32[1];
-
- params.set(CameraParameters::KEY_PREVIEW_FPS_RANGE,
- String8::format("%d,%d",
- previewFpsRange[0] * kFpsToApiScale,
- previewFpsRange[1] * kFpsToApiScale));
-
- {
- String8 supportedPreviewFpsRange;
- for (size_t i=0; i < availableFpsRanges.count; i += 2) {
- if (i != 0) supportedPreviewFpsRange += ",";
- supportedPreviewFpsRange += String8::format("(%d,%d)",
- availableFpsRanges.data.i32[i] * kFpsToApiScale,
- availableFpsRanges.data.i32[i+1] * kFpsToApiScale);
- }
- params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE,
- supportedPreviewFpsRange);
- }
-
previewFormat = HAL_PIXEL_FORMAT_YCrCb_420_SP;
params.set(CameraParameters::KEY_PREVIEW_FORMAT,
formatEnumToString(previewFormat)); // NV21
@@ -179,6 +159,9 @@ status_t Parameters::initialize(const CameraMetadata *info) {
supportedPreviewFormats);
}
+ previewFpsRange[0] = availableFpsRanges.data.i32[0];
+ previewFpsRange[1] = availableFpsRanges.data.i32[1];
+
// PREVIEW_FRAME_RATE / SUPPORTED_PREVIEW_FRAME_RATES are deprecated, but
// still have to do something sane for them
@@ -187,6 +170,27 @@ status_t Parameters::initialize(const CameraMetadata *info) {
params.set(CameraParameters::KEY_PREVIEW_FRAME_RATE,
previewFps);
+ // PREVIEW_FPS_RANGE
+ // -- Order matters. Set range after single value to so that a roundtrip
+ // of setParameters(getParameters()) would keep the FPS range in higher
+ // order.
+ params.set(CameraParameters::KEY_PREVIEW_FPS_RANGE,
+ String8::format("%d,%d",
+ previewFpsRange[0] * kFpsToApiScale,
+ previewFpsRange[1] * kFpsToApiScale));
+
+ {
+ String8 supportedPreviewFpsRange;
+ for (size_t i=0; i < availableFpsRanges.count; i += 2) {
+ if (i != 0) supportedPreviewFpsRange += ",";
+ supportedPreviewFpsRange += String8::format("(%d,%d)",
+ availableFpsRanges.data.i32[i] * kFpsToApiScale,
+ availableFpsRanges.data.i32[i+1] * kFpsToApiScale);
+ }
+ params.set(CameraParameters::KEY_SUPPORTED_PREVIEW_FPS_RANGE,
+ supportedPreviewFpsRange);
+ }
+
{
SortedVector<int32_t> sortedPreviewFrameRates;
@@ -944,7 +948,7 @@ status_t Parameters::buildFastInfo() {
if (sceneModeOverrides.count !=
availableSceneModes.count * kModesPerSceneMode) {
ALOGE("%s: Camera %d: Scene mode override list is an "
- "unexpected size: %d (expected %d)", __FUNCTION__,
+ "unexpected size: %zu (expected %zu)", __FUNCTION__,
cameraId, sceneModeOverrides.count,
availableSceneModes.count);
return NO_INIT;
@@ -1074,7 +1078,7 @@ camera_metadata_ro_entry_t Parameters::staticInfo(uint32_t tag,
const char* tagName = get_camera_metadata_tag_name(tag);
if (tagName == NULL) tagName = "<unknown>";
ALOGE("Malformed static metadata entry '%s.%s' (%x):"
- "Expected between %d and %d values, but got %d values",
+ "Expected between %zu and %zu values, but got %zu values",
tagSection, tagName, tag, minCount, maxCount, entry.count);
}
@@ -1084,7 +1088,7 @@ camera_metadata_ro_entry_t Parameters::staticInfo(uint32_t tag,
status_t Parameters::set(const String8& paramString) {
status_t res;
- CameraParameters newParams(paramString);
+ CameraParameters2 newParams(paramString);
// TODO: Currently ignoring any changes to supposedly read-only parameters
// such as supported preview sizes, etc. Should probably produce an error if
@@ -1127,29 +1131,73 @@ status_t Parameters::set(const String8& paramString) {
// RECORDING_HINT (always supported)
validatedParams.recordingHint = boolFromString(
newParams.get(CameraParameters::KEY_RECORDING_HINT) );
- bool recordingHintChanged = validatedParams.recordingHint != recordingHint;
- ALOGV_IF(recordingHintChanged, "%s: Recording hint changed to %d",
- __FUNCTION__, recordingHintChanged);
+ IF_ALOGV() { // Avoid unused variable warning
+ bool recordingHintChanged =
+ validatedParams.recordingHint != recordingHint;
+ if (recordingHintChanged) {
+ ALOGV("%s: Recording hint changed to %d",
+ __FUNCTION__, validatedParams.recordingHint);
+ }
+ }
// PREVIEW_FPS_RANGE
- bool fpsRangeChanged = false;
- int32_t lastSetFpsRange[2];
- params.getPreviewFpsRange(&lastSetFpsRange[0], &lastSetFpsRange[1]);
- lastSetFpsRange[0] /= kFpsToApiScale;
- lastSetFpsRange[1] /= kFpsToApiScale;
+ /**
+ * Use the single FPS value if it was set later than the range.
+ * Otherwise, use the range value.
+ */
+ bool fpsUseSingleValue;
+ {
+ const char *fpsRange, *fpsSingle;
+
+ fpsRange = newParams.get(CameraParameters::KEY_PREVIEW_FRAME_RATE);
+ fpsSingle = newParams.get(CameraParameters::KEY_PREVIEW_FPS_RANGE);
+ /**
+ * Pick either the range or the single key if only one was set.
+ *
+ * If both are set, pick the one that has greater set order.
+ */
+ if (fpsRange == NULL && fpsSingle == NULL) {
+ ALOGE("%s: FPS was not set. One of %s or %s must be set.",
+ __FUNCTION__, CameraParameters::KEY_PREVIEW_FRAME_RATE,
+ CameraParameters::KEY_PREVIEW_FPS_RANGE);
+ return BAD_VALUE;
+ } else if (fpsRange == NULL) {
+ fpsUseSingleValue = true;
+ ALOGV("%s: FPS range not set, using FPS single value",
+ __FUNCTION__);
+ } else if (fpsSingle == NULL) {
+ fpsUseSingleValue = false;
+ ALOGV("%s: FPS single not set, using FPS range value",
+ __FUNCTION__);
+ } else {
+ int fpsKeyOrder;
+ res = newParams.compareSetOrder(
+ CameraParameters::KEY_PREVIEW_FRAME_RATE,
+ CameraParameters::KEY_PREVIEW_FPS_RANGE,
+ &fpsKeyOrder);
+ LOG_ALWAYS_FATAL_IF(res != OK, "Impossibly bad FPS keys");
+
+ fpsUseSingleValue = (fpsKeyOrder > 0);
+
+ }
+
+ ALOGV("%s: Preview FPS value is used from '%s'",
+ __FUNCTION__, fpsUseSingleValue ? "single" : "range");
+ }
newParams.getPreviewFpsRange(&validatedParams.previewFpsRange[0],
&validatedParams.previewFpsRange[1]);
+
validatedParams.previewFpsRange[0] /= kFpsToApiScale;
validatedParams.previewFpsRange[1] /= kFpsToApiScale;
- // Compare the FPS range value from the last set() to the current set()
- // to determine if the client has changed it
- if (validatedParams.previewFpsRange[0] != lastSetFpsRange[0] ||
- validatedParams.previewFpsRange[1] != lastSetFpsRange[1]) {
+ // Ignore the FPS range if the FPS single has higher precedence
+ if (!fpsUseSingleValue) {
+ ALOGV("%s: Preview FPS range (%d, %d)", __FUNCTION__,
+ validatedParams.previewFpsRange[0],
+ validatedParams.previewFpsRange[1]);
- fpsRangeChanged = true;
camera_metadata_ro_entry_t availablePreviewFpsRanges =
staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, 2);
for (i = 0; i < availablePreviewFpsRanges.count; i += 2) {
@@ -1200,14 +1248,13 @@ status_t Parameters::set(const String8& paramString) {
}
}
- // PREVIEW_FRAME_RATE Deprecated, only use if the preview fps range is
- // unchanged this time. The single-value FPS is the same as the minimum of
- // the range. To detect whether the application has changed the value of
- // previewFps, compare against their last-set preview FPS.
- if (!fpsRangeChanged) {
+ // PREVIEW_FRAME_RATE Deprecated
+ // - Use only if the single FPS value was set later than the FPS range
+ if (fpsUseSingleValue) {
int previewFps = newParams.getPreviewFrameRate();
- int lastSetPreviewFps = params.getPreviewFrameRate();
- if (previewFps != lastSetPreviewFps || recordingHintChanged) {
+ ALOGV("%s: Preview FPS single value requested: %d",
+ __FUNCTION__, previewFps);
+ {
camera_metadata_ro_entry_t availableFrameRates =
staticInfo(ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
/**
@@ -1276,6 +1323,35 @@ status_t Parameters::set(const String8& paramString) {
}
}
+ /**
+ * Update Preview FPS and Preview FPS ranges based on
+ * what we actually set.
+ *
+ * This updates the API-visible (Camera.Parameters#getParameters) values of
+ * the FPS fields, not only the internal versions.
+ *
+ * Order matters: The value that was set last takes precedence.
+ * - If the client does a setParameters(getParameters()) we retain
+ * the same order for preview FPS.
+ */
+ if (!fpsUseSingleValue) {
+ // Set fps single, then fps range (range wins)
+ newParams.setPreviewFrameRate(
+ fpsFromRange(/*min*/validatedParams.previewFpsRange[0],
+ /*max*/validatedParams.previewFpsRange[1]));
+ newParams.setPreviewFpsRange(
+ validatedParams.previewFpsRange[0] * kFpsToApiScale,
+ validatedParams.previewFpsRange[1] * kFpsToApiScale);
+ } else {
+ // Set fps range, then fps single (single wins)
+ newParams.setPreviewFpsRange(
+ validatedParams.previewFpsRange[0] * kFpsToApiScale,
+ validatedParams.previewFpsRange[1] * kFpsToApiScale);
+ // Set this to the same value, but with higher priority
+ newParams.setPreviewFrameRate(
+ newParams.getPreviewFrameRate());
+ }
+
// PICTURE_SIZE
newParams.getPictureSize(&validatedParams.pictureWidth,
&validatedParams.pictureHeight);
@@ -1750,6 +1826,9 @@ status_t Parameters::updateRequest(CameraMetadata *request) const {
camera_metadata_entry_t intent =
request->find(ANDROID_CONTROL_CAPTURE_INTENT);
+
+ if (intent.count == 0) return BAD_VALUE;
+
if (intent.data.u8[0] == ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE) {
res = request->update(ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
fastInfo.bestStillCaptureFpsRange, 2);
@@ -1858,23 +1937,23 @@ status_t Parameters::updateRequest(CameraMetadata *request) const {
size_t reqFocusingAreasSize = focusingAreas.size() * 5;
int32_t *reqFocusingAreas = new int32_t[reqFocusingAreasSize];
- for (size_t i = 0; i < reqFocusingAreasSize; i += 5) {
- if (focusingAreas[i].weight != 0) {
+ for (size_t i = 0, j = 0; i < reqFocusingAreasSize; i += 5, j++) {
+ if (focusingAreas[j].weight != 0) {
reqFocusingAreas[i + 0] =
- normalizedXToArray(focusingAreas[i].left);
+ normalizedXToArray(focusingAreas[j].left);
reqFocusingAreas[i + 1] =
- normalizedYToArray(focusingAreas[i].top);
+ normalizedYToArray(focusingAreas[j].top);
reqFocusingAreas[i + 2] =
- normalizedXToArray(focusingAreas[i].right);
+ normalizedXToArray(focusingAreas[j].right);
reqFocusingAreas[i + 3] =
- normalizedYToArray(focusingAreas[i].bottom);
+ normalizedYToArray(focusingAreas[j].bottom);
} else {
reqFocusingAreas[i + 0] = 0;
reqFocusingAreas[i + 1] = 0;
reqFocusingAreas[i + 2] = 0;
reqFocusingAreas[i + 3] = 0;
}
- reqFocusingAreas[i + 4] = focusingAreas[i].weight;
+ reqFocusingAreas[i + 4] = focusingAreas[j].weight;
}
res = request->update(ANDROID_CONTROL_AF_REGIONS,
reqFocusingAreas, reqFocusingAreasSize);
@@ -1887,23 +1966,23 @@ status_t Parameters::updateRequest(CameraMetadata *request) const {
size_t reqMeteringAreasSize = meteringAreas.size() * 5;
int32_t *reqMeteringAreas = new int32_t[reqMeteringAreasSize];
- for (size_t i = 0; i < reqMeteringAreasSize; i += 5) {
- if (meteringAreas[i].weight != 0) {
+ for (size_t i = 0, j = 0; i < reqMeteringAreasSize; i += 5, j++) {
+ if (meteringAreas[j].weight != 0) {
reqMeteringAreas[i + 0] =
- normalizedXToArray(meteringAreas[i].left);
+ normalizedXToArray(meteringAreas[j].left);
reqMeteringAreas[i + 1] =
- normalizedYToArray(meteringAreas[i].top);
+ normalizedYToArray(meteringAreas[j].top);
reqMeteringAreas[i + 2] =
- normalizedXToArray(meteringAreas[i].right);
+ normalizedXToArray(meteringAreas[j].right);
reqMeteringAreas[i + 3] =
- normalizedYToArray(meteringAreas[i].bottom);
+ normalizedYToArray(meteringAreas[j].bottom);
} else {
reqMeteringAreas[i + 0] = 0;
reqMeteringAreas[i + 1] = 0;
reqMeteringAreas[i + 2] = 0;
reqMeteringAreas[i + 3] = 0;
}
- reqMeteringAreas[i + 4] = meteringAreas[i].weight;
+ reqMeteringAreas[i + 4] = meteringAreas[j].weight;
}
res = request->update(ANDROID_CONTROL_AE_REGIONS,
reqMeteringAreas, reqMeteringAreasSize);
@@ -2330,7 +2409,7 @@ status_t Parameters::validateAreas(const Vector<Parameters::Area> &areas,
}
if (areas.size() > maxRegions) {
- ALOGE("%s: Too many areas requested: %d",
+ ALOGE("%s: Too many areas requested: %zu",
__FUNCTION__, areas.size());
return BAD_VALUE;
}
diff --git a/services/camera/libcameraservice/api1/client2/Parameters.h b/services/camera/libcameraservice/api1/client2/Parameters.h
index 32dbd42..da07ccf 100644
--- a/services/camera/libcameraservice/api1/client2/Parameters.h
+++ b/services/camera/libcameraservice/api1/client2/Parameters.h
@@ -25,6 +25,7 @@
#include <utils/Vector.h>
#include <utils/KeyedVector.h>
#include <camera/CameraParameters.h>
+#include <camera/CameraParameters2.h>
#include <camera/CameraMetadata.h>
namespace android {
@@ -32,7 +33,7 @@ namespace camera2 {
/**
* Current camera state; this is the full state of the Camera under the old
- * camera API (contents of the CameraParameters object in a more-efficient
+ * camera API (contents of the CameraParameters2 object in a more-efficient
* format, plus other state). The enum values are mostly based off the
* corresponding camera2 enums, not the camera1 strings. A few are defined here
* if they don't cleanly map to camera2 values.
@@ -128,7 +129,7 @@ struct Parameters {
LIGHTFX_HDR
} lightFx;
- CameraParameters params;
+ CameraParameters2 params;
String8 paramsFlattened;
// These parameters are also part of the camera API-visible state, but not
diff --git a/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp b/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp
index 6076dae..77ae7ec 100644
--- a/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp
+++ b/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp
@@ -225,14 +225,14 @@ status_t StreamingProcessor::setRecordingBufferCount(size_t count) {
ATRACE_CALL();
// Make sure we can support this many buffer slots
if (count > BufferQueue::NUM_BUFFER_SLOTS) {
- ALOGE("%s: Camera %d: Too many recording buffers requested: %d, max %d",
+ ALOGE("%s: Camera %d: Too many recording buffers requested: %zu, max %d",
__FUNCTION__, mId, count, BufferQueue::NUM_BUFFER_SLOTS);
return BAD_VALUE;
}
Mutex::Autolock m(mMutex);
- ALOGV("%s: Camera %d: New recording buffer count from encoder: %d",
+ ALOGV("%s: Camera %d: New recording buffer count from encoder: %zu",
__FUNCTION__, mId, count);
// Need to re-size consumer and heap
@@ -314,7 +314,7 @@ status_t StreamingProcessor::updateRecordingStream(const Parameters &params) {
bool newConsumer = false;
if (mRecordingConsumer == 0) {
- ALOGV("%s: Camera %d: Creating recording consumer with %d + 1 "
+ ALOGV("%s: Camera %d: Creating recording consumer with %zu + 1 "
"consumer-side buffers", __FUNCTION__, mId, mRecordingHeapCount);
// Create CPU buffer queue endpoint. We need one more buffer here so that we can
// always acquire and free a buffer when the heap is full; otherwise the consumer
@@ -435,7 +435,7 @@ status_t StreamingProcessor::startStream(StreamType type,
releaseAllRecordingFramesLocked();
}
- ALOGV("%s: Camera %d: %s started, recording heap has %d free of %d",
+ ALOGV("%s: Camera %d: %s started, recording heap has %zu free of %zu",
__FUNCTION__, mId, (type == PREVIEW) ? "preview" : "recording",
mRecordingHeapFree, mRecordingHeapCount);
@@ -658,8 +658,8 @@ status_t StreamingProcessor::processRecordingFrame() {
if (mRecordingHeap == 0) {
const size_t bufferSize = 4 + sizeof(buffer_handle_t);
- ALOGV("%s: Camera %d: Creating recording heap with %d buffers of "
- "size %d bytes", __FUNCTION__, mId,
+ ALOGV("%s: Camera %d: Creating recording heap with %zu buffers of "
+ "size %zu bytes", __FUNCTION__, mId,
mRecordingHeapCount, bufferSize);
mRecordingHeap = new Camera2Heap(bufferSize, mRecordingHeapCount,
@@ -819,10 +819,10 @@ void StreamingProcessor::releaseAllRecordingFramesLocked() {
}
if (releasedCount > 0) {
- ALOGW("%s: Camera %d: Force-freed %d outstanding buffers "
+ ALOGW("%s: Camera %d: Force-freed %zu outstanding buffers "
"from previous recording session", __FUNCTION__, mId, releasedCount);
ALOGE_IF(releasedCount != mRecordingHeapCount - mRecordingHeapFree,
- "%s: Camera %d: Force-freed %d buffers, but expected %d",
+ "%s: Camera %d: Force-freed %zu buffers, but expected %zu",
__FUNCTION__, mId, releasedCount, mRecordingHeapCount - mRecordingHeapFree);
}
diff --git a/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp b/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp
index 4207ba9..130f81a 100644
--- a/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp
+++ b/services/camera/libcameraservice/api1/client2/ZslProcessor.cpp
@@ -25,6 +25,8 @@
#define ALOGVV(...) ((void)0)
#endif
+#include <inttypes.h>
+
#include <utils/Log.h>
#include <utils/Trace.h>
#include <gui/Surface.h>
@@ -78,7 +80,7 @@ void ZslProcessor::onFrameAvailable(int32_t /*requestId*/,
entry = frame.find(ANDROID_SENSOR_TIMESTAMP);
nsecs_t timestamp = entry.data.i64[0];
(void)timestamp;
- ALOGVV("Got preview frame for timestamp %lld", timestamp);
+ ALOGVV("Got preview frame for timestamp %" PRId64, timestamp);
if (mState != RUNNING) return;
@@ -461,7 +463,7 @@ status_t ZslProcessor::processNewZslBuffer() {
mZslQueueHead = (mZslQueueHead + 1) % kZslBufferDepth;
- ALOGVV(" Acquired buffer, timestamp %lld", queueHead.buffer.mTimestamp);
+ ALOGVV(" Acquired buffer, timestamp %" PRId64, queueHead.buffer.mTimestamp);
findMatchesLocked();
@@ -480,7 +482,7 @@ void ZslProcessor::findMatchesLocked() {
entry = queueEntry.frame.find(ANDROID_SENSOR_TIMESTAMP);
frameTimestamp = entry.data.i64[0];
}
- ALOGVV(" %d: b: %lld\tf: %lld", i,
+ ALOGVV(" %d: b: %" PRId64 "\tf: %" PRId64, i,
bufferTimestamp, frameTimestamp );
}
if (queueEntry.frame.isEmpty() && bufferTimestamp != 0) {
@@ -498,13 +500,13 @@ void ZslProcessor::findMatchesLocked() {
}
nsecs_t frameTimestamp = entry.data.i64[0];
if (bufferTimestamp == frameTimestamp) {
- ALOGVV("%s: Found match %lld", __FUNCTION__,
+ ALOGVV("%s: Found match %" PRId64, __FUNCTION__,
frameTimestamp);
match = true;
} else {
int64_t delta = abs(bufferTimestamp - frameTimestamp);
if ( delta < 1000000) {
- ALOGVV("%s: Found close match %lld (delta %lld)",
+ ALOGVV("%s: Found close match %" PRId64 " (delta %" PRId64 ")",
__FUNCTION__, bufferTimestamp, delta);
match = true;
}
@@ -540,7 +542,7 @@ void ZslProcessor::dumpZslQueue(int fd) const {
if (entry.count > 0) frameAeState = entry.data.u8[0];
}
String8 result =
- String8::format(" %d: b: %lld\tf: %lld, AE state: %d", i,
+ String8::format(" %zu: b: %" PRId64 "\tf: %" PRId64 ", AE state: %d", i,
bufferTimestamp, frameTimestamp, frameAeState);
ALOGV("%s", result.string());
if (fd != -1) {
diff --git a/services/camera/libcameraservice/api1/client2/ZslProcessor3.cpp b/services/camera/libcameraservice/api1/client2/ZslProcessor3.cpp
index 776ebe2..2fce2b6 100644
--- a/services/camera/libcameraservice/api1/client2/ZslProcessor3.cpp
+++ b/services/camera/libcameraservice/api1/client2/ZslProcessor3.cpp
@@ -25,6 +25,8 @@
#define ALOGVV(...) ((void)0)
#endif
+#include <inttypes.h>
+
#include <utils/Log.h>
#include <utils/Trace.h>
#include <gui/Surface.h>
@@ -68,7 +70,7 @@ void ZslProcessor3::onFrameAvailable(int32_t /*requestId*/,
entry = frame.find(ANDROID_SENSOR_TIMESTAMP);
nsecs_t timestamp = entry.data.i64[0];
(void)timestamp;
- ALOGVV("Got preview metadata for timestamp %lld", timestamp);
+ ALOGVV("Got preview metadata for timestamp %" PRId64, timestamp);
if (mState != RUNNING) return;
@@ -355,7 +357,7 @@ void ZslProcessor3::dumpZslQueue(int fd) const {
if (entry.count > 0) frameAeState = entry.data.u8[0];
}
String8 result =
- String8::format(" %d: b: %lld\tf: %lld, AE state: %d", i,
+ String8::format(" %zu: b: %" PRId64 "\tf: %" PRId64 ", AE state: %d", i,
bufferTimestamp, frameTimestamp, frameAeState);
ALOGV("%s", result.string());
if (fd != -1) {
@@ -415,7 +417,7 @@ nsecs_t ZslProcessor3::getCandidateTimestampLocked(size_t* metadataIdx) const {
idx = j;
}
- ALOGVV("%s: Saw timestamp %lld", __FUNCTION__, frameTimestamp);
+ ALOGVV("%s: Saw timestamp %" PRId64, __FUNCTION__, frameTimestamp);
}
}
@@ -435,7 +437,7 @@ nsecs_t ZslProcessor3::getCandidateTimestampLocked(size_t* metadataIdx) const {
ALOGW("%s: ZSL queue has no metadata frames", __FUNCTION__);
}
- ALOGV("%s: Candidate timestamp %lld (idx %d), empty frames: %d",
+ ALOGV("%s: Candidate timestamp %" PRId64 " (idx %zu), empty frames: %zu",
__FUNCTION__, minTimestamp, idx, emptyCount);
if (metadataIdx) {
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index 1cdf8dc..142da9e 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -284,7 +284,7 @@ status_t CameraDeviceClient::createStream(int width, int height, int format,
ssize_t index = mStreamMap.indexOfKey(bufferProducer->asBinder());
if (index != NAME_NOT_FOUND) {
ALOGW("%s: Camera %d: Buffer producer already has a stream for it "
- "(ID %d)",
+ "(ID %zd)",
__FUNCTION__, mCameraId, index);
return ALREADY_EXISTS;
}
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.cpp b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
index 2d1253f..6a88c87 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.cpp
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
@@ -18,6 +18,8 @@
#define ATRACE_TAG ATRACE_TAG_CAMERA
//#define LOG_NDEBUG 0
+#include <inttypes.h>
+
#include <utils/Log.h>
#include <utils/Trace.h>
@@ -236,7 +238,7 @@ void Camera2ClientBase<TClientBase>::notifyShutter(int requestId,
(void)requestId;
(void)timestamp;
- ALOGV("%s: Shutter notification for request id %d at time %lld",
+ ALOGV("%s: Shutter notification for request id %d at time %" PRId64,
__FUNCTION__, requestId, timestamp);
}
diff --git a/services/camera/libcameraservice/common/FrameProcessorBase.cpp b/services/camera/libcameraservice/common/FrameProcessorBase.cpp
index f2064fb..4d31667 100644
--- a/services/camera/libcameraservice/common/FrameProcessorBase.cpp
+++ b/services/camera/libcameraservice/common/FrameProcessorBase.cpp
@@ -183,7 +183,7 @@ status_t FrameProcessorBase::processListeners(const CameraMetadata &frame,
item++;
}
}
- ALOGV("Got %d range listeners out of %d", listeners.size(), mRangeListeners.size());
+ ALOGV("Got %zu range listeners out of %zu", listeners.size(), mRangeListeners.size());
List<sp<FilteredListener> >::iterator item = listeners.begin();
for (; item != listeners.end(); item++) {
(*item)->onFrameAvailable(requestId, frame);
diff --git a/services/camera/libcameraservice/device2/Camera2Device.cpp b/services/camera/libcameraservice/device2/Camera2Device.cpp
index 2bc1a8a..2966d82 100644
--- a/services/camera/libcameraservice/device2/Camera2Device.cpp
+++ b/services/camera/libcameraservice/device2/Camera2Device.cpp
@@ -25,6 +25,7 @@
#define ALOGVV(...) ((void)0)
#endif
+#include <inttypes.h>
#include <utils/Log.h>
#include <utils/Trace.h>
#include <utils/Timers.h>
@@ -822,7 +823,7 @@ status_t Camera2Device::MetadataQueue::dump(int fd,
result.append(" Stream slot: Empty\n");
write(fd, result.string(), result.size());
} else {
- result.appendFormat(" Stream slot: %d entries\n",
+ result.appendFormat(" Stream slot: %zu entries\n",
mStreamSlot.size());
int i = 0;
for (List<camera_metadata_t*>::iterator r = mStreamSlot.begin();
@@ -837,7 +838,7 @@ status_t Camera2Device::MetadataQueue::dump(int fd,
result = " Main queue is empty\n";
write(fd, result.string(), result.size());
} else {
- result = String8::format(" Main queue has %d entries:\n",
+ result = String8::format(" Main queue has %zu entries:\n",
mEntries.size());
int i = 0;
for (List<camera_metadata_t*>::iterator r = mEntries.begin();
@@ -1000,7 +1001,7 @@ status_t Camera2Device::StreamAdapter::connectToDevice(
return BAD_VALUE;
}
- ALOGV("%s: New stream parameters %d x %d, format 0x%x, size %d",
+ ALOGV("%s: New stream parameters %d x %d, format 0x%x, size %zu",
__FUNCTION__, width, height, format, size);
mConsumerInterface = consumer;
@@ -1072,7 +1073,7 @@ status_t Camera2Device::StreamAdapter::connectToDevice(
mSize, 1, mFormat);
if (res != OK) {
ALOGE("%s: Unable to configure compressed stream buffer geometry"
- " %d x %d, size %d for stream %d",
+ " %d x %d, size %zu for stream %d",
__FUNCTION__, mWidth, mHeight, mSize, mId);
return res;
}
@@ -1214,11 +1215,11 @@ status_t Camera2Device::StreamAdapter::dump(int fd,
ATRACE_CALL();
String8 result = String8::format(" Stream %d: %d x %d, format 0x%x\n",
mId, mWidth, mHeight, mFormat);
- result.appendFormat(" size %d, usage 0x%x, requested format 0x%x\n",
+ result.appendFormat(" size %zu, usage 0x%x, requested format 0x%x\n",
mSize, mUsage, mFormatRequested);
result.appendFormat(" total buffers: %d, dequeued buffers: %d\n",
mTotalBuffers, mActiveBuffers);
- result.appendFormat(" frame count: %d, last timestamp %lld\n",
+ result.appendFormat(" frame count: %d, last timestamp %" PRId64 "\n",
mFrameCount, mLastTimestamp);
write(fd, result.string(), result.size());
return OK;
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 3dbc1b0..1d4768c 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -37,6 +37,8 @@
"%s: " fmt, __FUNCTION__, \
##__VA_ARGS__)
+#include <inttypes.h>
+
#include <utils/Log.h>
#include <utils/Trace.h>
#include <utils/Timers.h>
@@ -345,7 +347,7 @@ status_t Camera3Device::dump(int fd, const Vector<String16> &args) {
} else {
for (size_t i = 0; i < mInFlightMap.size(); i++) {
InFlightRequest r = mInFlightMap.valueAt(i);
- lines.appendFormat(" Frame %d | Timestamp: %lld, metadata"
+ lines.appendFormat(" Frame %d | Timestamp: %" PRId64 ", metadata"
" arrived: %s, buffers left: %d\n", mInFlightMap.keyAt(i),
r.captureTimestamp, r.haveResultMetadata ? "true" : "false",
r.numBuffersLeft);
@@ -652,6 +654,8 @@ status_t Camera3Device::createZslStream(
}
mInputStream = newStream;
+ mNeedConfig = true;
+
*id = mNextStreamId++;
*zslStream = newStream;
@@ -676,7 +680,7 @@ status_t Camera3Device::createStream(sp<ANativeWindow> consumer,
ATRACE_CALL();
Mutex::Autolock il(mInterfaceLock);
Mutex::Autolock l(mLock);
- ALOGV("Camera %d: Creating new stream %d: %d x %d, format %d, size %d",
+ ALOGV("Camera %d: Creating new stream %d: %d x %d, format %d, size %zu",
mId, mNextStreamId, width, height, format, size);
status_t res;
@@ -1018,7 +1022,7 @@ status_t Camera3Device::waitForNextFrame(nsecs_t timeout) {
if (res == TIMED_OUT) {
return res;
} else if (res != OK) {
- ALOGW("%s: Camera %d: No frame in %lld ns: %s (%d)",
+ ALOGW("%s: Camera %d: No frame in %" PRId64 " ns: %s (%d)",
__FUNCTION__, mId, timeout, strerror(-res), res);
return res;
}
@@ -1673,7 +1677,7 @@ void Camera3Device::processCaptureResult(const camera3_capture_result *result) {
// Sanity check - if we have too many in-flight frames, something has
// likely gone wrong
if (mInFlightMap.size() > kInFlightWarnLimit) {
- CLOGE("In-flight list too large: %d", mInFlightMap.size());
+ CLOGE("In-flight list too large: %zu", mInFlightMap.size());
}
}
@@ -1723,7 +1727,7 @@ void Camera3Device::processCaptureResult(const camera3_capture_result *result) {
gotResult = false;
} else if (timestamp != entry.data.i64[0]) {
SET_ERR("Timestamp mismatch between shutter notify and result"
- " metadata for frame %d (%lld vs %lld respectively)",
+ " metadata for frame %d (%" PRId64 " vs %" PRId64 " respectively)",
frameNumber, timestamp, entry.data.i64[0]);
gotResult = false;
}
@@ -1745,7 +1749,7 @@ void Camera3Device::processCaptureResult(const camera3_capture_result *result) {
// Note: stream may be deallocated at this point, if this buffer was the
// last reference to it.
if (res != OK) {
- ALOGE("Can't return buffer %d for frame %d to its stream: "
+ ALOGE("Can't return buffer %zu for frame %d to its stream: "
" %s (%d)", i, frameNumber, strerror(-res), res);
}
}
@@ -1835,7 +1839,7 @@ void Camera3Device::notify(const camera3_notify_msg *msg) {
frameNumber);
break;
}
- ALOGVV("Camera %d: %s: Shutter fired for frame %d (id %d) at %lld",
+ ALOGVV("Camera %d: %s: Shutter fired for frame %d (id %d) at %" PRId64,
mId, __FUNCTION__, frameNumber, requestId, timestamp);
// Call listener, if any
if (listener != NULL) {
diff --git a/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp b/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
index da51228..d662cc2 100644
--- a/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
+++ b/services/camera/libcameraservice/device3/Camera3IOStreamBase.cpp
@@ -18,8 +18,7 @@
#define ATRACE_TAG ATRACE_TAG_CAMERA
//#define LOG_NDEBUG 0
-// This is needed for stdint.h to define INT64_MAX in C++
-#define __STDC_LIMIT_MACROS
+#include <inttypes.h>
#include <utils/Log.h>
#include <utils/Trace.h>
@@ -54,8 +53,8 @@ Camera3IOStreamBase::~Camera3IOStreamBase() {
bool Camera3IOStreamBase::hasOutstandingBuffersLocked() const {
nsecs_t signalTime = mCombinedFence->getSignalTime();
- ALOGV("%s: Stream %d: Has %d outstanding buffers,"
- " buffer signal time is %lld",
+ ALOGV("%s: Stream %d: Has %zu outstanding buffers,"
+ " buffer signal time is %" PRId64,
__FUNCTION__, mId, mDequeuedBufferCount, signalTime);
if (mDequeuedBufferCount > 0 || signalTime == INT64_MAX) {
return true;
@@ -70,12 +69,12 @@ void Camera3IOStreamBase::dump(int fd, const Vector<String16> &args) const {
lines.appendFormat(" Dims: %d x %d, format 0x%x\n",
camera3_stream::width, camera3_stream::height,
camera3_stream::format);
- lines.appendFormat(" Max size: %d\n", mMaxSize);
+ lines.appendFormat(" Max size: %zu\n", mMaxSize);
lines.appendFormat(" Usage: %d, max HAL buffers: %d\n",
camera3_stream::usage, camera3_stream::max_buffers);
- lines.appendFormat(" Frames produced: %d, last timestamp: %lld ns\n",
+ lines.appendFormat(" Frames produced: %d, last timestamp: %" PRId64 " ns\n",
mFrameCount, mLastTimestamp);
- lines.appendFormat(" Total buffers: %d, currently dequeued: %d\n",
+ lines.appendFormat(" Total buffers: %zu, currently dequeued: %zu\n",
mTotalBufferCount, mDequeuedBufferCount);
write(fd, lines.string(), lines.size());
}
@@ -119,7 +118,7 @@ status_t Camera3IOStreamBase::disconnectLocked() {
}
if (mDequeuedBufferCount > 0) {
- ALOGE("%s: Can't disconnect with %d buffers still dequeued!",
+ ALOGE("%s: Can't disconnect with %zu buffers still dequeued!",
__FUNCTION__, mDequeuedBufferCount);
return INVALID_OPERATION;
}
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.cpp b/services/camera/libcameraservice/device3/Camera3Stream.cpp
index 6d2cf94..70406f1 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Stream.cpp
@@ -353,7 +353,7 @@ status_t Camera3Stream::registerBuffersLocked(camera3_device *hal3Device) {
}
if (bufferIdx == bufferCount) {
// Got all buffers, register with HAL
- ALOGV("%s: Registering %d buffers with camera HAL",
+ ALOGV("%s: Registering %zu buffers with camera HAL",
__FUNCTION__, bufferCount);
ATRACE_BEGIN("camera3->register_stream_buffers");
res = hal3Device->ops->register_stream_buffers(hal3Device,
diff --git a/services/camera/libcameraservice/device3/Camera3ZslStream.cpp b/services/camera/libcameraservice/device3/Camera3ZslStream.cpp
index 04f5dc5..44d8188 100644
--- a/services/camera/libcameraservice/device3/Camera3ZslStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3ZslStream.cpp
@@ -18,6 +18,8 @@
#define ATRACE_TAG ATRACE_TAG_CAMERA
//#define LOG_NDEBUG 0
+#include <inttypes.h>
+
#include <utils/Log.h>
#include <utils/Trace.h>
#include "Camera3ZslStream.h"
@@ -271,7 +273,7 @@ void Camera3ZslStream::dump(int fd, const Vector<String16> &args) const {
Camera3IOStreamBase::dump(fd, args);
lines = String8();
- lines.appendFormat(" Input buffers pending: %d, in flight %d\n",
+ lines.appendFormat(" Input buffers pending: %zu, in flight %zu\n",
mInputBufferQueue.size(), mBuffersInFlight.size());
write(fd, lines.string(), lines.size());
}
@@ -297,7 +299,7 @@ status_t Camera3ZslStream::enqueueInputBufferByTimestamp(
if (actual != timestamp) {
ALOGW("%s: ZSL buffer candidate search didn't find an exact match --"
- " requested timestamp = %lld, actual timestamp = %lld",
+ " requested timestamp = %" PRId64 ", actual timestamp = %" PRId64,
__FUNCTION__, timestamp, actual);
}
diff --git a/services/camera/libcameraservice/device3/StatusTracker.cpp b/services/camera/libcameraservice/device3/StatusTracker.cpp
index ab5419f..723b5c2 100644
--- a/services/camera/libcameraservice/device3/StatusTracker.cpp
+++ b/services/camera/libcameraservice/device3/StatusTracker.cpp
@@ -18,9 +18,6 @@
#define ATRACE_TAG ATRACE_TAG_CAMERA
//#define LOG_NDEBUG 0
-// This is needed for stdint.h to define INT64_MAX in C++
-#define __STDC_LIMIT_MACROS
-
#include <utils/Log.h>
#include <utils/Trace.h>
#include <ui/Fence.h>
@@ -52,7 +49,7 @@ int StatusTracker::addComponent() {
ALOGV("%s: Adding new component %d", __FUNCTION__, id);
err = mStates.add(id, IDLE);
- ALOGE_IF(err < 0, "%s: Can't add new component %d: %s (%d)",
+ ALOGE_IF(err < 0, "%s: Can't add new component %d: %s (%zd)",
__FUNCTION__, id, strerror(-err), err);
}
diff --git a/services/camera/libcameraservice/gui/RingBufferConsumer.cpp b/services/camera/libcameraservice/gui/RingBufferConsumer.cpp
index ebc7ea7..e4ec5fd 100644
--- a/services/camera/libcameraservice/gui/RingBufferConsumer.cpp
+++ b/services/camera/libcameraservice/gui/RingBufferConsumer.cpp
@@ -17,15 +17,18 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "RingBufferConsumer"
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+
+#include <inttypes.h>
+
#include <utils/Log.h>
#include <gui/RingBufferConsumer.h>
-#define BI_LOGV(x, ...) ALOGV("[%s] "x, mName.string(), ##__VA_ARGS__)
-#define BI_LOGD(x, ...) ALOGD("[%s] "x, mName.string(), ##__VA_ARGS__)
-#define BI_LOGI(x, ...) ALOGI("[%s] "x, mName.string(), ##__VA_ARGS__)
-#define BI_LOGW(x, ...) ALOGW("[%s] "x, mName.string(), ##__VA_ARGS__)
-#define BI_LOGE(x, ...) ALOGE("[%s] "x, mName.string(), ##__VA_ARGS__)
+#define BI_LOGV(x, ...) ALOGV("[%s] " x, mName.string(), ##__VA_ARGS__)
+#define BI_LOGD(x, ...) ALOGD("[%s] " x, mName.string(), ##__VA_ARGS__)
+#define BI_LOGI(x, ...) ALOGI("[%s] " x, mName.string(), ##__VA_ARGS__)
+#define BI_LOGW(x, ...) ALOGW("[%s] " x, mName.string(), ##__VA_ARGS__)
+#define BI_LOGE(x, ...) ALOGE("[%s] " x, mName.string(), ##__VA_ARGS__)
#undef assert
#define assert(x) ALOG_ASSERT((x), #x)
@@ -164,10 +167,10 @@ void RingBufferConsumer::pinBufferLocked(const BufferItem& item) {
}
if (it == end) {
- BI_LOGE("Failed to pin buffer (timestamp %lld, framenumber %lld)",
+ BI_LOGE("Failed to pin buffer (timestamp %" PRId64 ", framenumber %" PRIu64 ")",
item.mTimestamp, item.mFrameNumber);
} else {
- BI_LOGV("Pinned buffer (frame %lld, timestamp %lld)",
+ BI_LOGV("Pinned buffer (frame %" PRIu64 ", timestamp %" PRId64 ")",
item.mFrameNumber, item.mTimestamp);
}
}
@@ -222,12 +225,12 @@ status_t RingBufferConsumer::releaseOldestBufferLocked(size_t* pinnedFrames) {
if (err != OK) {
BI_LOGE("Failed to add release fence to buffer "
- "(timestamp %lld, framenumber %lld",
+ "(timestamp %" PRId64 ", framenumber %" PRIu64,
item.mTimestamp, item.mFrameNumber);
return err;
}
- BI_LOGV("Attempting to release buffer timestamp %lld, frame %lld",
+ BI_LOGV("Attempting to release buffer timestamp %" PRId64 ", frame %" PRIu64,
item.mTimestamp, item.mFrameNumber);
// item.mGraphicBuffer was populated with the proper graphic-buffer
@@ -241,7 +244,7 @@ status_t RingBufferConsumer::releaseOldestBufferLocked(size_t* pinnedFrames) {
return err;
}
- BI_LOGV("Buffer timestamp %lld, frame %lld evicted",
+ BI_LOGV("Buffer timestamp %" PRId64 ", frame %" PRIu64 " evicted",
item.mTimestamp, item.mFrameNumber);
size_t currentSize = mBufferItemList.size();
@@ -294,8 +297,8 @@ void RingBufferConsumer::onFrameAvailable() {
return;
}
- BI_LOGV("New buffer acquired (timestamp %lld), "
- "buffer items %u out of %d",
+ BI_LOGV("New buffer acquired (timestamp %" PRId64 "), "
+ "buffer items %zu out of %d",
item.mTimestamp,
mBufferItemList.size(), mBufferCount);
@@ -321,7 +324,7 @@ void RingBufferConsumer::unpinBuffer(const BufferItem& item) {
if (res != OK) {
BI_LOGE("Failed to add release fence to buffer "
- "(timestamp %lld, framenumber %lld",
+ "(timestamp %" PRId64 ", framenumber %" PRIu64,
item.mTimestamp, item.mFrameNumber);
return;
}
@@ -333,10 +336,10 @@ void RingBufferConsumer::unpinBuffer(const BufferItem& item) {
if (it == end) {
// This should never happen. If it happens, we have a bug.
- BI_LOGE("Failed to unpin buffer (timestamp %lld, framenumber %lld)",
+ BI_LOGE("Failed to unpin buffer (timestamp %" PRId64 ", framenumber %" PRIu64 ")",
item.mTimestamp, item.mFrameNumber);
} else {
- BI_LOGV("Unpinned buffer (timestamp %lld, framenumber %lld)",
+ BI_LOGV("Unpinned buffer (timestamp %" PRId64 ", framenumber %" PRIu64 ")",
item.mTimestamp, item.mFrameNumber);
}
}
diff --git a/services/camera/libcameraservice/utils/CameraTraces.cpp b/services/camera/libcameraservice/utils/CameraTraces.cpp
index 346e15f..374dc5e 100644
--- a/services/camera/libcameraservice/utils/CameraTraces.cpp
+++ b/services/camera/libcameraservice/utils/CameraTraces.cpp
@@ -74,10 +74,10 @@ status_t CameraTraces::dump(int fd, const Vector<String16> &args __attribute__((
return BAD_VALUE;
}
- fdprintf(fd, "Camera traces (%zu):\n", pcsList.size());
+ dprintf(fd, "Camera traces (%zu):\n", pcsList.size());
if (pcsList.empty()) {
- fdprintf(fd, " No camera traces collected.\n");
+ dprintf(fd, " No camera traces collected.\n");
}
// Print newest items first
diff --git a/services/medialog/Android.mk b/services/medialog/Android.mk
index 08006c8..95f2fef 100644
--- a/services/medialog/Android.mk
+++ b/services/medialog/Android.mk
@@ -8,4 +8,6 @@ LOCAL_SHARED_LIBRARIES := libmedia libbinder libutils liblog libnbaio
LOCAL_MODULE:= libmedialogservice
+LOCAL_32_BIT_ONLY := true
+
include $(BUILD_SHARED_LIBRARY)
diff --git a/services/medialog/MediaLogService.cpp b/services/medialog/MediaLogService.cpp
index 683fdf3..e53b3a6 100644
--- a/services/medialog/MediaLogService.cpp
+++ b/services/medialog/MediaLogService.cpp
@@ -60,7 +60,7 @@ status_t MediaLogService::dump(int fd, const Vector<String16>& args)
static const String16 sDump("android.permission.DUMP");
if (!(IPCThreadState::self()->getCallingUid() == AID_MEDIA ||
PermissionCache::checkCallingPermission(sDump))) {
- fdprintf(fd, "Permission Denial: can't dump media.log from pid=%d, uid=%d\n",
+ dprintf(fd, "Permission Denial: can't dump media.log from pid=%d, uid=%d\n",
IPCThreadState::self()->getCallingPid(),
IPCThreadState::self()->getCallingUid());
return NO_ERROR;
@@ -74,7 +74,7 @@ status_t MediaLogService::dump(int fd, const Vector<String16>& args)
for (size_t i = 0; i < namedReaders.size(); i++) {
const NamedReader& namedReader = namedReaders[i];
if (fd >= 0) {
- fdprintf(fd, "\n%s:\n", namedReader.name());
+ dprintf(fd, "\n%s:\n", namedReader.name());
} else {
ALOGI("%s:", namedReader.name());
}
diff --git a/tools/resampler_tools/fir.cpp b/tools/resampler_tools/fir.cpp
index cc3d509..8c8a4ea 100644
--- a/tools/resampler_tools/fir.cpp
+++ b/tools/resampler_tools/fir.cpp
@@ -243,7 +243,7 @@ int main(int argc, char** argv)
}
}
} else {
- for (int j=0 ; j<polyN ; j++) {
+ for (unsigned int j=0 ; j<polyN ; j++) {
// calculate the phase
double p = ((polyM*j) % polyN) / double(polyN);
if (!debug) printf("\n ");