New upstream version 24.0.1+dfsg1

This commit is contained in:
Sebastian Ramacher 2019-09-22 23:19:10 +02:00
parent b14f9eae6d
commit 5a730d6ec3
842 changed files with 42245 additions and 33385 deletions

View file

@ -36,13 +36,13 @@ static inline void shrink_packet(struct ff_packet *packet, int packet_length)
int remaining = packet->base.size - packet_length;
memmove(packet->base.data, &packet->base.data[packet_length],
remaining);
remaining);
av_shrink_packet(&packet->base, remaining);
}
}
static bool handle_reset_packet(struct ff_decoder *decoder,
struct ff_packet *packet)
struct ff_packet *packet)
{
if (decoder->clock != NULL)
ff_clock_release(&decoder->clock);
@ -53,27 +53,29 @@ static bool handle_reset_packet(struct ff_decoder *decoder,
}
static void drop_late_packets(struct ff_decoder *decoder,
struct ff_packet *packet)
struct ff_packet *packet)
{
int64_t start_time = ff_clock_start_time(decoder->clock);
if (start_time != AV_NOPTS_VALUE) {
if (ff_decoder_set_frame_drop_state(decoder, start_time,
packet->base.pts))
packet->base.pts))
shrink_packet(packet, packet->base.size);
}
}
static int decode_frame(struct ff_decoder *decoder,
struct ff_packet *packet, AVFrame *frame, bool *frame_complete)
static int decode_frame(struct ff_decoder *decoder, struct ff_packet *packet,
AVFrame *frame, bool *frame_complete)
{
int packet_length;
int ret;
while (true) {
if (decoder->eof)
ret = packet_queue_get(&decoder->packet_queue, packet, 0);
ret = packet_queue_get(&decoder->packet_queue, packet,
0);
else
ret = packet_queue_get(&decoder->packet_queue, packet, 1);
ret = packet_queue_get(&decoder->packet_queue, packet,
1);
if (ret == FF_PACKET_EMPTY) {
return 0;
@ -82,7 +84,7 @@ static int decode_frame(struct ff_decoder *decoder,
}
if (packet->base.data ==
decoder->packet_queue.flush_packet.base.data) {
decoder->packet_queue.flush_packet.base.data) {
avcodec_flush_buffers(decoder->codec);
continue;
}
@ -98,8 +100,8 @@ static int decode_frame(struct ff_decoder *decoder,
drop_late_packets(decoder, packet);
packet_length = avcodec_decode_audio4(decoder->codec,
frame, &complete,
&packet->base);
frame, &complete,
&packet->base);
if (packet_length < 0)
break;
@ -112,7 +114,7 @@ static int decode_frame(struct ff_decoder *decoder,
*frame_complete = complete != 0;
return frame->nb_samples *
av_get_bytes_per_sample(frame->format);
av_get_bytes_per_sample(frame->format);
}
if (packet->base.data != NULL)
@ -121,7 +123,7 @@ static int decode_frame(struct ff_decoder *decoder,
}
static bool queue_frame(struct ff_decoder *decoder, AVFrame *frame,
double best_effort_pts)
double best_effort_pts)
{
struct ff_frame *queue_frame;
bool call_initialize;
@ -135,10 +137,11 @@ static bool queue_frame(struct ff_decoder *decoder, AVFrame *frame,
queue_frame = ff_circular_queue_peek_write(&decoder->frame_queue);
AVCodecContext *codec = decoder->codec;
call_initialize = (queue_frame->frame == NULL
|| queue_frame->frame->channels != codec->channels
|| queue_frame->frame->sample_rate != codec->sample_rate
|| queue_frame->frame->format != codec->sample_fmt);
call_initialize =
(queue_frame->frame == NULL ||
queue_frame->frame->channels != codec->channels ||
queue_frame->frame->sample_rate != codec->sample_rate ||
queue_frame->frame->format != codec->sample_fmt);
if (queue_frame->frame != NULL) {
//FIXME: this shouldn't happen any more!
@ -183,7 +186,7 @@ void *ff_audio_decoder_thread(void *opaque_audio_decoder)
// This function returns a pts scaled to stream
// time base
double best_effort_pts =
ff_decoder_get_best_effort_pts(decoder, frame);
ff_decoder_get_best_effort_pts(decoder, frame);
queue_frame(decoder, frame, best_effort_pts);
av_frame_unref(frame);
}

View file

@ -16,8 +16,7 @@
#include "ff-callbacks.h"
bool ff_callbacks_frame(struct ff_callbacks *callbacks,
struct ff_frame *frame)
bool ff_callbacks_frame(struct ff_callbacks *callbacks, struct ff_frame *frame)
{
if (callbacks->frame == NULL)
return true;
@ -26,7 +25,7 @@ bool ff_callbacks_frame(struct ff_callbacks *callbacks,
}
bool ff_callbacks_format(struct ff_callbacks *callbacks,
AVCodecContext *codec_context)
AVCodecContext *codec_context)
{
if (callbacks->format == NULL)
return true;
@ -43,7 +42,7 @@ bool ff_callbacks_initialize(struct ff_callbacks *callbacks)
}
bool ff_callbacks_frame_initialize(struct ff_frame *frame,
struct ff_callbacks *callbacks)
struct ff_callbacks *callbacks)
{
if (callbacks->frame_initialize == NULL)
return true;
@ -52,7 +51,7 @@ bool ff_callbacks_frame_initialize(struct ff_frame *frame,
}
bool ff_callbacks_frame_free(struct ff_frame *frame,
struct ff_callbacks *callbacks)
struct ff_callbacks *callbacks)
{
if (callbacks->frame_free == NULL)
return true;

View file

@ -29,7 +29,6 @@ typedef bool (*ff_callback_frame)(struct ff_frame *frame, void *opaque);
typedef bool (*ff_callback_format)(AVCodecContext *codec_context, void *opaque);
typedef bool (*ff_callback_initialize)(void *opaque);
struct ff_callbacks {
ff_callback_frame frame;
ff_callback_format format;
@ -39,15 +38,14 @@ struct ff_callbacks {
void *opaque;
};
bool ff_callbacks_frame(struct ff_callbacks *callbacks,
struct ff_frame *frame);
bool ff_callbacks_frame(struct ff_callbacks *callbacks, struct ff_frame *frame);
bool ff_callbacks_format(struct ff_callbacks *callbacks,
AVCodecContext *codec_context);
AVCodecContext *codec_context);
bool ff_callbacks_initialize(struct ff_callbacks *callbacks);
bool ff_callbacks_frame_initialize(struct ff_frame *frame,
struct ff_callbacks *callbacks);
struct ff_callbacks *callbacks);
bool ff_callbacks_frame_free(struct ff_frame *frame,
struct ff_callbacks *callbacks);
struct ff_callbacks *callbacks);
#ifdef __cplusplus
}

View file

@ -16,8 +16,7 @@
#include "ff-circular-queue.h"
static void *queue_fetch_or_alloc(struct ff_circular_queue *cq,
int index)
static void *queue_fetch_or_alloc(struct ff_circular_queue *cq, int index)
{
if (cq->slots[index] == NULL)
cq->slots[index] = av_mallocz(cq->item_size);
@ -46,7 +45,7 @@ static void queue_wait(struct ff_circular_queue *cq)
}
bool ff_circular_queue_init(struct ff_circular_queue *cq, int item_size,
int capacity)
int capacity)
{
memset(cq, 0, sizeof(struct ff_circular_queue));
@ -136,5 +135,3 @@ void ff_circular_queue_advance_read(struct ff_circular_queue *cq)
queue_signal(cq);
queue_unlock(cq);
}

