mirror of
https://github.com/mpv-player/mpv
synced 2025-01-01 04:36:24 +01:00
clone_demux_packet(), using refcounting to avoid memcpy()
based on (sligtly simplified) patch by Alexander Neundorf <neundorf@dellingsoft.de> git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@6193 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
parent
37e42a149b
commit
d8c7608ac8
@ -38,7 +38,7 @@ demux_stream_t* new_demuxer_stream(struct demuxer_st *demuxer,int id){
|
||||
//---------------
|
||||
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 @@ int demux_fill_buffer(demuxer_t *demux,demux_stream_t *ds){
|
||||
// 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 @@ int ds_fill_buffer(demux_stream_t *ds){
|
||||
}
|
||||
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 @@ int ds_fill_buffer(demux_stream_t *ds){
|
||||
}
|
||||
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 @@ void ds_free_packs(demux_stream_t *ds){
|
||||
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 @@ void ds_free_packs(demux_stream_t *ds){
|
||||
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;
|
||||
|
@ -51,13 +51,15 @@ typedef struct demux_packet_st {
|
||||
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 @@ typedef struct {
|
||||
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 @@ inline static demux_packet_t* new_demux_packet(int len){
|
||||
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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user