removed broken frame reording code; unified audio and video frame storing code (in memory, not in the packets); simple workaround to handle non-standard framerate mpeg1/2 video

git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@17299 b3059339-0415-0410-9bf9-f77b7e298cf2
This commit is contained in:
nicodvb 2006-01-03 22:02:11 +00:00
parent fc64668e65
commit a5092cfa00
1 changed files with 48 additions and 108 deletions

View File

@ -314,6 +314,7 @@ static mpeg_frame_t *init_frames(uint16_t num, size_t size)
if(tmp[i].buffer == NULL)
return NULL;
tmp[i].size = 0;
tmp[i].pos = 0;
tmp[i].alloc_size = size;
tmp[i].pts = 0;
}
@ -322,6 +323,7 @@ static mpeg_frame_t *init_frames(uint16_t num, size_t size)
}
static uint32_t calc_pack_hlen(muxer_priv_t *priv, muxer_headers_t *h);
static int add_frame(muxer_headers_t *spriv, uint64_t idur, uint8_t *ptr, int len, uint8_t pt, uint32_t temp_ref);
static muxer_stream_t* mpegfile_new_stream(muxer_t *muxer,int type){
muxer_priv_t *priv = (muxer_priv_t*) muxer->priv;
@ -1017,94 +1019,6 @@ static void patch_panscan(muxer_priv_t *priv, unsigned char *buf)
#define min(a, b) ((a) <= (b) ? (a) : (b))
static int reorder_frame(muxer_headers_t *spriv, uint8_t *ptr, size_t len, uint8_t pt, uint32_t temp_ref, uint64_t idur)
{
uint16_t idx = 0, move=0;
/* HOW TO REORDER FRAMES IN DECODING ORDER:
current frame is n
IF pt(n)==I or P and
n>0 && temp_ref(n) > temp_ref(n-1) && pt(n-1 .. n-m)==B
then insert frame n before frame n-m
and shift forward the others
*/
idx = spriv->framebuf_used;
if(spriv->reorder)
{
//stores the frame in decoding order
if((idx > 0) && ((pt == I_FRAME) || (pt == P_FRAME)))
{
if((spriv->framebuf[idx - 1].type == B_FRAME) && (spriv->framebuf[idx - 1].temp_ref == temp_ref-1))
{
while((spriv->framebuf[idx - 1].type == B_FRAME) && (spriv->framebuf[idx - 1].temp_ref < temp_ref) && (idx > 0))
idx--;
move = spriv->framebuf_used - idx; //from idx there are 'move' frames to move forward
}
}
}
//now idx is the position where we should store the frame
if(idx+move >= spriv->framebuf_cnt)
{ //realloc
spriv->framebuf = (mpeg_frame_t*) realloc(spriv->framebuf, (spriv->framebuf_cnt+1)*sizeof(mpeg_frame_t));
if(spriv->framebuf == NULL)
{
mp_msg(MSGT_MUXER, MSGL_FATAL, "Couldn't realloc frame buffer(idx), abort\n");
return 0;
}
spriv->framebuf[spriv->framebuf_cnt].size = 0;
spriv->framebuf[spriv->framebuf_cnt].alloc_size = 0;
spriv->framebuf[spriv->framebuf_cnt].buffer = (uint8_t*) malloc(len);
if(spriv->framebuf[spriv->framebuf_cnt].buffer == NULL)
{
mp_msg(MSGT_MUXER, MSGL_FATAL, "Couldn't realloc frame buffer(frame), abort\n");
return 0;
}
spriv->framebuf[spriv->framebuf_cnt].alloc_size = len;
spriv->framebuf_cnt++;
}
while(move > 0)
{
mpeg_frame_t f;
f = spriv->framebuf[move + idx];
spriv->framebuf[move + idx] = spriv->framebuf[move + idx - 1];
spriv->framebuf[move + idx - 1] = f;
move--;
}
if(spriv->framebuf[idx].alloc_size < len)
{
spriv->framebuf[idx].buffer = realloc(spriv->framebuf[idx].buffer, len);
if(spriv->framebuf[idx].buffer == NULL)
{
mp_msg(MSGT_MUXER, MSGL_FATAL, "Couldn't realloc frame buffer(frame), abort\n");
return 0;
}
spriv->framebuf[idx].alloc_size = len;
}
mp_msg(MSGT_MUXER, MSGL_DBG2, "\nIDX: %u, type: %c, temp_ref: %u, ptr: %p, len: %u, alloc: %u, buffer: %p\n",
(uint32_t) idx, FTYPE(pt), temp_ref, ptr, (uint32_t) len, (uint32_t) spriv->framebuf[idx].alloc_size, spriv->framebuf[idx].buffer);
memcpy(spriv->framebuf[idx].buffer, ptr, len);
spriv->framebuf[idx].pos = 0;
spriv->framebuf[idx].size = len;
spriv->framebuf[idx].temp_ref = temp_ref;
spriv->framebuf[idx].type = pt;
spriv->framebuf[idx].idur = idur;
spriv->framebuf_used++;
return 1;
}
static uint32_t dump_audio(muxer_t *muxer, muxer_stream_t *as, uint32_t abytes, int force)
{
uint32_t len = 0, tlen, sz;
@ -1201,6 +1115,7 @@ static uint32_t dump_audio(muxer_t *muxer, muxer_stream_t *as, uint32_t abytes,
{
for(j = n; j < apriv->framebuf_used; j++)
{
apriv->framebuf[j - n].size = apriv->framebuf[j - n].pos = 0;
frm2 = apriv->framebuf[j - n];
apriv->framebuf[j - n] = apriv->framebuf[j];
apriv->framebuf[j] = frm2;
@ -1812,6 +1727,8 @@ init:
vpriv->last_pts += idur;
}
for(i=0; i<n; i++)
vpriv->framebuf[i].pos = vpriv->framebuf[i].size = 0;
for(i = n; i < vpriv->framebuf_used; i++)
{
temp_frame = vpriv->framebuf[i - n];
@ -1820,7 +1737,6 @@ init:
}
vpriv->framebuf_used -= n;
if((as != NULL) && priv->has_audio)
{
while(abytes > 0)
@ -1953,6 +1869,9 @@ static size_t parse_mpeg12_video(muxer_stream_t *s, muxer_priv_t *priv, muxer_he
spriv->delta_pts = spriv->nom_delta_pts = parse_fps(spriv->picture.fps);
spriv->delta_clock = (double) 1/fps;
//the 2 lines below are needed to handle non-standard frame rates (such as 18)
if(! spriv->delta_pts)
spriv->delta_pts = spriv->nom_delta_pts = (uint64_t) ((double)92160000.0 * spriv->delta_clock );
mp_msg(MSGT_MUXER, MSGL_DBG2, "\nFPS: %.3f, FRAMETIME: %.3lf\n", fps, (double)1/fps);
if(priv->patch_seq)
patch_seq(priv, s->buffer);
@ -2086,7 +2005,7 @@ static size_t parse_mpeg12_video(muxer_stream_t *s, muxer_priv_t *priv, muxer_he
}
spriv->vframes++;
reorder_frame(spriv, s->buffer, len, pt, temp_ref, spriv->delta_pts);
add_frame(spriv, spriv->delta_pts, s->buffer, len, pt, temp_ref);
}
mp_msg(MSGT_MUXER, MSGL_DBG2,"parse_mpeg12_video, return %u\n", (uint32_t) len);
@ -2195,7 +2114,7 @@ static size_t parse_mpeg4_video(muxer_stream_t *s, muxer_priv_t *priv, muxer_hea
vpriv->last_dts += vpriv->frame_duration;
vpriv->last_pts += delta_pts;
reorder_frame(vpriv, s->buffer, len, pt, 0, delta_pts);
add_frame(vpriv, delta_pts, s->buffer, len, pt, 0);
vpriv->framebuf[vpriv->framebuf_used-1].pts = vpriv->last_pts;
vpriv->framebuf[vpriv->framebuf_used-1].dts = vpriv->last_dts;
vpriv->framebuf[vpriv->framebuf_used-1].idur = vpriv->frame_duration;
@ -2251,8 +2170,7 @@ static int fill_last_frame(muxer_headers_t *spriv, uint8_t *ptr, int len)
return len;
}
static int add_audio_frame(muxer_headers_t *spriv, uint64_t idur, uint8_t *ptr, int len)
static int add_frame(muxer_headers_t *spriv, uint64_t idur, uint8_t *ptr, int len, uint8_t pt, uint32_t temp_ref)
{
int idx, i;
@ -2263,7 +2181,7 @@ static int add_audio_frame(muxer_headers_t *spriv, uint64_t idur, uint8_t *ptr,
if(spriv->framebuf == NULL)
{
mp_msg(MSGT_MUXER, MSGL_FATAL, "Couldn't realloc frame buffer(idx), abort\n");
return 0;
return -1;
}
spriv->framebuf[spriv->framebuf_cnt].size = 0;
@ -2274,7 +2192,7 @@ static int add_audio_frame(muxer_headers_t *spriv, uint64_t idur, uint8_t *ptr,
if(spriv->framebuf[spriv->framebuf_cnt].buffer == NULL)
{
mp_msg(MSGT_MUXER, MSGL_FATAL, "Couldn't realloc frame buffer(frame), abort\n");
return 0;
return -1;
}
spriv->framebuf[spriv->framebuf_cnt].alloc_size = len;
spriv->framebuf_cnt++;
@ -2286,7 +2204,7 @@ static int add_audio_frame(muxer_headers_t *spriv, uint64_t idur, uint8_t *ptr,
if(spriv->framebuf[idx].buffer == NULL)
{
mp_msg(MSGT_MUXER, MSGL_FATAL, "Couldn't realloc frame buffer(frame), abort\n");
return 0;
return -1;
}
spriv->framebuf[idx].alloc_size = spriv->framebuf[idx].size + len;
}
@ -2294,17 +2212,13 @@ static int add_audio_frame(muxer_headers_t *spriv, uint64_t idur, uint8_t *ptr,
memcpy(&(spriv->framebuf[idx].buffer[spriv->framebuf[idx].size]), ptr, len);
spriv->framebuf[idx].size += len;
spriv->framebuf[idx].pos = 0;
spriv->framebuf[idx].temp_ref = temp_ref;
spriv->framebuf[idx].type = pt;
spriv->framebuf[idx].idur = idur;
spriv->framebuf[idx].pts = spriv->last_pts;
spriv->framebuf_used++;
for(i = idx; i < spriv->framebuf_cnt; i++)
spriv->framebuf[i].pts = spriv->last_pts;
spriv->last_pts += idur;
return 1;
return idx;
}
@ -2312,7 +2226,7 @@ extern int aac_parse_frame(uint8_t *buf, int *srate, int *num);
static int parse_audio(muxer_stream_t *s, int finalize, int *nf, double *timer)
{
int i, len, chans, srate, spf, layer, dummy, tot, num, frames;
int i, j, len, chans, srate, spf, layer, dummy, tot, num, frames, frm_idx;
uint64_t idur;
muxer_headers_t *spriv = (muxer_headers_t *) s->priv;
@ -2333,7 +2247,13 @@ static int parse_audio(muxer_stream_t *s, int finalize, int *nf, double *timer)
fill_last_frame(spriv, &(s->b_buffer[tot]), i - tot);
idur = (92160000ULL * spf) / srate;
add_audio_frame(spriv, idur, &(s->b_buffer[i]), len);
frm_idx = add_frame(spriv, idur, &(s->b_buffer[i]), len, 0, 0);
if(frm_idx < 0)
continue;
for(j = frm_idx; j < spriv->framebuf_cnt; j++)
spriv->framebuf[j].pts = spriv->last_pts;
spriv->last_pts += idur;
i += len;
tot = i;
continue;
@ -2357,7 +2277,13 @@ static int parse_audio(muxer_stream_t *s, int finalize, int *nf, double *timer)
fill_last_frame(spriv, &(s->b_buffer[tot]), i - tot);
idur = (92160000ULL * 1536) / srate;
add_audio_frame(spriv, idur, &(s->b_buffer[i]), len);
frm_idx = add_frame(spriv, idur, &(s->b_buffer[i]), len, 0, 0);
if(frm_idx < 0)
continue;
for(j = frm_idx; j < spriv->framebuf_cnt; j++)
spriv->framebuf[j].pts = spriv->last_pts;
spriv->last_pts += idur;
i += len;
tot = i;
continue;
@ -2382,7 +2308,13 @@ static int parse_audio(muxer_stream_t *s, int finalize, int *nf, double *timer)
fill_last_frame(spriv, &(s->b_buffer[tot]), i - tot);
idur = (92160000ULL * 1024 * num) / srate;
add_audio_frame(spriv, idur, &(s->b_buffer[i]), len);
frm_idx = add_frame(spriv, idur, &(s->b_buffer[i]), len, 0, 0);
if(frm_idx < 0)
continue;
for(j = frm_idx; j < spriv->framebuf_cnt; j++)
spriv->framebuf[j].pts = spriv->last_pts;
spriv->last_pts += idur;
i += len;
tot = i;
continue;
@ -2404,7 +2336,15 @@ static int parse_audio(muxer_stream_t *s, int finalize, int *nf, double *timer)
}
if(finalize)
add_audio_frame(spriv, 0, s->b_buffer, s->b_buffer_len);
{
frm_idx = add_frame(spriv, 0, s->b_buffer, s->b_buffer_len, 0, 0);
if(frm_idx >= 0)
{
for(j = frm_idx; j < spriv->framebuf_cnt; j++)
spriv->framebuf[j].pts = spriv->last_pts;
}
}
*nf = frames;
*timer = (double) (spriv->last_pts - spriv->init_pts)/92160000.0;