View file

@ -43,7 +43,7 @@ struct ff_circular_queue {
typedef struct ff_circular_queue ff_circular_queue_t;
bool ff_circular_queue_init(struct ff_circular_queue *cq, int item_size,
int capacity);
int capacity);
void ff_circular_queue_abort(struct ff_circular_queue *cq);
void ff_circular_queue_free(struct ff_circular_queue *cq);

View file

@ -41,7 +41,7 @@ int64_t ff_clock_start_time(struct ff_clock *clock)
}
bool ff_clock_start(struct ff_clock *clock, enum ff_av_sync_type sync_type,
const bool *abort)
const bool *abort)
{
bool release = false;
bool aborted = false;
@ -57,14 +57,14 @@ bool ff_clock_start(struct ff_clock *clock, enum ff_av_sync_type sync_type,
} else {
while (!clock->started) {
pthread_mutex_lock(&clock->mutex);
int64_t current_time = av_gettime()
+ CLOCK_START_CHECK_INTERVAL;
int64_t current_time =
av_gettime() + CLOCK_START_CHECK_INTERVAL;
struct timespec sleep_time = {
.tv_sec = current_time / AV_TIME_BASE,
.tv_nsec = (current_time % AV_TIME_BASE) * 1000
};
.tv_sec = current_time / AV_TIME_BASE,
.tv_nsec =
(current_time % AV_TIME_BASE) * 1000};
pthread_cond_timedwait(&clock->cond, &clock->mutex,
&sleep_time);
&sleep_time);
aborted = *abort;
@ -75,10 +75,11 @@ bool ff_clock_start(struct ff_clock *clock, enum ff_av_sync_type sync_type,
pthread_mutex_unlock(&clock->mutex);
if (aborted || release) {
av_log(NULL, AV_LOG_ERROR, "could not start "
"slave clock as master clock "
"was never started before "
"being released or aborted");
av_log(NULL, AV_LOG_ERROR,
"could not start "
"slave clock as master clock "
"was never started before "
"being released or aborted");
break;
}
}

View file

@ -50,7 +50,7 @@ struct ff_clock {
typedef struct ff_clock ff_clock_t;
struct ff_clock * ff_clock_init(void);
struct ff_clock *ff_clock_init(void);
double ff_get_sync_clock(struct ff_clock *clock);
struct ff_clock *ff_clock_retain(struct ff_clock *clock);
struct ff_clock *ff_clock_move(struct ff_clock **clock);
@ -58,7 +58,7 @@ void ff_clock_release(struct ff_clock **clock);
int64_t ff_clock_start_time(struct ff_clock *clock);
bool ff_clock_start(struct ff_clock *clock, enum ff_av_sync_type sync_type,
const bool *abort);
const bool *abort);
#ifdef __cplusplus
}

View file

