1
0
Fork 0
mirror of https://github.com/ossrs/srs.git synced 2025-03-09 15:49:59 +00:00

UniquePtr: Support SrsUniquePtr to replace SrsAutoFree. v6.0.136 (#4109)

To manage an object:

```cpp
// Before
MyClass* ptr = new MyClass();
SrsAutoFree(MyClass, ptr);
ptr->do_something();

// Now
SrsUniquePtr<MyClass> ptr(new MyClass());
ptr->do_something();
```

To manage an array of objects:

```cpp
// Before
char* ptr = new char[10];
SrsAutoFreeA(char, ptr);
ptr[0] = 0xf;

// Now
SrsUniquePtr<char[]> ptr(new char[10]);
ptr[0] = 0xf;
```

In fact, SrsUniquePtr is a limited subset of SrsAutoFree, mainly
managing pointers and arrays. SrsUniquePtr is better than SrsAutoFree
because it has the same API to standard unique ptr.

```cpp
SrsUniquePtr<MyClass> ptr(new MyClass());
ptr->do_something();
MyClass* p = ptr.get();
```

SrsAutoFree actually uses a pointer to a pointer, so it can be set to
NULL, allowing the pointer's value to be changed later (this usage is
different from SrsUniquePtr).

```cpp
// OK to free ptr correctly.
MyClass* ptr;
SrsAutoFree(MyClass, ptr);
ptr = new MyClass();

// Crash because ptr is an invalid pointer.
MyClass* ptr;
SrsUniquePtr<MyClass> ptr(ptr);
ptr = new MyClass();
```

Additionally, SrsAutoFreeH can use specific release functions, which
SrsUniquePtr does not support.

---------

Co-authored-by: Jacob Su <suzp1984@gmail.com>
This commit is contained in:
Winlin 2024-07-09 10:29:36 +08:00 committed by GitHub
parent baf22d01c1
commit 23d2602c34
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
72 changed files with 1720 additions and 1669 deletions

View file

