mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
dshow: use distinct buffers per stream.
Basically sometimes if you start dropping video packets, you also drop audio packets. Now they each have separate buffers to avoid this unexpected behavior. Signed-off-by: rogerdpack <rogerpack2005@gmail.com> Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
parent
87ecefdab0
commit
6abc56e892
@ -53,7 +53,7 @@ struct dshow_ctx {
|
|||||||
|
|
||||||
int eof;
|
int eof;
|
||||||
|
|
||||||
int64_t curbufsize;
|
int64_t curbufsize[2];
|
||||||
unsigned int video_frame_num;
|
unsigned int video_frame_num;
|
||||||
|
|
||||||
IMediaControl *control;
|
IMediaControl *control;
|
||||||
@ -180,16 +180,16 @@ static char *dup_wchar_to_utf8(wchar_t *w)
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int shall_we_drop(AVFormatContext *s)
|
static int shall_we_drop(AVFormatContext *s, int index)
|
||||||
{
|
{
|
||||||
struct dshow_ctx *ctx = s->priv_data;
|
struct dshow_ctx *ctx = s->priv_data;
|
||||||
static const uint8_t dropscore[] = {62, 75, 87, 100};
|
static const uint8_t dropscore[] = {62, 75, 87, 100};
|
||||||
const int ndropscores = FF_ARRAY_ELEMS(dropscore);
|
const int ndropscores = FF_ARRAY_ELEMS(dropscore);
|
||||||
unsigned int buffer_fullness = (ctx->curbufsize*100)/s->max_picture_buffer;
|
unsigned int buffer_fullness = (ctx->curbufsize[index]*100)/s->max_picture_buffer;
|
||||||
|
|
||||||
if(dropscore[++ctx->video_frame_num%ndropscores] <= buffer_fullness) {
|
if(dropscore[++ctx->video_frame_num%ndropscores] <= buffer_fullness) {
|
||||||
av_log(s, AV_LOG_ERROR,
|
av_log(s, AV_LOG_ERROR,
|
||||||
"real-time buffer %d%% full! frame dropped!\n", buffer_fullness);
|
"real-time buffer[%d] too full (%d%% of size: %d)! frame dropped!\n", index, buffer_fullness, s->max_picture_buffer);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -207,7 +207,7 @@ callback(void *priv_data, int index, uint8_t *buf, int buf_size, int64_t time)
|
|||||||
|
|
||||||
WaitForSingleObject(ctx->mutex, INFINITE);
|
WaitForSingleObject(ctx->mutex, INFINITE);
|
||||||
|
|
||||||
if(shall_we_drop(s))
|
if(shall_we_drop(s, index))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
pktl_next = av_mallocz(sizeof(AVPacketList));
|
pktl_next = av_mallocz(sizeof(AVPacketList));
|
||||||
@ -225,8 +225,7 @@ callback(void *priv_data, int index, uint8_t *buf, int buf_size, int64_t time)
|
|||||||
|
|
||||||
for(ppktl = &ctx->pktl ; *ppktl ; ppktl = &(*ppktl)->next);
|
for(ppktl = &ctx->pktl ; *ppktl ; ppktl = &(*ppktl)->next);
|
||||||
*ppktl = pktl_next;
|
*ppktl = pktl_next;
|
||||||
|
ctx->curbufsize[index] += buf_size;
|
||||||
ctx->curbufsize += buf_size;
|
|
||||||
|
|
||||||
SetEvent(ctx->event[1]);
|
SetEvent(ctx->event[1]);
|
||||||
ReleaseMutex(ctx->mutex);
|
ReleaseMutex(ctx->mutex);
|
||||||
@ -944,7 +943,8 @@ static int dshow_read_header(AVFormatContext *avctx)
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ctx->curbufsize[0] = 0;
|
||||||
|
ctx->curbufsize[1] = 0;
|
||||||
ctx->mutex = CreateMutex(NULL, 0, NULL);
|
ctx->mutex = CreateMutex(NULL, 0, NULL);
|
||||||
if (!ctx->mutex) {
|
if (!ctx->mutex) {
|
||||||
av_log(avctx, AV_LOG_ERROR, "Could not create Mutex\n");
|
av_log(avctx, AV_LOG_ERROR, "Could not create Mutex\n");
|
||||||
@ -1038,7 +1038,7 @@ static int dshow_read_packet(AVFormatContext *s, AVPacket *pkt)
|
|||||||
*pkt = pktl->pkt;
|
*pkt = pktl->pkt;
|
||||||
ctx->pktl = ctx->pktl->next;
|
ctx->pktl = ctx->pktl->next;
|
||||||
av_free(pktl);
|
av_free(pktl);
|
||||||
ctx->curbufsize -= pkt->size;
|
ctx->curbufsize[pkt->stream_index] -= pkt->size;
|
||||||
}
|
}
|
||||||
ResetEvent(ctx->event[1]);
|
ResetEvent(ctx->event[1]);
|
||||||
ReleaseMutex(ctx->mutex);
|
ReleaseMutex(ctx->mutex);
|
||||||
|
Loading…
Reference in New Issue
Block a user