@ -25,8 +25,9 @@ extern void *ff_audio_decoder_thread(void *opaque_audio_decoder);
extern void *ff_video_decoder_thread(void *opaque_video_decoder);
struct ff_decoder *ff_decoder_init(AVCodecContext *codec_context,
AVStream *stream, unsigned int packet_queue_size,
unsigned int frame_queue_size)
AVStream *stream,
unsigned int packet_queue_size,
unsigned int frame_queue_size)
{
bool success;
@ -56,12 +57,13 @@ struct ff_decoder *ff_decoder_init(AVCodecContext *codec_context,
decoder->first_frame = true;
success = ff_timer_init(&decoder->refresh_timer, ff_decoder_refresh,
decoder);
decoder);
if (!success)
goto fail2;
success = ff_circular_queue_init(&decoder->frame_queue,
sizeof(struct ff_frame), frame_queue_size);
sizeof(struct ff_frame),
frame_queue_size);
if (!success)
goto fail3;
@ -88,14 +90,14 @@ bool ff_decoder_start(struct ff_decoder *decoder)
decoder_thread = ff_video_decoder_thread;
} else {
av_log(NULL, AV_LOG_ERROR, "no decoder found for type %d",
decoder->codec->codec_type);
decoder->codec->codec_type);
return false;
}
ff_decoder_schedule_refresh(decoder, 40);
return (pthread_create(&decoder->decoder_thread, NULL,
decoder_thread, decoder) != 0);
return (pthread_create(&decoder->decoder_thread, NULL, decoder_thread,
decoder) != 0);
}
void ff_decoder_free(struct ff_decoder *decoder)
@ -139,7 +141,7 @@ void ff_decoder_free(struct ff_decoder *decoder)
void ff_decoder_schedule_refresh(struct ff_decoder *decoder, int delay)
{
ff_timer_schedule(&decoder->refresh_timer, 1000*delay);
ff_timer_schedule(&decoder->refresh_timer, 1000 * delay);
}
double ff_decoder_clock(void *opaque)
@ -149,16 +151,16 @@ double ff_decoder_clock(void *opaque)
return decoder->current_pts + delta;
}
static double get_sync_adjusted_pts_diff(struct ff_clock *clock,
double pts, double pts_diff)
static double get_sync_adjusted_pts_diff(struct ff_clock *clock, double pts,
double pts_diff)
{
double new_pts_diff = pts_diff;
double sync_time = ff_get_sync_clock(clock);
double diff = pts - sync_time;
double sync_threshold;
sync_threshold = (pts_diff > AV_SYNC_THRESHOLD)
? pts_diff : AV_SYNC_THRESHOLD;
sync_threshold = (pts_diff > AV_SYNC_THRESHOLD) ? pts_diff
: AV_SYNC_THRESHOLD;
if (fabs(diff) < AV_NOSYNC_THRESHOLD) {
if (diff <= -sync_threshold) {
@ -183,7 +185,7 @@ void ff_decoder_refresh(void *opaque)
if (!decoder->eof || !decoder->finished) {
// We expected a frame, but there were none
// available
// Schedule another call as soon as possible
ff_decoder_schedule_refresh(decoder, 1);
} else {
@ -191,7 +193,7 @@ void ff_decoder_refresh(void *opaque)
decoder->refresh_timer.abort = true;
// no more refreshes, we are at the eof
av_log(NULL, AV_LOG_INFO,
"refresh timer stopping; eof");
"refresh timer stopping; eof");
return;
}
} else {
@ -200,12 +202,12 @@ void ff_decoder_refresh(void *opaque)
bool late_first_frame = false;
frame = ff_circular_queue_peek_read(
&decoder->frame_queue);
&decoder->frame_queue);
// Get frame clock and start it if needed
ff_clock_t *clock = ff_clock_move(&frame->clock);
if (!ff_clock_start(clock, decoder->natural_sync_clock,
&decoder->refresh_timer.abort)) {
&decoder->refresh_timer.abort)) {
ff_clock_release(&clock);
// Our clock was never started and deleted or
@ -213,7 +215,7 @@ void ff_decoder_refresh(void *opaque)
if (decoder->refresh_timer.abort) {
av_log(NULL, AV_LOG_INFO,
"refresh timer aborted");
"refresh timer aborted");
return;
}
@ -227,7 +229,7 @@ void ff_decoder_refresh(void *opaque)
// Drop this frame as we have no way of timing
// it
ff_circular_queue_advance_read(
&decoder->frame_queue);
&decoder->frame_queue);
return;
}
@ -256,17 +258,16 @@ void ff_decoder_refresh(void *opaque)
decoder->previous_pts = frame->pts;
// if not synced against natural clock
if (clock->sync_type
!= decoder->natural_sync_clock) {
pts_diff = get_sync_adjusted_pts_diff(clock,
frame->pts, pts_diff);
if (clock->sync_type != decoder->natural_sync_clock) {
pts_diff = get_sync_adjusted_pts_diff(
clock, frame->pts, pts_diff);
}
decoder->timer_next_wake += pts_diff;
// compute the amount of time until next refresh
delay_until_next_wake = decoder->timer_next_wake -
(av_gettime() / 1000000.0L);
(av_gettime() / 1000000.0L);
if (delay_until_next_wake < 0.010L) {
delay_until_next_wake = 0.010L;
}
@ -277,9 +278,9 @@ void ff_decoder_refresh(void *opaque)
ff_clock_release(&clock);
ff_callbacks_frame(decoder->callbacks, frame);
ff_decoder_schedule_refresh(decoder,
(int)(delay_until_next_wake * 1000
+ 0.5L));
ff_decoder_schedule_refresh(
decoder,
(int)(delay_until_next_wake * 1000 + 0.5L));
av_frame_free(&frame->frame);
@ -309,7 +310,7 @@ bool ff_decoder_accept(struct ff_decoder *decoder, struct ff_packet *packet)
}
double ff_decoder_get_best_effort_pts(struct ff_decoder *decoder,
AVFrame *frame)
AVFrame *frame)
{
// this is how long each frame is added to the amount of repeated frames
// according to the codec
@ -328,9 +329,10 @@ double ff_decoder_get_best_effort_pts(struct ff_decoder *decoder,
if (decoder->first_frame) {
best_effort_pts = decoder->start_pts;
} else {
av_log(NULL, AV_LOG_WARNING, "multiple pts < "
"start_pts; setting start pts "
"to 0");
av_log(NULL, AV_LOG_WARNING,
"multiple pts < "
"start_pts; setting start pts "
"to 0");
decoder->start_pts = 0;
}
}
@ -347,11 +349,11 @@ double ff_decoder_get_best_effort_pts(struct ff_decoder *decoder,
// Update our predicted pts to include the repeated picture count
// Our predicted pts clock is based on the codecs time base
estimated_frame_delay = av_frame_get_pkt_duration(frame)
* av_q2d(decoder->codec->time_base);
estimated_frame_delay = av_frame_get_pkt_duration(frame) *
av_q2d(decoder->codec->time_base);
// Add repeat frame delay
estimated_frame_delay += frame->repeat_pict
/ (1.0L / estimated_frame_delay);
estimated_frame_delay +=
frame->repeat_pict / (1.0L / estimated_frame_delay);
decoder->predicted_pts += estimated_frame_delay;
@ -359,13 +361,12 @@ double ff_decoder_get_best_effort_pts(struct ff_decoder *decoder,
}
bool ff_decoder_set_frame_drop_state(struct ff_decoder *decoder,
int64_t start_time, int64_t pts)
int64_t start_time, int64_t pts)
{
if (pts != AV_NOPTS_VALUE) {
int64_t rescaled_pts = av_rescale_q(pts,
decoder->stream->time_base, AV_TIME_BASE_Q);
int64_t master_clock = av_gettime() -
start_time;
int64_t rescaled_pts = av_rescale_q(
pts, decoder->stream->time_base, AV_TIME_BASE_Q);
int64_t master_clock = av_gettime() - start_time;
int64_t diff = master_clock - rescaled_pts;

View file

@ -41,11 +41,11 @@ struct ff_decoder {
unsigned int packet_queue_size;
double timer_next_wake;
double previous_pts; // previous decoded frame's pts
double previous_pts_diff; // previous decoded frame pts delay
double predicted_pts; // predicted pts of next frame
double current_pts; // pts of the most recently dispatched frame
int64_t current_pts_time; // clock time when current_pts was set
double previous_pts; // previous decoded frame's pts
double previous_pts_diff; // previous decoded frame pts delay
double predicted_pts; // predicted pts of next frame
double current_pts; // pts of the most recently dispatched frame
int64_t current_pts_time; // clock time when current_pts was set
int64_t start_pts;
bool hwaccel_decoder;
@ -62,8 +62,9 @@ struct ff_decoder {
typedef struct ff_decoder ff_decoder_t;
struct ff_decoder *ff_decoder_init(AVCodecContext *codec_context,
AVStream *stream, unsigned int packet_queue_size,
unsigned int frame_queue_size);
AVStream *stream,
unsigned int packet_queue_size,
unsigned int frame_queue_size);
bool ff_decoder_start(struct ff_decoder *decoder);
void ff_decoder_free(struct ff_decoder *decoder);
@ -76,10 +77,10 @@ void ff_decoder_schedule_refresh(struct ff_decoder *decoder, int delay);
void ff_decoder_refresh(void *opaque);
double ff_decoder_get_best_effort_pts(struct ff_decoder *decoder,
AVFrame *frame);
AVFrame *frame);
bool ff_decoder_set_frame_drop_state(struct ff_decoder *decoder,
int64_t start_time, int64_t pts);
int64_t start_time, int64_t pts);
#ifdef __cplusplus
}

View file

@ -43,7 +43,7 @@ struct ff_demuxer *ff_demuxer_init()
avdevice_register_all();
avfilter_register_all();
avformat_network_init();
demuxer = av_mallocz(sizeof(struct ff_demuxer));
if (demuxer == NULL)
return NULL;
@ -60,7 +60,7 @@ struct ff_demuxer *ff_demuxer_init()
}
bool ff_demuxer_open(struct ff_demuxer *demuxer, char *input,
char *input_format)
char *input_format)
{
int ret;
@ -69,7 +69,7 @@ bool ff_demuxer_open(struct ff_demuxer *demuxer, char *input,
demuxer->input_format = av_strdup(input_format);
ret = pthread_create(&demuxer->demuxer_thread, NULL, demux_thread,
demuxer);
demuxer);
return ret == 0;
}
@ -100,12 +100,11 @@ void ff_demuxer_free(struct ff_demuxer *demuxer)
}
void ff_demuxer_set_callbacks(struct ff_callbacks *callbacks,
ff_callback_frame frame,
ff_callback_format format,
ff_callback_initialize initialize,
ff_callback_frame frame_initialize,
ff_callback_frame frame_free,
void *opaque)
ff_callback_frame frame,
ff_callback_format format,
ff_callback_initialize initialize,
ff_callback_frame frame_initialize,
ff_callback_frame frame_free, void *opaque)
{
callbacks->opaque = opaque;
callbacks->frame = frame;
@ -165,19 +164,18 @@ AVHWAccel *find_hwaccel_codec(AVCodecContext *codec_context)
while ((hwaccel = av_hwaccel_next(hwaccel)) != NULL) {
if (hwaccel->id == codec_context->codec_id &&
(hwaccel->pix_fmt == AV_PIX_FMT_VDA_VLD ||
(hwaccel->pix_fmt == AV_PIX_FMT_VDA_VLD ||
hwaccel->pix_fmt == AV_PIX_FMT_DXVA2_VLD ||
hwaccel->pix_fmt == AV_PIX_FMT_VAAPI_VLD)) {
return hwaccel;
}
}
return NULL;
}
enum AVPixelFormat get_hwaccel_format(struct AVCodecContext *s,
const enum AVPixelFormat * fmt)
const enum AVPixelFormat *fmt)
{
(void)s;
(void)fmt;
@ -187,25 +185,25 @@ enum AVPixelFormat get_hwaccel_format(struct AVCodecContext *s,
}
static bool initialize_decoder(struct ff_demuxer *demuxer,
AVCodecContext *codec_context, AVStream *stream,
bool hwaccel_decoder)
AVCodecContext *codec_context, AVStream *stream,
bool hwaccel_decoder)
{
switch (codec_context->codec_type) {
case AVMEDIA_TYPE_AUDIO:
demuxer->audio_decoder = ff_decoder_init(
codec_context, stream,
demuxer->options.audio_packet_queue_size,
demuxer->options.audio_frame_queue_size);
codec_context, stream,
demuxer->options.audio_packet_queue_size,
demuxer->options.audio_frame_queue_size);
demuxer->audio_decoder->hwaccel_decoder = hwaccel_decoder;
demuxer->audio_decoder->frame_drop =
demuxer->options.frame_drop;
demuxer->options.frame_drop;
demuxer->audio_decoder->natural_sync_clock =
AV_SYNC_AUDIO_MASTER;
AV_SYNC_AUDIO_MASTER;
demuxer->audio_decoder->callbacks = &demuxer->audio_callbacks;
if (!ff_callbacks_format(&demuxer->audio_callbacks,
codec_context)) {
codec_context)) {
ff_decoder_free(demuxer->audio_decoder);
demuxer->audio_decoder = NULL;
return false;
@ -216,19 +214,19 @@ static bool initialize_decoder(struct ff_demuxer *demuxer,
case AVMEDIA_TYPE_VIDEO:
demuxer->video_decoder = ff_decoder_init(
codec_context, stream,
demuxer->options.video_packet_queue_size,
demuxer->options.video_frame_queue_size);
codec_context, stream,
demuxer->options.video_packet_queue_size,
demuxer->options.video_frame_queue_size);
demuxer->video_decoder->hwaccel_decoder = hwaccel_decoder;
demuxer->video_decoder->frame_drop =
demuxer->options.frame_drop;
demuxer->options.frame_drop;
demuxer->video_decoder->natural_sync_clock =
AV_SYNC_VIDEO_MASTER;
AV_SYNC_VIDEO_MASTER;
demuxer->video_decoder->callbacks = &demuxer->video_callbacks;
if (!ff_callbacks_format(&demuxer->video_callbacks,
codec_context)) {
codec_context)) {
ff_decoder_free(demuxer->video_decoder);
demuxer->video_decoder = NULL;
return false;
@ -240,8 +238,8 @@ static bool initialize_decoder(struct ff_demuxer *demuxer,
}
}
typedef enum AVPixelFormat (*AVGetFormatCb)(
struct AVCodecContext *s, const enum AVPixelFormat * fmt);
typedef enum AVPixelFormat (*AVGetFormatCb)(struct AVCodecContext *s,
const enum AVPixelFormat *fmt);
static bool find_decoder(struct ff_demuxer *demuxer, AVStream *stream)
{
@ -258,10 +256,10 @@ static bool find_decoder(struct ff_demuxer *demuxer, AVStream *stream)
codec_context->refcounted_frames = 1;
// png/tiff decoders have serious issues with multiple threads
if (codec_context->codec_id == AV_CODEC_ID_PNG
|| codec_context->codec_id == AV_CODEC_ID_TIFF
|| codec_context->codec_id == AV_CODEC_ID_JPEG2000
|| codec_context->codec_id == AV_CODEC_ID_WEBP)
if (codec_context->codec_id == AV_CODEC_ID_PNG ||
codec_context->codec_id == AV_CODEC_ID_TIFF ||
codec_context->codec_id == AV_CODEC_ID_JPEG2000 ||
codec_context->codec_id == AV_CODEC_ID_WEBP)
codec_context->thread_count = 1;
if (demuxer->options.is_hw_decoding) {
@ -269,24 +267,24 @@ static bool find_decoder(struct ff_demuxer *demuxer, AVStream *stream)
if (hwaccel) {
AVCodec *codec_vda =
avcodec_find_decoder_by_name(hwaccel->name);
avcodec_find_decoder_by_name(hwaccel->name);
if (codec_vda != NULL) {
AVGetFormatCb original_get_format =
codec_context->get_format;
codec_context->get_format;
codec_context->get_format = get_hwaccel_format;
codec_context->opaque = hwaccel;
ret = avcodec_open2(codec_context, codec_vda,
&options_dict);
&options_dict);
if (ret < 0) {
av_log(NULL, AV_LOG_WARNING,
"no hardware decoder found for"
" codec with id %d",
codec_context->codec_id);
"no hardware decoder found for"
" codec with id %d",
codec_context->codec_id);
codec_context->get_format =
original_get_format;
original_get_format;
codec_context->opaque = NULL;
} else {
codec = codec_vda;
@ -305,21 +303,23 @@ static bool find_decoder(struct ff_demuxer *demuxer, AVStream *stream)
if (!codec)
codec = avcodec_find_decoder(codec_context->codec_id);
if (codec == NULL) {
av_log(NULL, AV_LOG_WARNING, "no decoder found for"
" codec with id %d",
codec_context->codec_id);
av_log(NULL, AV_LOG_WARNING,
"no decoder found for"
" codec with id %d",
codec_context->codec_id);
return false;
}
if (avcodec_open2(codec_context, codec, &options_dict) < 0) {
av_log(NULL, AV_LOG_WARNING, "unable to open decoder"
" with codec id %d",
codec_context->codec_id);
av_log(NULL, AV_LOG_WARNING,
"unable to open decoder"
" with codec id %d",
codec_context->codec_id);
return false;
}
}
return initialize_decoder(demuxer, codec_context, stream,
hwaccel_decoder);
hwaccel_decoder);
}
void ff_demuxer_flush(struct ff_demuxer *demuxer)
@ -328,14 +328,14 @@ void ff_demuxer_flush(struct ff_demuxer *demuxer)
demuxer->video_decoder->stream != NULL) {
packet_queue_flush(&demuxer->video_decoder->packet_queue);
packet_queue_put_flush_packet(
&demuxer->video_decoder->packet_queue);
&demuxer->video_decoder->packet_queue);
}
if (demuxer->audio_decoder != NULL &&
demuxer->audio_decoder->stream != NULL) {
packet_queue_flush(&demuxer->audio_decoder->packet_queue);
packet_queue_put_flush_packet(
&demuxer->audio_decoder->packet_queue);
&demuxer->audio_decoder->packet_queue);
}
}
@ -352,18 +352,18 @@ void ff_demuxer_reset(struct ff_demuxer *demuxer)
if (demuxer->audio_decoder != NULL) {
ff_clock_retain(clock);
packet_queue_put(&demuxer->audio_decoder->packet_queue,
&packet);
&packet);
}
if (demuxer->video_decoder != NULL) {
ff_clock_retain(clock);
packet_queue_put(&demuxer->video_decoder->packet_queue,
&packet);
&packet);
}
}
static bool open_input(struct ff_demuxer *demuxer,
AVFormatContext **format_context)
AVFormatContext **format_context)
{
AVInputFormat *input_format = NULL;
@ -377,24 +377,25 @@ static bool open_input(struct ff_demuxer *demuxer,
if (demuxer->input_format != NULL) {
input_format = av_find_input_format(demuxer->input_format);
if (input_format == NULL)
av_log(NULL, AV_LOG_WARNING, "unable to find input "
"format %s",
demuxer->input_format);
av_log(NULL, AV_LOG_WARNING,
"unable to find input "
"format %s",
demuxer->input_format);
}
if (avformat_open_input(format_context, demuxer->input,
input_format, &demuxer->options.custom_options) != 0)
if (avformat_open_input(format_context, demuxer->input, input_format,
&demuxer->options.custom_options) != 0)
return false;
return avformat_find_stream_info(*format_context, NULL) >= 0;
}
static inline void set_decoder_start_time(struct ff_decoder *decoder,
int64_t start_time)
int64_t start_time)
{
if (decoder)
decoder->start_pts = av_rescale_q(start_time, AV_TIME_BASE_Q,
decoder->stream->time_base);
decoder->stream->time_base);
}
static bool find_and_initialize_stream_decoders(struct ff_demuxer *demuxer)
@ -415,12 +416,12 @@ static bool find_and_initialize_stream_decoders(struct ff_demuxer *demuxer)
audio_stream = format_context->streams[i];
}
int default_stream_index = av_find_default_stream_index(
demuxer->format_context);
int default_stream_index =
av_find_default_stream_index(demuxer->format_context);
if (default_stream_index >= 0) {
AVStream *stream =
format_context->streams[default_stream_index];
format_context->streams[default_stream_index];
if (stream->codec->codec_type == AVMEDIA_TYPE_AUDIO)
demuxer->clock.sync_type = AV_SYNC_AUDIO_MASTER;
@ -452,7 +453,7 @@ static bool find_and_initialize_stream_decoders(struct ff_demuxer *demuxer)
}
st_start_time = av_rescale_q(st->start_time, st->time_base,
AV_TIME_BASE_Q);
AV_TIME_BASE_Q);
start_time = FFMIN(start_time, st_start_time);
}
@ -508,18 +509,17 @@ static bool handle_seek(struct ff_demuxer *demuxer)
seek_stream = demuxer->audio_decoder->stream;
}
if (seek_stream != NULL && demuxer->format_context->duration != AV_NOPTS_VALUE) {
seek_target = av_rescale_q(seek_target,
AV_TIME_BASE_Q,
seek_stream->time_base);
if (seek_stream != NULL &&
demuxer->format_context->duration != AV_NOPTS_VALUE) {
seek_target = av_rescale_q(seek_target, AV_TIME_BASE_Q,
seek_stream->time_base);
}
ret = av_seek_frame(demuxer->format_context,
0, seek_target,
demuxer->seek_flags);
ret = av_seek_frame(demuxer->format_context, 0, seek_target,
demuxer->seek_flags);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "unable to seek stream: %s",
av_err2str(ret));
av_err2str(ret));
demuxer->seek_pos = 0;
demuxer->seek_request = false;
return false;
@ -551,7 +551,7 @@ static void seek_beginning(struct ff_demuxer *demuxer)
static void *demux_thread(void *opaque)
{
struct ff_demuxer *demuxer = (struct ff_demuxer *) opaque;
struct ff_demuxer *demuxer = (struct ff_demuxer *)opaque;
int result;
struct ff_packet packet = {0};
@ -584,7 +584,7 @@ static void *demux_thread(void *opaque)
eof = true;
} else if (demuxer->format_context->pb != NULL) {
AVIOContext *io_context =
demuxer->format_context->pb;
demuxer->format_context->pb;
if (io_context->error == 0) {
av_usleep(100 * 1000); // 100ms
continue;
@ -603,8 +603,8 @@ static void *demux_thread(void *opaque)
continue;
} else {
av_log(NULL, AV_LOG_ERROR,
"av_read_frame() failed: %s",
av_err2str(result));
"av_read_frame() failed: %s",
av_err2str(result));
break;
}
}