@ -53,10 +53,9 @@ srs_error_t SrsAacTransmuxer::write_audio(int64_t timestamp, char* data, int siz
srs_assert(data);
timestamp &= 0x7fffffff;
SrsBuffer* stream = new SrsBuffer(data, size);
SrsAutoFree(SrsBuffer, stream);
SrsUniquePtr<SrsBuffer> stream(new SrsBuffer(data, size));
// audio decode
if (!stream->require(1)) {
return srs_error_new(ERROR_AAC_DECODE_ERROR, "aac decode audio sound_format failed");

View file

@ -730,13 +730,12 @@ srs_error_t SrsVideoFrame::parse_avc_b_frame(const SrsSample* sample, bool& is_b
return err;
}
SrsBuffer* stream = new SrsBuffer(sample->bytes, sample->size);
SrsAutoFree(SrsBuffer, stream);
SrsUniquePtr<SrsBuffer> stream(new SrsBuffer(sample->bytes, sample->size));
// Skip nalu header.
stream->skip(1);
SrsBitBuffer bitstream(stream);
SrsBitBuffer bitstream(stream.get());
int32_t first_mb_in_slice = 0;
if ((err = srs_avc_nalu_read_uev(&bitstream, first_mb_in_slice)) != srs_success) {
return srs_error_wrap(err, "nalu read uev");
@ -793,10 +792,9 @@ srs_error_t SrsFormat::on_audio(int64_t timestamp, char* data, int size)
srs_info("no audio present, ignore it.");
return err;
}
SrsBuffer* buffer = new SrsBuffer(data, size);
SrsAutoFree(SrsBuffer, buffer);
SrsUniquePtr<SrsBuffer> buffer(new SrsBuffer(data, size));
// We already checked the size is positive and data is not NULL.
srs_assert(buffer->require(1));
@ -824,10 +822,10 @@ srs_error_t SrsFormat::on_audio(int64_t timestamp, char* data, int size)
buffer->skip(-1 * buffer->pos());
if (codec == SrsAudioCodecIdMP3) {
return audio_mp3_demux(buffer, timestamp, fresh);
return audio_mp3_demux(buffer.get(), timestamp, fresh);
}
return audio_aac_demux(buffer, timestamp);
return audio_aac_demux(buffer.get(), timestamp);
}
srs_error_t SrsFormat::on_video(int64_t timestamp, char* data, int size)
@ -838,11 +836,9 @@ srs_error_t SrsFormat::on_video(int64_t timestamp, char* data, int size)
srs_trace("no video present, ignore it.");
return err;
}
SrsBuffer* buffer = new SrsBuffer(data, size);
SrsAutoFree(SrsBuffer, buffer);
return video_avc_demux(buffer, timestamp);
SrsUniquePtr<SrsBuffer> buffer(new SrsBuffer(data, size));
return video_avc_demux(buffer.get(), timestamp);
}
srs_error_t SrsFormat::on_aac_sequence_header(char* data, int size)
@ -2807,10 +2803,9 @@ srs_error_t SrsFormat::audio_mp3_demux(SrsBuffer* stream, int64_t timestamp, boo
srs_error_t SrsFormat::audio_aac_sequence_header_demux(char* data, int size)
{
srs_error_t err = srs_success;
SrsBuffer* buffer = new SrsBuffer(data, size);
SrsAutoFree(SrsBuffer, buffer);
SrsUniquePtr<SrsBuffer> buffer(new SrsBuffer(data, size));
// only need to decode the first 2bytes:
// audioObjectType, aac_profile, 5bits.
// samplingFrequencyIndex, aac_sample_rate, 4bits.

View file

@ -584,10 +584,9 @@ void SrsFlvTransmuxer::cache_metadata(char type, char* data, int size, char* cac
(char)0x00, // TimestampExtended UI8
(char)0x00, (char)0x00, (char)0x00, // StreamID UI24 Always 0.
};*/
SrsBuffer* tag_stream = new SrsBuffer(cache, 11);
SrsAutoFree(SrsBuffer, tag_stream);
SrsUniquePtr<SrsBuffer> tag_stream(new SrsBuffer(cache, 11));
// write data size.
tag_stream->write_1bytes(type);
tag_stream->write_3bytes(size);
@ -610,10 +609,9 @@ void SrsFlvTransmuxer::cache_audio(int64_t timestamp, char* data, int size, char
(char)0x00, // TimestampExtended UI8
(char)0x00, (char)0x00, (char)0x00, // StreamID UI24 Always 0.
};*/
SrsBuffer* tag_stream = new SrsBuffer(cache, 11);
SrsAutoFree(SrsBuffer, tag_stream);
SrsUniquePtr<SrsBuffer> tag_stream(new SrsBuffer(cache, 11));
// write data size.
tag_stream->write_1bytes(SrsFrameTypeAudio);
tag_stream->write_3bytes(size);
@ -637,10 +635,9 @@ void SrsFlvTransmuxer::cache_video(int64_t timestamp, char* data, int size, char
(char)0x00, // TimestampExtended UI8
(char)0x00, (char)0x00, (char)0x00, // StreamID UI24 Always 0.
};*/
SrsBuffer* tag_stream = new SrsBuffer(cache, 11);
SrsAutoFree(SrsBuffer, tag_stream);
SrsUniquePtr<SrsBuffer> tag_stream(new SrsBuffer(cache, 11));
// write data size.
tag_stream->write_1bytes(SrsFrameTypeVideo);
tag_stream->write_3bytes(size);
@ -652,8 +649,7 @@ void SrsFlvTransmuxer::cache_video(int64_t timestamp, char* data, int size, char
void SrsFlvTransmuxer::cache_pts(int size, char* cache)
{
SrsBuffer* tag_stream = new SrsBuffer(cache, 11);
SrsAutoFree(SrsBuffer, tag_stream);
SrsUniquePtr<SrsBuffer> tag_stream(new SrsBuffer(cache, 11));
tag_stream->write_4bytes(size);
}
@ -860,10 +856,9 @@ srs_error_t SrsFlvVodStreamDecoder::read_sequence_header_summary(int64_t* pstart
if ((err = reader->read(tag_header, SRS_FLV_TAG_HEADER_SIZE, NULL)) != srs_success) {
return srs_error_wrap(err, "read tag header");
}
SrsBuffer* tag_stream = new SrsBuffer(tag_header, SRS_FLV_TAG_HEADER_SIZE);
SrsAutoFree(SrsBuffer, tag_stream);
SrsUniquePtr<SrsBuffer> tag_stream(new SrsBuffer(tag_header, SRS_FLV_TAG_HEADER_SIZE));
int8_t tag_type = tag_stream->read_1bytes();
int32_t data_size = tag_stream->read_3bytes();

View file

@ -74,10 +74,9 @@ srs_error_t SrsMp3Transmuxer::write_audio(int64_t timestamp, char* data, int siz
srs_assert(data);
timestamp &= 0x7fffffff;
SrsBuffer* stream = new SrsBuffer(data, size);
SrsAutoFree(SrsBuffer, stream);
SrsUniquePtr<SrsBuffer> stream(new SrsBuffer(data, size));
// audio decode
if (!stream->require(1)) {
return srs_error_new(ERROR_MP3_DECODE_ERROR, "decode sound_format");

View file

@ -13,6 +13,7 @@
#include <srs_kernel_io.hpp>
#include <srs_kernel_utility.hpp>
#include <srs_kernel_buffer.hpp>
#include <srs_core_deprecated.hpp>
#include <string.h>
#include <sstream>
@ -36,10 +37,8 @@ srs_error_t srs_mp4_write_box(ISrsWriter* writer, ISrsCodec* box)
int nb_data = box->nb_bytes();
std::vector<char> data(nb_data);
SrsBuffer* buffer = new SrsBuffer(&data[0], nb_data);
SrsAutoFree(SrsBuffer, buffer);
if ((err = box->encode(buffer)) != srs_success) {
SrsUniquePtr<SrsBuffer> buffer(new SrsBuffer(&data[0], nb_data));
if ((err = box->encode(buffer.get())) != srs_success) {
return srs_error_wrap(err, "encode box");
}
@ -5316,6 +5315,7 @@ srs_error_t SrsMp4BoxReader::read(SrsSimpleStream* stream, SrsMp4Box** ppbox)
srs_error_t err = srs_success;
SrsMp4Box* box = NULL;
// Note that we should use SrsAutoFree to free the ptr which is set later.
SrsAutoFree(SrsMp4Box, box);
while (true) {
@ -5338,12 +5338,11 @@ srs_error_t SrsMp4BoxReader::read(SrsSimpleStream* stream, SrsMp4Box** ppbox)
srs_assert(nread > 0);
stream->append(buf, (int)nread);
}
SrsBuffer* buffer = new SrsBuffer(stream->bytes(), stream->length());
SrsAutoFree(SrsBuffer, buffer);
SrsUniquePtr<SrsBuffer> buffer(new SrsBuffer(stream->bytes(), stream->length()));
// Discovery the box with basic header.
if (!box && (err = SrsMp4Box::discovery(buffer, &box)) != srs_success) {
if (!box && (err = SrsMp4Box::discovery(buffer.get(), &box)) != srs_success) {
if (srs_error_code(err) == ERROR_MP4_BOX_REQUIRE_SPACE) {
srs_freep(err);
continue;
@ -5431,15 +5430,14 @@ srs_error_t SrsMp4Decoder::initialize(ISrsReadSeeker* rs)
off_t offset = -1;
while (true) {
SrsMp4Box* box = NULL;
SrsAutoFree(SrsMp4Box, box);
if ((err = load_next_box(&box, 0)) != srs_success) {
SrsMp4Box* box_raw = NULL;
if ((err = load_next_box(&box_raw, 0)) != srs_success) {
return srs_error_wrap(err, "load box");
}
SrsUniquePtr<SrsMp4Box> box(box_raw);
if (box->is_ftyp()) {
SrsMp4FileTypeBox* ftyp = dynamic_cast<SrsMp4FileTypeBox*>(box);
SrsMp4FileTypeBox* ftyp = dynamic_cast<SrsMp4FileTypeBox*>(box.get());
if ((err = parse_ftyp(ftyp)) != srs_success) {
return srs_error_wrap(err, "parse ftyp");
}
@ -5450,7 +5448,7 @@ srs_error_t SrsMp4Decoder::initialize(ISrsReadSeeker* rs)
}
offset = off_t(cur - box->sz());
} else if (box->is_moov()) {
SrsMp4MovieBox* moov = dynamic_cast<SrsMp4MovieBox*>(box);
SrsMp4MovieBox* moov = dynamic_cast<SrsMp4MovieBox*>(box.get());
if ((err = parse_moov(moov)) != srs_success) {
return srs_error_wrap(err, "parse moov");
}
@ -5653,6 +5651,7 @@ srs_error_t SrsMp4Decoder::load_next_box(SrsMp4Box** ppbox, uint32_t required_bo
while (true) {
SrsMp4Box* box = NULL;
// Note that we should use SrsAutoFree to free the ptr which is set later.
SrsAutoFree(SrsMp4Box, box);
if ((err = do_load_next_box(&box, required_box_type)) != srs_success) {
@ -5679,16 +5678,15 @@ srs_error_t SrsMp4Decoder::do_load_next_box(SrsMp4Box** ppbox, uint32_t required
if ((err = br->read(stream, &box)) != srs_success) {
return srs_error_wrap(err, "read box");
}
SrsBuffer* buffer = new SrsBuffer(stream->bytes(), stream->length());
SrsAutoFree(SrsBuffer, buffer);
SrsUniquePtr<SrsBuffer> buffer(new SrsBuffer(stream->bytes(), stream->length()));
// Decode the box:
// 1. Any box, when no box type is required.
// 2. Matched box, when box type match the required type.
// 3. Mdat box, always decode the mdat because we only decode the header of it.
if (!required_box_type || (uint32_t)box->type == required_box_type || box->is_mdat()) {
err = box->decode(buffer);
err = box->decode(buffer.get());
}
// Skip the box from stream, move stream to next box.
@ -5741,20 +5739,17 @@ srs_error_t SrsMp4Encoder::initialize(ISrsWriteSeeker* ws)
// Write ftyp box.
if (true) {
SrsMp4FileTypeBox* ftyp = new SrsMp4FileTypeBox();
SrsAutoFree(SrsMp4FileTypeBox, ftyp);
SrsUniquePtr<SrsMp4FileTypeBox> ftyp(new SrsMp4FileTypeBox());
ftyp->major_brand = SrsMp4BoxBrandISOM;
ftyp->minor_version = 512;
ftyp->set_compatible_brands(SrsMp4BoxBrandISOM, SrsMp4BoxBrandISO2, SrsMp4BoxBrandMP41);
int nb_data = ftyp->nb_bytes();
std::vector<char> data(nb_data);
SrsBuffer* buffer = new SrsBuffer(&data[0], nb_data);
SrsAutoFree(SrsBuffer, buffer);
if ((err = ftyp->encode(buffer)) != srs_success) {
SrsUniquePtr<SrsBuffer> buffer(new SrsBuffer(&data[0], nb_data));
if ((err = ftyp->encode(buffer.get())) != srs_success) {
return srs_error_wrap(err, "encode ftyp");
}
@ -5766,16 +5761,13 @@ srs_error_t SrsMp4Encoder::initialize(ISrsWriteSeeker* ws)
// 8B reserved free box.
if (true) {
SrsMp4FreeSpaceBox* freeb = new SrsMp4FreeSpaceBox(SrsMp4BoxTypeFREE);
SrsAutoFree(SrsMp4FreeSpaceBox, freeb);
SrsUniquePtr<SrsMp4FreeSpaceBox> freeb(new SrsMp4FreeSpaceBox(SrsMp4BoxTypeFREE));
int nb_data = freeb->nb_bytes();
std::vector<char> data(nb_data);
SrsBuffer* buffer = new SrsBuffer(&data[0], nb_data);
SrsAutoFree(SrsBuffer, buffer);
if ((err = freeb->encode(buffer)) != srs_success) {
SrsUniquePtr<SrsBuffer> buffer(new SrsBuffer(&data[0], nb_data));
if ((err = freeb->encode(buffer.get())) != srs_success) {
return srs_error_wrap(err, "encode free box");
}
@ -5789,27 +5781,23 @@ srs_error_t SrsMp4Encoder::initialize(ISrsWriteSeeker* ws)
// Write empty mdat box,
// its payload will be writen by samples,
// and we will update its header(size) when flush.
SrsMp4MediaDataBox* mdat = new SrsMp4MediaDataBox();
SrsAutoFree(SrsMp4MediaDataBox, mdat);
SrsUniquePtr<SrsMp4MediaDataBox> mdat(new SrsMp4MediaDataBox());
// Update the mdat box from this offset.
if ((err = wsio->lseek(0, SEEK_CUR, &mdat_offset)) != srs_success) {
return srs_error_wrap(err, "seek to mdat");
}
int nb_data = mdat->sz_header();
uint8_t* data = new uint8_t[nb_data];
SrsAutoFreeA(uint8_t, data);
SrsBuffer* buffer = new SrsBuffer((char*)data, nb_data);
SrsAutoFree(SrsBuffer, buffer);
if ((err = mdat->encode(buffer)) != srs_success) {
SrsUniquePtr<uint8_t[]> data(new uint8_t[nb_data]);
SrsUniquePtr<SrsBuffer> buffer(new SrsBuffer((char*)data.get(), nb_data));
if ((err = mdat->encode(buffer.get())) != srs_success) {
return srs_error_wrap(err, "encode mdat");
}
// TODO: FIXME: Ensure all bytes are writen.
if ((err = wsio->write(data, nb_data, NULL)) != srs_success) {
if ((err = wsio->write(data.get(), nb_data, NULL)) != srs_success) {
return srs_error_wrap(err, "write mdat");
}
@ -5874,9 +5862,8 @@ srs_error_t SrsMp4Encoder::flush()
// Write moov.
if (true) {
SrsMp4MovieBox* moov = new SrsMp4MovieBox();
SrsAutoFree(SrsMp4MovieBox, moov);
SrsUniquePtr<SrsMp4MovieBox> moov(new SrsMp4MovieBox());
SrsMp4MovieHeaderBox* mvhd = new SrsMp4MovieHeaderBox();
moov->set_mvhd(mvhd);
@ -6057,23 +6044,20 @@ srs_error_t SrsMp4Encoder::flush()
}
}
if ((err = samples->write(moov)) != srs_success) {
if ((err = samples->write(moov.get())) != srs_success) {
return srs_error_wrap(err, "write samples");
}
int nb_data = moov->nb_bytes();
uint8_t* data = new uint8_t[nb_data];
SrsAutoFreeA(uint8_t, data);
SrsBuffer* buffer = new SrsBuffer((char*)data, nb_data);
SrsAutoFree(SrsBuffer, buffer);
if ((err = moov->encode(buffer)) != srs_success) {
SrsUniquePtr<uint8_t[]> data(new uint8_t[nb_data]);
SrsUniquePtr<SrsBuffer> buffer(new SrsBuffer((char*)data.get(), nb_data));
if ((err = moov->encode(buffer.get())) != srs_success) {
return srs_error_wrap(err, "encode moov");
}
// TODO: FIXME: Ensure all bytes are writen.
if ((err = wsio->write(data, nb_data, NULL)) != srs_success) {
if ((err = wsio->write(data.get(), nb_data, NULL)) != srs_success) {
return srs_error_wrap(err, "write moov");
}
}
@ -6083,21 +6067,17 @@ srs_error_t SrsMp4Encoder::flush()
// Write mdat box with size of data,
// its payload already writen by samples,
// and we will update its header(size) when flush.
SrsMp4MediaDataBox* mdat = new SrsMp4MediaDataBox();
SrsAutoFree(SrsMp4MediaDataBox, mdat);
SrsUniquePtr<SrsMp4MediaDataBox> mdat(new SrsMp4MediaDataBox());
// Update the size of mdat first, for over 2GB file.
mdat->nb_data = mdat_bytes;
mdat->update_size();
int nb_data = mdat->sz_header();
uint8_t* data = new uint8_t[nb_data];
SrsAutoFreeA(uint8_t, data);
SrsBuffer* buffer = new SrsBuffer((char*)data, nb_data);
SrsAutoFree(SrsBuffer, buffer);
SrsUniquePtr<uint8_t[]> data(new uint8_t[nb_data]);
if ((err = mdat->encode(buffer)) != srs_success) {
SrsUniquePtr<SrsBuffer> buffer(new SrsBuffer((char*)data.get(), nb_data));
if ((err = mdat->encode(buffer.get())) != srs_success) {
return srs_error_wrap(err, "encode mdat");
}
@ -6117,7 +6097,7 @@ srs_error_t SrsMp4Encoder::flush()
}
// TODO: FIXME: Ensure all bytes are writen.
if ((err = wsio->write(data, nb_data, NULL)) != srs_success) {
if ((err = wsio->write(data.get(), nb_data, NULL)) != srs_success) {
return srs_error_wrap(err, "write mdat");
}
}
@ -6231,22 +6211,20 @@ srs_error_t SrsMp4M2tsInitEncoder::write(SrsFormat* format, bool video, int tid)
// Write ftyp box.
if (true) {
SrsMp4FileTypeBox* ftyp = new SrsMp4FileTypeBox();
SrsAutoFree(SrsMp4FileTypeBox, ftyp);
SrsUniquePtr<SrsMp4FileTypeBox> ftyp(new SrsMp4FileTypeBox());
ftyp->major_brand = SrsMp4BoxBrandISO5;
ftyp->minor_version = 512;
ftyp->set_compatible_brands(SrsMp4BoxBrandISO6, SrsMp4BoxBrandMP41);
if ((err = srs_mp4_write_box(writer, ftyp)) != srs_success) {
if ((err = srs_mp4_write_box(writer, ftyp.get())) != srs_success) {
return srs_error_wrap(err, "write ftyp");
}
}
// Write moov.
if (true) {
SrsMp4MovieBox* moov = new SrsMp4MovieBox();
SrsAutoFree(SrsMp4MovieBox, moov);
SrsUniquePtr<SrsMp4MovieBox> moov(new SrsMp4MovieBox());
SrsMp4MovieHeaderBox* mvhd = new SrsMp4MovieHeaderBox();
moov->set_mvhd(mvhd);
@ -6456,7 +6434,7 @@ srs_error_t SrsMp4M2tsInitEncoder::write(SrsFormat* format, bool video, int tid)
trex->default_sample_description_index = 1;
}
if ((err = srs_mp4_write_box(writer, moov)) != srs_success) {
if ((err = srs_mp4_write_box(writer, moov.get())) != srs_success) {
return srs_error_wrap(err, "write moov");
}
}
@ -6492,9 +6470,8 @@ srs_error_t SrsMp4M2tsSegmentEncoder::initialize(ISrsWriter* w, uint32_t sequenc
// Write styp box.
if (true) {
SrsMp4SegmentTypeBox* styp = new SrsMp4SegmentTypeBox();
SrsAutoFree(SrsMp4SegmentTypeBox, styp);
SrsUniquePtr<SrsMp4SegmentTypeBox> styp(new SrsMp4SegmentTypeBox());
styp->major_brand = SrsMp4BoxBrandMSDH;
styp->minor_version = 0;
styp->set_compatible_brands(SrsMp4BoxBrandMSDH, SrsMp4BoxBrandMSIX);
@ -6502,7 +6479,7 @@ srs_error_t SrsMp4M2tsSegmentEncoder::initialize(ISrsWriter* w, uint32_t sequenc
// Used for sidx to calcalute the referenced size.
styp_bytes = styp->nb_bytes();
if ((err = srs_mp4_write_box(writer, styp)) != srs_success) {
if ((err = srs_mp4_write_box(writer, styp.get())) != srs_success) {
return srs_error_wrap(err, "write styp");
}
}
@ -6556,8 +6533,7 @@ srs_error_t SrsMp4M2tsSegmentEncoder::flush(uint64_t& dts)
}
// Although the sidx is not required to start play DASH, but it's required for AV sync.
SrsMp4SegmentIndexBox* sidx = new SrsMp4SegmentIndexBox();
SrsAutoFree(SrsMp4SegmentIndexBox, sidx);
SrsUniquePtr<SrsMp4SegmentIndexBox> sidx(new SrsMp4SegmentIndexBox());
if (true) {
sidx->version = 1;
sidx->reference_id = 1;
@ -6580,14 +6556,12 @@ srs_error_t SrsMp4M2tsSegmentEncoder::flush(uint64_t& dts)
// Create a mdat box.
// its payload will be writen by samples,
// and we will update its header(size) when flush.
SrsMp4MediaDataBox* mdat = new SrsMp4MediaDataBox();
SrsAutoFree(SrsMp4MediaDataBox, mdat);
SrsUniquePtr<SrsMp4MediaDataBox> mdat(new SrsMp4MediaDataBox());
// Write moof.
if (true) {
SrsMp4MovieFragmentBox* moof = new SrsMp4MovieFragmentBox();
SrsAutoFree(SrsMp4MovieFragmentBox, moof);
SrsUniquePtr<SrsMp4MovieFragmentBox> moof(new SrsMp4MovieFragmentBox());
SrsMp4MovieFragmentHeaderBox* mfhd = new SrsMp4MovieFragmentHeaderBox();
moof->set_mfhd(mfhd);
@ -6611,7 +6585,7 @@ srs_error_t SrsMp4M2tsSegmentEncoder::flush(uint64_t& dts)
SrsMp4TrackFragmentRunBox* trun = new SrsMp4TrackFragmentRunBox();
traf->set_trun(trun);
if ((err = samples->write(moof, dts)) != srs_success) {
if ((err = samples->write(moof.get(), dts)) != srs_success) {
return srs_error_wrap(err, "write samples");
}
@ -6623,11 +6597,11 @@ srs_error_t SrsMp4M2tsSegmentEncoder::flush(uint64_t& dts)
// Update the size of sidx.
SrsMp4SegmentIndexEntry* entry = &sidx->entries[0];
entry->referenced_size = moof_bytes + mdat->nb_bytes();
if ((err = srs_mp4_write_box(writer, sidx)) != srs_success) {
if ((err = srs_mp4_write_box(writer, sidx.get())) != srs_success) {
return srs_error_wrap(err, "write sidx");
}
if ((err = srs_mp4_write_box(writer, moof)) != srs_success) {
if ((err = srs_mp4_write_box(writer, moof.get())) != srs_success) {
return srs_error_wrap(err, "write moof");
}
}
@ -6635,18 +6609,15 @@ srs_error_t SrsMp4M2tsSegmentEncoder::flush(uint64_t& dts)
// Write mdat.
if (true) {
int nb_data = mdat->sz_header();
uint8_t* data = new uint8_t[nb_data];
SrsAutoFreeA(uint8_t, data);
SrsBuffer* buffer = new SrsBuffer((char*)data, nb_data);
SrsAutoFree(SrsBuffer, buffer);
if ((err = mdat->encode(buffer)) != srs_success) {
SrsUniquePtr<uint8_t[]> data(new uint8_t[nb_data]);
SrsUniquePtr<SrsBuffer> buffer(new SrsBuffer((char*)data.get(), nb_data));
if ((err = mdat->encode(buffer.get())) != srs_success) {
return srs_error_wrap(err, "encode mdat");
}
// TODO: FIXME: Ensure all bytes are writen.
if ((err = writer->write(data, nb_data, NULL)) != srs_success) {
if ((err = writer->write(data.get(), nb_data, NULL)) != srs_success) {
return srs_error_wrap(err, "write mdat");
}

View file

@ -107,8 +107,7 @@ srs_error_t SrsPsContext::decode(SrsBuffer* stream, ISrsPsMessageHandler* handle
}
// Reap the last completed PS message.
SrsTsMessage* msg = reap();
SrsAutoFree(SrsTsMessage, msg);
SrsUniquePtr<SrsTsMessage> msg(reap());
if (msg->sid == SrsTsPESStreamIdProgramStreamMap) {
if (!msg->payload || !msg->payload->length()) {
@ -136,7 +135,7 @@ srs_error_t SrsPsContext::decode(SrsBuffer* stream, ISrsPsMessageHandler* handle
helper_.pack_nn_msgs_++;
//srs_error("PS: Got message %s, dts=%" PRId64 ", payload=%dB", msg->is_video() ? "Video" : "Audio", msg->dts/9000, msg->PES_packet_length);
if (handler && (err = handler->on_ts_message(msg)) != srs_success) {
if (handler && (err = handler->on_ts_message(msg.get())) != srs_success) {
return srs_error_wrap(err, "handle PS message");
}
} else {

View file

@ -257,20 +257,20 @@ srs_error_t SrsTsContext::decode(SrsBuffer* stream, ISrsTsHandler* handler)
// parse util EOF of stream.
// for example, parse multiple times for the PES_packet_length(0) packet.
while (!stream->empty()) {
SrsTsPacket* packet = new SrsTsPacket(this);
SrsAutoFree(SrsTsPacket, packet);
SrsTsMessage* msg = NULL;
if ((err = packet->decode(stream, &msg)) != srs_success) {
SrsUniquePtr<SrsTsPacket> packet(new SrsTsPacket(this));
SrsTsMessage* msg_raw = NULL;
if ((err = packet->decode(stream, &msg_raw)) != srs_success) {
return srs_error_wrap(err, "ts: ts packet decode");
}
if (!msg) {
if (!msg_raw) {
continue;
}
SrsAutoFree(SrsTsMessage, msg);
SrsUniquePtr<SrsTsMessage> msg(msg_raw);
if ((err = handler->on_ts_message(msg)) != srs_success) {
if ((err = handler->on_ts_message(msg.get())) != srs_success) {
return srs_error_wrap(err, "ts: handle ts message");
}
}
@ -381,46 +381,42 @@ srs_error_t SrsTsContext::encode_pat_pmt(ISrsStreamWriter* writer, int16_t vpid,
int16_t pmt_number = TS_PMT_NUMBER;
int16_t pmt_pid = TS_PMT_PID;
if (true) {
SrsTsPacket* pkt = SrsTsPacket::create_pat(this, pmt_number, pmt_pid);
SrsAutoFree(SrsTsPacket, pkt);
SrsUniquePtr<SrsTsPacket> pkt(SrsTsPacket::create_pat(this, pmt_number, pmt_pid));
pkt->sync_byte = sync_byte;
char* buf = new char[SRS_TS_PACKET_SIZE];
SrsAutoFreeA(char, buf);
SrsUniquePtr<char[]> buf(new char[SRS_TS_PACKET_SIZE]);
// set the left bytes with 0xFF.
int nb_buf = pkt->size();
srs_assert(nb_buf < SRS_TS_PACKET_SIZE);
memset(buf + nb_buf, 0xFF, SRS_TS_PACKET_SIZE - nb_buf);
memset(buf.get() + nb_buf, 0xFF, SRS_TS_PACKET_SIZE - nb_buf);
SrsBuffer stream(buf, nb_buf);
SrsBuffer stream(buf.get(), nb_buf);
if ((err = pkt->encode(&stream)) != srs_success) {
return srs_error_wrap(err, "ts: encode packet");
}
if ((err = writer->write(buf, SRS_TS_PACKET_SIZE, NULL)) != srs_success) {
if ((err = writer->write(buf.get(), SRS_TS_PACKET_SIZE, NULL)) != srs_success) {
return srs_error_wrap(err, "ts: write packet");
}
}
if (true) {
SrsTsPacket* pkt = SrsTsPacket::create_pmt(this, pmt_number, pmt_pid, vpid, vs, apid, as);
SrsAutoFree(SrsTsPacket, pkt);
SrsUniquePtr<SrsTsPacket> pkt(SrsTsPacket::create_pmt(this, pmt_number, pmt_pid, vpid, vs, apid, as));
pkt->sync_byte = sync_byte;
char* buf = new char[SRS_TS_PACKET_SIZE];
SrsAutoFreeA(char, buf);
SrsUniquePtr<char[]> buf(new char[SRS_TS_PACKET_SIZE]);
// set the left bytes with 0xFF.
int nb_buf = pkt->size();
srs_assert(nb_buf < SRS_TS_PACKET_SIZE);
memset(buf + nb_buf, 0xFF, SRS_TS_PACKET_SIZE - nb_buf);
memset(buf.get() + nb_buf, 0xFF, SRS_TS_PACKET_SIZE - nb_buf);
SrsBuffer stream(buf, nb_buf);
SrsBuffer stream(buf.get(), nb_buf);
if ((err = pkt->encode(&stream)) != srs_success) {
return srs_error_wrap(err, "ts: encode packet");
}
if ((err = writer->write(buf, SRS_TS_PACKET_SIZE, NULL)) != srs_success) {
if ((err = writer->write(buf.get(), SRS_TS_PACKET_SIZE, NULL)) != srs_success) {
return srs_error_wrap(err, "ts: write packet");
}
}
@ -461,7 +457,7 @@ srs_error_t SrsTsContext::encode_pes(ISrsStreamWriter* writer, SrsTsMessage* msg
char* p = start;
while (p < end) {
SrsTsPacket* pkt = NULL;
SrsTsPacket* pkt_raw = NULL;
if (p == start) {
// write pcr according to message.
bool write_pcr = msg->write_pcr;
@ -485,20 +481,19 @@ srs_error_t SrsTsContext::encode_pes(ISrsStreamWriter* writer, SrsTsMessage* msg
int64_t pcr = write_pcr? msg->dts : -1;
// TODO: FIXME: finger it why use discontinuity of msg.
pkt = SrsTsPacket::create_pes_first(this,
pkt_raw = SrsTsPacket::create_pes_first(this,
pid, msg->sid, channel->continuity_counter++, msg->is_discontinuity,
pcr, msg->dts, msg->pts, msg->payload->length()
);
} else {
pkt = SrsTsPacket::create_pes_continue(this, pid, msg->sid, channel->continuity_counter++);
pkt_raw = SrsTsPacket::create_pes_continue(this, pid, msg->sid, channel->continuity_counter++);
}
SrsAutoFree(SrsTsPacket, pkt);
SrsUniquePtr<SrsTsPacket> pkt(pkt_raw);
pkt->sync_byte = sync_byte;
char* buf = new char[SRS_TS_PACKET_SIZE];
SrsAutoFreeA(char, buf);
SrsUniquePtr<char[]> buf(new char[SRS_TS_PACKET_SIZE]);
// set the left bytes with 0xFF.
int nb_buf = pkt->size();
srs_assert(nb_buf < SRS_TS_PACKET_SIZE);
@ -507,7 +502,7 @@ srs_error_t SrsTsContext::encode_pes(ISrsStreamWriter* writer, SrsTsMessage* msg
int nb_stuffings = SRS_TS_PACKET_SIZE - nb_buf - left;
if (nb_stuffings > 0) {
// set all bytes to stuffings.
memset(buf, 0xFF, SRS_TS_PACKET_SIZE);
memset(buf.get(), 0xFF, SRS_TS_PACKET_SIZE);
// padding with stuffings.
pkt->padding(nb_stuffings);
@ -520,14 +515,14 @@ srs_error_t SrsTsContext::encode_pes(ISrsStreamWriter* writer, SrsTsMessage* msg
nb_stuffings = SRS_TS_PACKET_SIZE - nb_buf - left;
srs_assert(nb_stuffings == 0);
}
memcpy(buf + nb_buf, p, left);
memcpy(buf.get() + nb_buf, p, left);
p += left;
SrsBuffer stream(buf, nb_buf);
SrsBuffer stream(buf.get(), nb_buf);
if ((err = pkt->encode(&stream)) != srs_success) {
return srs_error_wrap(err, "ts: encode packet");
}
if ((err = writer->write(buf, SRS_TS_PACKET_SIZE, NULL)) != srs_success) {
if ((err = writer->write(buf.get(), SRS_TS_PACKET_SIZE, NULL)) != srs_success) {
return srs_error_wrap(err, "ts: write packet");
}
}
@ -2773,14 +2768,13 @@ srs_error_t SrsEncFileWriter::write(void* data, size_t count, ssize_t* pnwrite)
if (nb_buf == HLS_AES_ENCRYPT_BLOCK_LENGTH) {
nb_buf = 0;
char* cipher = new char[HLS_AES_ENCRYPT_BLOCK_LENGTH];
SrsAutoFreeA(char, cipher);
SrsUniquePtr<char[]> cipher(new char[HLS_AES_ENCRYPT_BLOCK_LENGTH]);
AES_KEY* k = (AES_KEY*)key;
AES_cbc_encrypt((unsigned char *)buf, (unsigned char *)cipher, HLS_AES_ENCRYPT_BLOCK_LENGTH, k, iv, AES_ENCRYPT);
AES_cbc_encrypt((unsigned char *)buf, (unsigned char *)cipher.get(), HLS_AES_ENCRYPT_BLOCK_LENGTH, k, iv, AES_ENCRYPT);
if ((err = SrsFileWriter::write(cipher, HLS_AES_ENCRYPT_BLOCK_LENGTH, pnwrite)) != srs_success) {
if ((err = SrsFileWriter::write(cipher.get(), HLS_AES_ENCRYPT_BLOCK_LENGTH, pnwrite)) != srs_success) {
return srs_error_wrap(err, "write cipher");
}
}
@ -2809,15 +2803,14 @@ void SrsEncFileWriter::close()
if (nb_padding > 0) {
memset(buf + nb_buf, nb_padding, nb_padding);
}
char* cipher = new char[nb_buf + nb_padding];
SrsAutoFreeA(char, cipher);
SrsUniquePtr<char[]> cipher(new char[nb_buf + nb_padding]);
AES_KEY* k = (AES_KEY*)key;
AES_cbc_encrypt((unsigned char *)buf, (unsigned char *)cipher, nb_buf + nb_padding, k, iv, AES_ENCRYPT);
AES_cbc_encrypt((unsigned char *)buf, (unsigned char *)cipher.get(), nb_buf + nb_padding, k, iv, AES_ENCRYPT);
srs_error_t err = srs_success;
if ((err = SrsFileWriter::write(cipher, nb_buf + nb_padding, NULL)) != srs_success) {
if ((err = SrsFileWriter::write(cipher.get(), nb_buf + nb_padding, NULL)) != srs_success) {
srs_warn("ignore err %s", srs_error_desc(err).c_str());
srs_error_reset(err);
}

View file

@ -28,6 +28,7 @@ using namespace std;
#include <srs_kernel_error.hpp>
#include <srs_kernel_buffer.hpp>
#include <srs_kernel_flv.hpp>
#include <srs_core_deprecated.hpp>
// this value must:
// equals to (SRS_SYS_CYCLE_INTERVAL*SRS_SYS_TIME_RESOLUTION_MS_TIMES)*1000