[Mplayer-cvslog] CVS: main/libmpdemux demuxer.c,1.97,1.98 demuxer.h,1.38,1.39
Arpi of Ize
arpi at mplayerhq.hu
Sun May 26 00:13:26 CEST 2002
Update of /cvsroot/mplayer/main/libmpdemux
In directory mail:/var/tmp.root/cvs-serv13231
Modified Files:
demuxer.c demuxer.h
Log Message:
clone_demux_packet(), using refcounting to avoid memcpy()
based on (sligtly simplified) patch by Alexander Neundorf <neundorf at dellingsoft.de>
Index: demuxer.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/demuxer.c,v
retrieving revision 1.97
retrieving revision 1.98
diff -u -r1.97 -r1.98
--- demuxer.c 2 May 2002 10:25:48 -0000 1.97
+++ demuxer.c 25 May 2002 22:13:23 -0000 1.98
@@ -38,7 +38,7 @@
//---------------
ds->packs=0;
ds->bytes=0;
- ds->first=ds->last=NULL;
+ ds->first=ds->last=ds->current=NULL;
ds->id=id;
ds->demuxer=demuxer;
//----------------
@@ -296,7 +296,7 @@
// 1 = succesfull
int ds_fill_buffer(demux_stream_t *ds){
demuxer_t *demux=ds->demuxer;
- if(ds->buffer) free(ds->buffer);
+ if(ds->current) free_demux_packet(ds->current);
if(verbose>2){
if(ds==demux->audio) mp_dbg(MSGT_DEMUXER,MSGL_DBG3,"ds_fill_buffer(d_audio) called\n");else
if(ds==demux->video) mp_dbg(MSGT_DEMUXER,MSGL_DBG3,"ds_fill_buffer(d_video) called\n");else
@@ -319,11 +319,11 @@
}
ds->pts_bytes+=p->len; // !!!
ds->flags=p->flags;
- // free packet:
+ // unlink packet:
ds->bytes-=p->len;
+ ds->current=p;
ds->first=p->next;
if(!ds->first) ds->last=NULL;
- free(p);
--ds->packs;
return 1; //ds->buffer_size;
}
@@ -344,6 +344,7 @@
}
ds->buffer_pos=ds->buffer_size=0;
ds->buffer=NULL;
+ ds->current=NULL;
mp_msg(MSGT_DEMUXER,MSGL_V,"ds_fill_buffer: EOF reached (stream: %s) \n",ds==demux->audio?"audio":"video");
ds->eof=1;
return 0;
@@ -387,8 +388,7 @@
demux_packet_t *dp=ds->first;
while(dp){
demux_packet_t *dn=dp->next;
- if(dp->buffer) free(dp->buffer);
- free(dp);
+ free_demux_packet(dp);
dp=dn;
}
if(ds->asf_packet){
@@ -400,7 +400,8 @@
ds->first=ds->last=NULL;
ds->packs=0; // !!!!!
ds->bytes=0;
- if(ds->buffer) free(ds->buffer);
+ if(ds->current) free_demux_packet(ds->current);
+ ds->current=NULL;
ds->buffer=NULL;
ds->buffer_pos=ds->buffer_size;
ds->pts=0; ds->pts_bytes=0;
Index: demuxer.h
===================================================================
RCS file: /cvsroot/mplayer/main/libmpdemux/demuxer.h,v
retrieving revision 1.38
retrieving revision 1.39
diff -u -r1.38 -r1.39
--- demuxer.h 2 May 2002 10:25:48 -0000 1.38
+++ demuxer.h 25 May 2002 22:13:23 -0000 1.39
@@ -51,13 +51,15 @@
off_t pos; // position in index (AVI) or file (MPG)
unsigned char* buffer;
int flags; // keyframe, etc
+ int refcount; //refcounter for the master packet, if 0, buffer can be free()d
+ struct demux_packet_st* master; //pointer to the master packet if this one is a cloned one
struct demux_packet_st* next;
} demux_packet_t;
typedef struct {
int buffer_pos; // current buffer position
int buffer_size; // current buffer size
- unsigned char* buffer; // current buffer
+ unsigned char* buffer; // current buffer, never free() it, always use free_demux_packet(buffer_ref);
float pts; // current buffer's pts
int pts_bytes; // number of bytes read after last pts stamp
int eof; // end of demuxed stream? (true if all buffer empty)
@@ -70,6 +72,7 @@
int bytes; // total bytes of packets in buffer
demux_packet_t *first; // read to current buffer from here
demux_packet_t *last; // append new packets from input stream to here
+ demux_packet_t *current;// needed for refcounting of the buffer
int id; // stream ID (for multiple audio/video streams)
struct demuxer_st *demuxer; // parent demuxer structure (stream handler)
// ---- asf -----
@@ -123,11 +126,33 @@
dp->pts=0;
dp->pos=0;
dp->flags=0;
+ dp->refcount=1;
+ dp->master=NULL;
+ return dp;
+}
+
+inline static demux_packet_t* clone_demux_packet(demux_packet_t* pack){
+ demux_packet_t* dp=malloc(sizeof(demux_packet_t));
+ while(pack->master) pack=pack->master; // find the master
+ memcpy(dp,pack,sizeof(demux_packet_t));
+ dp->next=NULL;
+ dp->refcount=0;
+ dp->master=pack;
+ pack->refcount++;
return dp;
}
inline static void free_demux_packet(demux_packet_t* dp){
- free(dp->buffer);
+ if (dp->master==NULL){ //dp is a master packet
+ dp->refcount--;
+ if (dp->refcount==0){
+ if (dp->buffer) free(dp->buffer);
+ free(dp);
+ }
+ return;
+ }
+ // dp is a clone:
+ free_demux_packet(dp->master);
free(dp);
}
More information about the MPlayer-cvslog
mailing list