View file

@ -31,8 +31,7 @@
extern "C" {
#endif
struct ff_demuxer_options
{
struct ff_demuxer_options {
int audio_packet_queue_size;
int video_packet_queue_size;
int audio_frame_queue_size;
@ -75,16 +74,16 @@ struct ff_demuxer {
typedef struct ff_demuxer ff_demuxer_t;
struct ff_demuxer *ff_demuxer_init();
bool ff_demuxer_open(struct ff_demuxer *demuxer, char *input, char *input_format);
bool ff_demuxer_open(struct ff_demuxer *demuxer, char *input,
char *input_format);
void ff_demuxer_free(struct ff_demuxer *demuxer);
void ff_demuxer_set_callbacks(struct ff_callbacks *callbacks,
ff_callback_frame frame,
ff_callback_format format,
ff_callback_initialize initialize,
ff_callback_frame frame_initialize,
ff_callback_frame frame_free,
void *opaque);
ff_callback_frame frame,
ff_callback_format format,
ff_callback_initialize initialize,
ff_callback_frame frame_initialize,
ff_callback_frame frame_free, void *opaque);
void ff_demuxer_flush(struct ff_demuxer *demuxer);

View file

@ -36,7 +36,6 @@ fail1:
pthread_mutex_destroy(&q->mutex);
fail:
return false;
}
void packet_queue_abort(struct ff_packet_queue *q)
@ -93,7 +92,7 @@ int packet_queue_put_flush_packet(struct ff_packet_queue *q)
}
int packet_queue_get(struct ff_packet_queue *q, struct ff_packet *packet,
bool block)
bool block)
{
struct ff_packet_list *potential_packet;
int return_status;
@ -141,7 +140,7 @@ void packet_queue_flush(struct ff_packet_queue *q)
pthread_mutex_lock(&q->mutex);
for (packet = q->first_packet; packet != NULL;
packet = q->first_packet) {
packet = q->first_packet) {
q->first_packet = packet->next;
av_free_packet(&packet->packet.base);
if (packet->packet.clock != NULL)

View file

@ -36,8 +36,8 @@ struct ff_packet {
};
struct ff_packet_list {
struct ff_packet packet;
struct ff_packet_list *next;
struct ff_packet packet;
struct ff_packet_list *next;
};
struct ff_packet_queue {
@ -59,7 +59,7 @@ void packet_queue_free(struct ff_packet_queue *q);
int packet_queue_put(struct ff_packet_queue *q, struct ff_packet *packet);
int packet_queue_put_flush_packet(struct ff_packet_queue *q);
int packet_queue_get(struct ff_packet_queue *q, struct ff_packet *packet,
bool block);
bool block);
void packet_queue_flush(struct ff_packet_queue *q);

View file

@ -38,17 +38,16 @@ static void *timer_thread(void *opaque)
uint64_t current_time = av_gettime();
if (current_time < timer->next_wake) {
struct timespec sleep_time = {
.tv_sec = timer->next_wake / AV_TIME_BASE,
.tv_nsec = (timer->next_wake % AV_TIME_BASE)
* 1000
};
.tv_sec = timer->next_wake / AV_TIME_BASE,
.tv_nsec = (timer->next_wake % AV_TIME_BASE) *
1000};
ret = pthread_cond_timedwait(&timer->cond,
&timer->mutex, &sleep_time);
ret = pthread_cond_timedwait(
&timer->cond, &timer->mutex, &sleep_time);
if (ret != ETIMEDOUT) {
// failed to wait, just sleep
av_usleep((unsigned)(timer->next_wake
- current_time));
av_usleep((unsigned)(timer->next_wake -
current_time));
}
pthread_mutex_unlock(&timer->mutex);
@ -78,7 +77,7 @@ static void *timer_thread(void *opaque)
}
bool ff_timer_init(struct ff_timer *timer, ff_timer_callback callback,
void *opaque)
void *opaque)
{
memset(timer, 0, sizeof(struct ff_timer));
timer->abort = false;
@ -88,14 +87,15 @@ bool ff_timer_init(struct ff_timer *timer, ff_timer_callback callback,
if (pthread_mutexattr_init(&timer->mutexattr) != 0)
goto fail;
if (pthread_mutexattr_settype(&timer->mutexattr,
PTHREAD_MUTEX_RECURSIVE))
PTHREAD_MUTEX_RECURSIVE))
goto fail1;
if (pthread_mutex_init(&timer->mutex, &timer->mutexattr) != 0)
goto fail1;
if (pthread_cond_init(&timer->cond, NULL) != 0)
goto fail2;
if (pthread_create(&timer->timer_thread, NULL, timer_thread, timer) != 0)
if (pthread_create(&timer->timer_thread, NULL, timer_thread, timer) !=
0)
goto fail3;
return true;

