diff --git a/content/media/webm/nsWebMReader.cpp b/content/media/webm/nsWebMReader.cpp index 49350a12af6..1ca545b9b80 100644 --- a/content/media/webm/nsWebMReader.cpp +++ b/content/media/webm/nsWebMReader.cpp @@ -66,6 +66,13 @@ static const unsigned NS_PER_MS = 1000000; static const float NS_PER_S = 1e9; static const float MS_PER_S = 1e3; +NS_SPECIALIZE_TEMPLATE +class nsAutoRefTraits : public nsPointerRefTraits +{ +public: + static void Release(nestegg_packet* aPacket) { nestegg_free_packet(aPacket); } +}; + // Functions for reading and seeking using nsMediaStream required for // nestegg_io. The 'user data' passed to these functions is the // decoder from which the media stream is obtained. @@ -358,7 +365,6 @@ PRBool nsWebMReader::DecodeAudioPacket(nestegg_packet* aPacket) uint64_t tstamp = 0; r = nestegg_packet_tstamp(aPacket, &tstamp); if (r == -1) { - nestegg_free_packet(aPacket); return PR_FALSE; } @@ -405,20 +411,17 @@ PRBool nsWebMReader::DecodeAudioPacket(nestegg_packet* aPacket) size_t length; r = nestegg_packet_data(aPacket, i, &data, &length); if (r == -1) { - nestegg_free_packet(aPacket); return PR_FALSE; } ogg_packet opacket = InitOggPacket(data, length, PR_FALSE, PR_FALSE, -1); if (vorbis_synthesis(&mVorbisBlock, &opacket) != 0) { - nestegg_free_packet(aPacket); return PR_FALSE; } if (vorbis_synthesis_blockin(&mVorbisDsp, &mVorbisBlock) != 0) { - nestegg_free_packet(aPacket); return PR_FALSE; } @@ -436,13 +439,11 @@ PRBool nsWebMReader::DecodeAudioPacket(nestegg_packet* aPacket) PRInt64 duration = 0; if (!SamplesToMs(samples, rate, duration)) { NS_WARNING("Int overflow converting WebM audio duration"); - nestegg_free_packet(aPacket); return PR_FALSE; } PRInt64 total_duration = 0; if (!SamplesToMs(total_samples, rate, total_duration)) { NS_WARNING("Int overflow converting WebM audio total_duration"); - nestegg_free_packet(aPacket); return PR_FALSE; } @@ -457,18 +458,15 @@ PRBool nsWebMReader::DecodeAudioPacket(nestegg_packet* aPacket) mAudioQueue.Push(s); mAudioSamples += samples; if (vorbis_synthesis_read(&mVorbisDsp, samples) != 0) { - nestegg_free_packet(aPacket); return PR_FALSE; } } } - nestegg_free_packet(aPacket); - return PR_TRUE; } -nestegg_packet* nsWebMReader::NextPacket(TrackType aTrackType) +nsReturnRef nsWebMReader::NextPacket(TrackType aTrackType) { // The packet queue that packets will be pushed on if they // are not the type we are interested in. @@ -493,30 +491,30 @@ nestegg_packet* nsWebMReader::NextPacket(TrackType aTrackType) // Value of other track PRUint32 otherTrack = aTrackType == VIDEO ? mAudioTrack : mVideoTrack; - nestegg_packet* packet = NULL; + nsAutoRef packet; if (packets.GetSize() > 0) { - packet = packets.PopFront(); - } - else { + packet.own(packets.PopFront()); + } else { // Keep reading packets until we find a packet // for the track we want. do { - int r = nestegg_read_packet(mContext, &packet); + nestegg_packet* p; + int r = nestegg_read_packet(mContext, &p); if (r <= 0) { - return NULL; + return nsReturnRef(); } + packet.own(p); unsigned int track = 0; r = nestegg_packet_track(packet, &track); if (r == -1) { - nestegg_free_packet(packet); - return NULL; + return nsReturnRef(); } if (hasOtherType && otherTrack == track) { // Save the packet for when we want these packets - otherPackets.Push(packet); + otherPackets.Push(packet.disown()); continue; } @@ -524,13 +522,10 @@ nestegg_packet* nsWebMReader::NextPacket(TrackType aTrackType) if (hasType && ourTrack == track) { break; } - - // The packet is for a track we're not interested in - nestegg_free_packet(packet); } while (PR_TRUE); } - return packet; + return packet.out(); } PRBool nsWebMReader::DecodeAudioData() @@ -538,7 +533,7 @@ PRBool nsWebMReader::DecodeAudioData() MonitorAutoEnter mon(mMonitor); NS_ASSERTION(mDecoder->OnStateMachineThread() || mDecoder->OnDecodeThread(), "Should be on state machine thread or decode thread."); - nestegg_packet* packet = NextPacket(AUDIO); + nsAutoRef packet(NextPacket(AUDIO)); if (!packet) { mAudioQueue.Finish(); return PR_FALSE; @@ -553,32 +548,28 @@ PRBool nsWebMReader::DecodeVideoFrame(PRBool &aKeyframeSkip, MonitorAutoEnter mon(mMonitor); NS_ASSERTION(mDecoder->OnStateMachineThread() || mDecoder->OnDecodeThread(), "Should be on state machine or decode thread."); - int r = 0; - nestegg_packet* packet = NextPacket(VIDEO); + nsAutoRef packet(NextPacket(VIDEO)); if (!packet) { mVideoQueue.Finish(); return PR_FALSE; } unsigned int track = 0; - r = nestegg_packet_track(packet, &track); + int r = nestegg_packet_track(packet, &track); if (r == -1) { - nestegg_free_packet(packet); return PR_FALSE; } unsigned int count = 0; r = nestegg_packet_count(packet, &count); if (r == -1) { - nestegg_free_packet(packet); return PR_FALSE; } uint64_t tstamp = 0; r = nestegg_packet_tstamp(packet, &tstamp); if (r == -1) { - nestegg_free_packet(packet); return PR_FALSE; } @@ -588,14 +579,13 @@ PRBool nsWebMReader::DecodeVideoFrame(PRBool &aKeyframeSkip, // video frame. uint64_t next_tstamp = 0; { - nestegg_packet* next_packet = NextPacket(VIDEO); + nsAutoRef next_packet(NextPacket(VIDEO)); if (next_packet) { r = nestegg_packet_tstamp(next_packet, &next_tstamp); if (r == -1) { - nestegg_free_packet(next_packet); return PR_FALSE; } - mVideoPackets.PushFront(next_packet); + mVideoPackets.PushFront(next_packet.disown()); } else { MonitorAutoExit exitMon(mMonitor); MonitorAutoEnter decoderMon(mDecoder->GetMonitor()); @@ -615,7 +605,6 @@ PRBool nsWebMReader::DecodeVideoFrame(PRBool &aKeyframeSkip, size_t length; r = nestegg_packet_data(packet, i, &data, &length); if (r == -1) { - nestegg_free_packet(packet); return PR_FALSE; } @@ -633,7 +622,6 @@ PRBool nsWebMReader::DecodeVideoFrame(PRBool &aKeyframeSkip, } if(vpx_codec_decode(&mVP8, data, length, NULL, 0)) { - nestegg_free_packet(packet); return PR_FALSE; } @@ -680,14 +668,12 @@ PRBool nsWebMReader::DecodeVideoFrame(PRBool &aKeyframeSkip, si.is_kf, -1); if (!v) { - nestegg_free_packet(packet); return PR_FALSE; } mVideoQueue.Push(v); } } - - nestegg_free_packet(packet); + return PR_TRUE; } diff --git a/content/media/webm/nsWebMReader.h b/content/media/webm/nsWebMReader.h index c6af6c62cda..22c6eab450a 100644 --- a/content/media/webm/nsWebMReader.h +++ b/content/media/webm/nsWebMReader.h @@ -42,6 +42,7 @@ #include "nsDeque.h" #include "nsBuiltinDecoderReader.h" #include "nsWebMBufferedParser.h" +#include "nsAutoRef.h" #include "nestegg/nestegg.h" #include "vpx/vpx_decoder.h" #include "vpx/vp8dx.h" @@ -139,7 +140,7 @@ private: // Read a packet from the nestegg file. Returns NULL if all packets for // the particular track have been read. Pass VIDEO or AUDIO to indicate the // type of the packet we want to read. - nestegg_packet* NextPacket(TrackType aTrackType); + nsReturnRef NextPacket(TrackType aTrackType); // Returns an initialized ogg packet with data obtained from the WebM container. ogg_packet InitOggPacket(unsigned char* aData,