On 2/7/2021 4:47 AM, Andreas Rheinhardt wrote:
James Almer:
Signed-off-by: James Almer <jamr...@gmail.com>
---
This one must be committed after the upcoming major bump, as it changes
the return value of an avpriv function.
libavdevice/iec61883.c | 2 +-
libavformat/dv.c | 56 ++++++++++++++++++++++++++++--------------
2 files changed, 38 insertions(+), 20 deletions(-)
diff --git a/libavdevice/iec61883.c b/libavdevice/iec61883.c
index cafafb2672..4582ada151 100644
--- a/libavdevice/iec61883.c
+++ b/libavdevice/iec61883.c
@@ -191,7 +191,7 @@ static int iec61883_parse_queue_dv(struct iec61883_data
*dv, AVPacket *pkt)
int size;
size = avpriv_dv_get_packet(dv->dv_demux, pkt);
- if (size > 0)
+ if (size)
return size;
packet = dv->queue_first;
diff --git a/libavformat/dv.c b/libavformat/dv.c
index 26a78139f5..f5c0c44afc 100644
--- a/libavformat/dv.c
+++ b/libavformat/dv.c
@@ -45,7 +45,7 @@ struct DVDemuxContext {
AVFormatContext* fctx;
AVStream* vst;
AVStream* ast[4];
- AVPacket audio_pkt[4];
+ AVPacket *audio_pkt[4];
uint8_t audio_buf[4][8192];
int ach;
int frames;
@@ -261,11 +261,10 @@ static int dv_extract_audio_info(DVDemuxContext *c, const
uint8_t *frame)
c->ast[i]->codecpar->codec_type = AVMEDIA_TYPE_AUDIO;
c->ast[i]->codecpar->codec_id = AV_CODEC_ID_PCM_S16LE;
- av_init_packet(&c->audio_pkt[i]);
- c->audio_pkt[i].size = 0;
- c->audio_pkt[i].data = c->audio_buf[i];
- c->audio_pkt[i].stream_index = c->ast[i]->index;
- c->audio_pkt[i].flags |= AV_PKT_FLAG_KEY;
+ c->audio_pkt[i]->size = 0;
+ c->audio_pkt[i]->data = c->audio_buf[i];
+ c->audio_pkt[i]->stream_index = c->ast[i]->index;
+ c->audio_pkt[i]->flags |= AV_PKT_FLAG_KEY;
}
c->ast[i]->codecpar->sample_rate = dv_audio_frequency[freq];
c->ast[i]->codecpar->channels = 2;
@@ -332,6 +331,12 @@ static int dv_init_demux(AVFormatContext *s,
DVDemuxContext *c)
c->vst->codecpar->bit_rate = 25000000;
c->vst->start_time = 0;
+ for (int i = 0; i < 4; i++) {
+ c->audio_pkt[i] = av_packet_alloc();
+ if (!c->audio_pkt[i])
+ return AVERROR(ENOMEM);
This leads to lots of leaks on error, for both avpriv_dv_init_demux (for
which a free function will be necessary) as well as the dv demuxer
(whose read_close function is not called automatically on error).
Will fix.
+ }
+
return 0;
}
@@ -353,13 +358,15 @@ DVDemuxContext *avpriv_dv_init_demux(AVFormatContext *s)
int avpriv_dv_get_packet(DVDemuxContext *c, AVPacket *pkt)
{
- int size = -1;
+ int size = 0;
int i;
for (i = 0; i < c->ach; i++) {
- if (c->ast[i] && c->audio_pkt[i].size) {
- *pkt = c->audio_pkt[i];
- c->audio_pkt[i].size = 0;
+ if (c->ast[i] && c->audio_pkt[i]->size) {
+ int ret = av_packet_ref(pkt, c->audio_pkt[i]);
+ if (ret < 0)
+ return ret;
+ c->audio_pkt[i]->size = 0;
size = pkt->size;
break;
}
@@ -384,9 +391,9 @@ int avpriv_dv_produce_packet(DVDemuxContext *c, AVPacket
*pkt,
/* FIXME: in case of no audio/bad audio we have to do something */
size = dv_extract_audio_info(c, buf);
for (i = 0; i < c->ach; i++) {
- c->audio_pkt[i].pos = pos;
- c->audio_pkt[i].size = size;
- c->audio_pkt[i].pts = (c->sys->height == 720) ? (c->frames & ~1) :
c->frames;
+ c->audio_pkt[i]->pos = pos;
+ c->audio_pkt[i]->size = size;
+ c->audio_pkt[i]->pts = (c->sys->height == 720) ? (c->frames & ~1) :
c->frames;
ppcm[i] = c->audio_buf[i];
}
if (c->ach)
@@ -396,15 +403,14 @@ int avpriv_dv_produce_packet(DVDemuxContext *c, AVPacket
*pkt,
* channels 0,1 and odd 2,3. */
if (c->sys->height == 720) {
if (buf[1] & 0x0C) {
- c->audio_pkt[2].size = c->audio_pkt[3].size = 0;
+ c->audio_pkt[2]->size = c->audio_pkt[3]->size = 0;
} else {
- c->audio_pkt[0].size = c->audio_pkt[1].size = 0;
+ c->audio_pkt[0]->size = c->audio_pkt[1]->size = 0;
}
}
/* Now it's time to return video packet */
size = dv_extract_video_info(c, buf);
- av_init_packet(pkt);
This function here is a bit nuts: It predates reference-counted buffers
and so it simply resets pkt->buf (it in fact treats pkt purely as
something for output as if it were already blank). The mov and avi
demuxers work around this by copying pkt->buf and putting it in the
returned packet afterwards (which is probably unnecessary when the above
call is ; whereas the iec61883 device/demuxer really puts a blank packet
in there and makes it refcounted afterwards. It would be nice if this
whole mess were to be cleaned up.
I agree it could be better, but I'm not going to rewrite a function i
can't test. Last time i handled this shared code to fix a massive memory
leak i had the help of a trac user that could test the iec61883 device.
pkt->data = buf;
pkt->pos = pos;
pkt->size = size;
@@ -439,8 +445,8 @@ static int64_t dv_frame_offset(AVFormatContext *s,
DVDemuxContext *c,
void ff_dv_offset_reset(DVDemuxContext *c, int64_t frame_offset)
{
c->frames = frame_offset;
- c->audio_pkt[0].size = c->audio_pkt[1].size = 0;
- c->audio_pkt[2].size = c->audio_pkt[3].size = 0;
+ c->audio_pkt[0]->size = c->audio_pkt[1]->size = 0;
+ c->audio_pkt[2]->size = c->audio_pkt[3]->size = 0;
}
/************************************************************
@@ -539,7 +545,7 @@ static int dv_read_packet(AVFormatContext *s, AVPacket *pkt)
size = avpriv_dv_get_packet(&c->dv_demux, pkt);
- if (size < 0) {
+ if (!size) {
int ret;
int64_t pos = avio_tell(s->pb);
if (!c->dv_demux.sys)
@@ -614,6 +620,17 @@ static int dv_probe(const AVProbeData *p)
return 0;
}
+static int dv_read_close(AVFormatContext *s)
+{
+ RawDVContext *r = s->priv_data;
+ DVDemuxContext *c = &r->dv_demux;
+
+ for (int i = 0; i < 4; i++)
+ av_packet_free(&c->audio_pkt[i]);
+
+ return 0;
+}
+
AVInputFormat ff_dv_demuxer = {
.name = "dv",
.long_name = NULL_IF_CONFIG_SMALL("DV (Digital Video)"),
@@ -622,5 +639,6 @@ AVInputFormat ff_dv_demuxer = {
.read_header = dv_read_header,
.read_packet = dv_read_packet,
.read_seek = dv_read_seek,
+ .read_close = dv_read_close,
.extensions = "dv,dif",
};
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".
_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".