View file

@ -43,8 +43,8 @@ struct ff_timer {
typedef struct ff_timer ff_timer_t;
bool ff_timer_init(struct ff_timer *timer,
ff_timer_callback callback, void *opaque);
bool ff_timer_init(struct ff_timer *timer, ff_timer_callback callback,
void *opaque);
void ff_timer_free(struct ff_timer *timer);
void ff_timer_schedule(struct ff_timer *timer, uint64_t microseconds);

View file

@ -40,7 +40,7 @@ struct ff_format_desc {
const char *extensions;
enum AVCodecID audio_codec;
enum AVCodecID video_codec;
const struct AVCodecTag * const *codec_tags;
const struct AVCodecTag *const *codec_tags;
const struct ff_format_desc *next;
};
@ -56,9 +56,11 @@ struct ff_codec_desc {
void ff_init()
{
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 9, 100)
av_register_all();
//avdevice_register_all();
avcodec_register_all();
#endif
avformat_network_init();
}
@ -71,7 +73,7 @@ const char *ff_codec_name_from_id(int codec_id)
return NULL;
}
static bool get_codecs(const AVCodecDescriptor*** descs, unsigned int *size)
static bool get_codecs(const AVCodecDescriptor ***descs, unsigned int *size)
{
const AVCodecDescriptor *desc = NULL;
const AVCodecDescriptor **codecs;
@ -84,8 +86,10 @@ static bool get_codecs(const AVCodecDescriptor*** descs, unsigned int *size)
codecs = av_calloc(codec_count, sizeof(AVCodecDescriptor *));
if (codecs == NULL) {
av_log(NULL, AV_LOG_ERROR, "unable to allocate sorted codec "
"array with size %d", codec_count);
av_log(NULL, AV_LOG_ERROR,
"unable to allocate sorted codec "
"array with size %d",
codec_count);
return false;
}
@ -99,18 +103,37 @@ static bool get_codecs(const AVCodecDescriptor*** descs, unsigned int *size)
static const AVCodec *next_codec_for_id(enum AVCodecID id, const AVCodec *prev)
{
while ((prev = av_codec_next(prev)) != NULL) {
if (prev->id == id && av_codec_is_encoder(prev))
return prev;
}
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(58, 9, 100)
const AVCodec *cur = NULL;
void *i = 0;
bool found_prev = false;
return NULL;
while ((cur = av_codec_iterate(&i)) != NULL) {
if (cur->id == id && av_codec_is_encoder(cur)) {
if (!prev) {
return cur;
} else if (!found_prev) {
if (cur == prev) {
found_prev = true;
}
} else {
return cur;
}
}
}
#else
while ((prev = av_codec_next(prev)) != NULL) {
if (prev->id == id && av_codec_is_encoder(prev))
return prev;
}
#endif
return NULL;
}
static void add_codec_to_list(const struct ff_format_desc *format_desc,
struct ff_codec_desc **first, struct ff_codec_desc **current,
enum AVCodecID id, const AVCodec *codec,
bool ignore_compatability)
struct ff_codec_desc **first,
struct ff_codec_desc **current, enum AVCodecID id,
const AVCodec *codec, bool ignore_compatability)
{
if (codec == NULL)
codec = avcodec_find_encoder(id);
@ -125,8 +148,8 @@ static void add_codec_to_list(const struct ff_format_desc *format_desc,
if (!ignore_compatability) {
// Format doesn't support this codec
unsigned int tag = av_codec_get_tag(format_desc->codec_tags,
codec->id);
unsigned int tag =
av_codec_get_tag(format_desc->codec_tags, codec->id);
if (tag == 0)
return;
}
@ -162,18 +185,19 @@ static void add_codec_to_list(const struct ff_format_desc *format_desc,
}
static void get_codecs_for_id(const struct ff_format_desc *format_desc,
struct ff_codec_desc **first, struct ff_codec_desc **current,
enum AVCodecID id, bool ignore_compatability)
struct ff_codec_desc **first,
struct ff_codec_desc **current, enum AVCodecID id,
bool ignore_compatability)
{
const AVCodec *codec = NULL;
while ((codec = next_codec_for_id(id, codec)) != NULL)
add_codec_to_list(format_desc, first, current, codec->id,
codec, ignore_compatability);
add_codec_to_list(format_desc, first, current, codec->id, codec,
ignore_compatability);
}
const struct ff_codec_desc *ff_codec_supported(
const struct ff_format_desc *format_desc,
bool ignore_compatability)
const struct ff_codec_desc *
ff_codec_supported(const struct ff_format_desc *format_desc,
bool ignore_compatability)
{
const AVCodecDescriptor **codecs;
unsigned int size;
@ -184,10 +208,10 @@ const struct ff_codec_desc *ff_codec_supported(
if (!get_codecs(&codecs, &size))
return NULL;
for(i = 0; i < size; i++) {
for (i = 0; i < size; i++) {
const AVCodecDescriptor *codec = codecs[i];
get_codecs_for_id(format_desc, &first, &current, codec->id,
ignore_compatability);
ignore_compatability);
}
av_free((void *)codecs);
@ -235,8 +259,8 @@ enum ff_codec_type ff_codec_desc_type(const struct ff_codec_desc *codec_desc)
return FF_CODEC_UNKNOWN;
}
const struct ff_codec_desc *ff_codec_desc_next(
const struct ff_codec_desc *codec_desc)
const struct ff_codec_desc *
ff_codec_desc_next(const struct ff_codec_desc *codec_desc)
{
if (codec_desc != NULL)
return codec_desc->next;
@ -255,7 +279,7 @@ int ff_codec_desc_id(const struct ff_codec_desc *codec_desc)
void ff_codec_desc_free(const struct ff_codec_desc *codec_desc)
{
const struct ff_codec_desc *desc = codec_desc;
while(desc != NULL) {
while (desc != NULL) {
const struct ff_codec_desc *next = desc->next;
av_free((void *)desc);
desc = next;
@ -283,11 +307,17 @@ static inline bool is_output_device(const AVClass *avclass)
const struct ff_format_desc *ff_format_supported()
{
AVOutputFormat *output_format = NULL;
const AVOutputFormat *output_format = NULL;
struct ff_format_desc *desc = NULL;
struct ff_format_desc *current = NULL;
#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(58, 9, 100)
void *i = 0;
while ((output_format = av_muxer_iterate(&i)) != NULL) {
#else
while ((output_format = av_oformat_next(output_format)) != NULL) {
#endif
struct ff_format_desc *d;
if (is_output_device(output_format->priv_class))
continue;
@ -377,8 +407,8 @@ int ff_format_desc_video(const struct ff_format_desc *format_desc)
return false;
}
const struct ff_format_desc *ff_format_desc_next(
const struct ff_format_desc *format_desc)
const struct ff_format_desc *
ff_format_desc_next(const struct ff_format_desc *format_desc)
{
if (format_desc != NULL)
return format_desc->next;
@ -387,7 +417,7 @@ const struct ff_format_desc *ff_format_desc_next(
}
static const char *get_encoder_name(const struct ff_format_desc *format_desc,
enum AVCodecID codec_id)
enum AVCodecID codec_id)
{
AVCodec *codec = avcodec_find_encoder(codec_id);
if (codec == NULL && codec_id == AV_CODEC_ID_NONE)
@ -398,27 +428,24 @@ static const char *get_encoder_name(const struct ff_format_desc *format_desc,
return codec->name;
}
const char *ff_format_desc_get_default_name(
const struct ff_format_desc *format_desc,
enum ff_codec_type codec_type)
const char *
ff_format_desc_get_default_name(const struct ff_format_desc *format_desc,
enum ff_codec_type codec_type)
{
switch (codec_type)
{
case FF_CODEC_AUDIO:
return get_encoder_name(format_desc,
format_desc->audio_codec);
case FF_CODEC_VIDEO:
return get_encoder_name(format_desc,
format_desc->video_codec);
default:
return NULL;
switch (codec_type) {
case FF_CODEC_AUDIO:
return get_encoder_name(format_desc, format_desc->audio_codec);
case FF_CODEC_VIDEO:
return get_encoder_name(format_desc, format_desc->video_codec);
default:
return NULL;
}
}
void ff_format_desc_free(const struct ff_format_desc *format_desc)
{
const struct ff_format_desc *desc = format_desc;
while(desc != NULL) {
while (desc != NULL) {
const struct ff_format_desc *next = desc->next;
av_free((void *)desc);
desc = next;

View file

@ -22,11 +22,7 @@
extern "C" {
#endif
enum ff_codec_type {
FF_CODEC_AUDIO,
FF_CODEC_VIDEO,
FF_CODEC_UNKNOWN
};
enum ff_codec_type { FF_CODEC_AUDIO, FF_CODEC_VIDEO, FF_CODEC_UNKNOWN };
struct ff_format_desc;
struct ff_codec_desc;
@ -36,9 +32,9 @@ void ff_init();
const char *ff_codec_name_from_id(int codec_id);
// Codec Description
const struct ff_codec_desc *ff_codec_supported(
const struct ff_format_desc *format_desc,
bool ignore_compatability);
const struct ff_codec_desc *
ff_codec_supported(const struct ff_format_desc *format_desc,
bool ignore_compatability);
void ff_codec_desc_free(const struct ff_codec_desc *codec_desc);
const char *ff_codec_desc_name(const struct ff_codec_desc *codec_desc);
const char *ff_codec_desc_long_name(const struct ff_codec_desc *codec_desc);
@ -46,8 +42,8 @@ enum ff_codec_type ff_codec_desc_type(const struct ff_codec_desc *codec_desc);
bool ff_codec_desc_is_alias(const struct ff_codec_desc *codec_desc);
const char *ff_codec_desc_base_name(const struct ff_codec_desc *codec_desc);
int ff_codec_desc_id(const struct ff_codec_desc *codec_desc);
const struct ff_codec_desc *ff_codec_desc_next(
const struct ff_codec_desc *codec_desc);
const struct ff_codec_desc *
ff_codec_desc_next(const struct ff_codec_desc *codec_desc);
// Format Description
const struct ff_format_desc *ff_format_supported();
@ -60,11 +56,11 @@ bool ff_format_desc_has_audio(const struct ff_format_desc *format_desc);
bool ff_format_desc_has_video(const struct ff_format_desc *format_desc);
int ff_format_desc_audio(const struct ff_format_desc *format_desc);
int ff_format_desc_video(const struct ff_format_desc *format_desc);
const char *ff_format_desc_get_default_name(
const struct ff_format_desc *format_desc,
enum ff_codec_type codec_type);
const struct ff_format_desc *ff_format_desc_next(
const struct ff_format_desc *format_desc);
const char *
ff_format_desc_get_default_name(const struct ff_format_desc *format_desc,
enum ff_codec_type codec_type);
const struct ff_format_desc *
ff_format_desc_next(const struct ff_format_desc *format_desc);
#ifdef __cplusplus
}

View file

@ -30,7 +30,7 @@
#include "ff-compat.h"
static bool queue_frame(struct ff_decoder *decoder, AVFrame *frame,
double best_effort_pts)
double best_effort_pts)
{
struct ff_frame *queue_frame;
bool call_initialize;
@ -46,10 +46,10 @@ static bool queue_frame(struct ff_decoder *decoder, AVFrame *frame,
// Check if we need to communicate a different format has been received
// to any callbacks
AVCodecContext *codec = decoder->codec;
call_initialize = (queue_frame->frame == NULL
|| queue_frame->frame->width != codec->width
|| queue_frame->frame->height != codec->height
|| queue_frame->frame->format != codec->pix_fmt);
call_initialize = (queue_frame->frame == NULL ||
queue_frame->frame->width != codec->width ||
queue_frame->frame->height != codec->height ||
queue_frame->frame->format != codec->pix_fmt);
if (queue_frame->frame != NULL) {
// This shouldn't happen any more, the frames are freed in
@ -72,7 +72,7 @@ static bool queue_frame(struct ff_decoder *decoder, AVFrame *frame,
void *ff_video_decoder_thread(void *opaque_video_decoder)
{
struct ff_decoder *decoder = (struct ff_decoder*)opaque_video_decoder;
struct ff_decoder *decoder = (struct ff_decoder *)opaque_video_decoder;
struct ff_packet packet = {0};
int complete;
@ -82,16 +82,19 @@ void *ff_video_decoder_thread(void *opaque_video_decoder)
while (!decoder->abort) {
if (decoder->eof)
ret = packet_queue_get(&decoder->packet_queue, &packet, 0);
ret = packet_queue_get(&decoder->packet_queue, &packet,
0);
else
ret = packet_queue_get(&decoder->packet_queue, &packet, 1);
ret = packet_queue_get(&decoder->packet_queue, &packet,
1);
if (ret == FF_PACKET_EMPTY || ret == FF_PACKET_FAIL) {
// should we just use abort here?
break;
}
if (packet.base.data == decoder->packet_queue.flush_packet.base.data) {
if (packet.base.data ==
decoder->packet_queue.flush_packet.base.data) {
avcodec_flush_buffers(decoder->codec);
continue;
}
@ -116,11 +119,11 @@ void *ff_video_decoder_thread(void *opaque_video_decoder)
frame_drop_check &= start_time != AV_NOPTS_VALUE;
if (frame_drop_check)
ff_decoder_set_frame_drop_state(decoder,
start_time, packet.base.pts);
ff_decoder_set_frame_drop_state(decoder, start_time,
packet.base.pts);
avcodec_decode_video2(decoder->codec, frame,
&complete, &packet.base);
avcodec_decode_video2(decoder->codec, frame, &complete,
&packet.base);
// Did we get an entire video frame? This doesn't guarantee
// there is a picture to show for some codecs, but we still want
@ -131,7 +134,7 @@ void *ff_video_decoder_thread(void *opaque_video_decoder)
// This function returns a pts scaled to stream
// time base
double best_effort_pts =
ff_decoder_get_best_effort_pts(decoder, frame);
ff_decoder_get_best_effort_pts(decoder, frame);
queue_frame(decoder, frame, best_effort_pts);
av_frame_unref(frame);