Fplay: code cleanup
git-svn-id: svn://kolibrios.org@6136 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
798707fd38
commit
f71187e224
@ -16,26 +16,17 @@
|
|||||||
#include "sound.h"
|
#include "sound.h"
|
||||||
#include "fplay.h"
|
#include "fplay.h"
|
||||||
|
|
||||||
#ifdef HAVE_VAAPI
|
|
||||||
int va_check_codec_support(enum AVCodecID id);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
volatile enum player_state player_state = STOP;
|
volatile enum player_state player_state = STOP;
|
||||||
volatile enum player_state decoder_state = PREPARE;
|
volatile enum player_state decoder_state = PREPARE;
|
||||||
volatile enum player_state sound_state = STOP;
|
volatile enum player_state sound_state = STOP;
|
||||||
|
|
||||||
uint32_t win_width, win_height;
|
uint32_t win_width, win_height;
|
||||||
|
|
||||||
int have_sound = 0;
|
int have_sound = 0;
|
||||||
|
|
||||||
uint8_t *decoder_buffer;
|
uint8_t *decoder_buffer;
|
||||||
extern int resampler_size;
|
extern int resampler_size;
|
||||||
|
|
||||||
extern int sample_rate;
|
extern int sample_rate;
|
||||||
char *movie_file;
|
|
||||||
|
|
||||||
void flush_video(vst_t* vst);
|
|
||||||
|
|
||||||
|
|
||||||
int64_t rewind_pos;
|
int64_t rewind_pos;
|
||||||
|
|
||||||
@ -46,12 +37,6 @@ int threads_running = DECODER_THREAD;
|
|||||||
extern double audio_base;
|
extern double audio_base;
|
||||||
|
|
||||||
|
|
||||||
double get_audio_base(vst_t* vst)
|
|
||||||
{
|
|
||||||
return (double)av_q2d(vst->fCtx->streams[vst->aStream]->time_base)*1000;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
int main( int argc, char *argv[])
|
int main( int argc, char *argv[])
|
||||||
{
|
{
|
||||||
static vst_t vst;
|
static vst_t vst;
|
||||||
@ -60,14 +45,14 @@ int main( int argc, char *argv[])
|
|||||||
|
|
||||||
if(argc < 2)
|
if(argc < 2)
|
||||||
{
|
{
|
||||||
movie_file = get_moviefile();
|
vst.input_file = get_moviefile();
|
||||||
if(movie_file == NULL)
|
if(vst.input_file == NULL)
|
||||||
{
|
{
|
||||||
printf("Please provide a movie file\n");
|
printf("Please provide a movie file\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else movie_file = argv[1];
|
else vst.input_file = argv[1];
|
||||||
|
|
||||||
/* register all codecs, demux and protocols */
|
/* register all codecs, demux and protocols */
|
||||||
|
|
||||||
@ -77,9 +62,9 @@ int main( int argc, char *argv[])
|
|||||||
avdevice_register_all();
|
avdevice_register_all();
|
||||||
av_register_all();
|
av_register_all();
|
||||||
|
|
||||||
if( avformat_open_input(&vst.fCtx, movie_file, NULL, NULL) < 0)
|
if( avformat_open_input(&vst.fCtx, vst.input_file, NULL, NULL) < 0)
|
||||||
{
|
{
|
||||||
printf("Cannot open file %s\n\r", movie_file);
|
printf("Cannot open file %s\n\r", vst.input_file);
|
||||||
return -1; // Couldn't open file
|
return -1; // Couldn't open file
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -92,15 +77,15 @@ int main( int argc, char *argv[])
|
|||||||
return -1;
|
return -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
file_name = strrchr(movie_file,'/')+1;
|
file_name = strrchr(vst.input_file,'/')+1;
|
||||||
dot = strrchr(file_name,'.');
|
dot = strrchr(file_name,'.');
|
||||||
if(dot)
|
if(dot)
|
||||||
{
|
{
|
||||||
movie_file = malloc(dot-file_name+1);
|
vst.input_name = malloc(dot-file_name+1);
|
||||||
memcpy(movie_file, file_name, dot-file_name);
|
memcpy(vst.input_name, file_name, dot-file_name);
|
||||||
movie_file[dot-file_name] = 0;
|
vst.input_name[dot-file_name] = 0;
|
||||||
}
|
}
|
||||||
else movie_file = file_name;
|
else vst.input_name = file_name;
|
||||||
|
|
||||||
stream_duration = vst.fCtx->duration;
|
stream_duration = vst.fCtx->duration;
|
||||||
|
|
||||||
@ -114,7 +99,7 @@ int main( int argc, char *argv[])
|
|||||||
&& vst.vStream < 0)
|
&& vst.vStream < 0)
|
||||||
{
|
{
|
||||||
vst.vStream = i;
|
vst.vStream = i;
|
||||||
video_time_base = vst.fCtx->streams[i]->time_base;
|
vst.video_time_base = vst.fCtx->streams[i]->time_base;
|
||||||
if(stream_duration == 0)
|
if(stream_duration == 0)
|
||||||
stream_duration = vst.fCtx->streams[i]->duration;
|
stream_duration = vst.fCtx->streams[i]->duration;
|
||||||
}
|
}
|
||||||
@ -123,6 +108,7 @@ int main( int argc, char *argv[])
|
|||||||
vst.aStream < 0)
|
vst.aStream < 0)
|
||||||
{
|
{
|
||||||
vst.aStream = i;
|
vst.aStream = i;
|
||||||
|
vst.audio_time_base = vst.fCtx->streams[i]->time_base;
|
||||||
if(stream_duration == 0)
|
if(stream_duration == 0)
|
||||||
stream_duration = vst.fCtx->streams[i]->duration;
|
stream_duration = vst.fCtx->streams[i]->duration;
|
||||||
}
|
}
|
||||||
@ -141,8 +127,6 @@ int main( int argc, char *argv[])
|
|||||||
vst.aCtx = vst.fCtx->streams[vst.aStream]->codec;
|
vst.aCtx = vst.fCtx->streams[vst.aStream]->codec;
|
||||||
|
|
||||||
vst.vCodec = avcodec_find_decoder(vst.vCtx->codec_id);
|
vst.vCodec = avcodec_find_decoder(vst.vCtx->codec_id);
|
||||||
printf("codec id %x name %s\n",vst.vCtx->codec_id, vst.vCodec->name);
|
|
||||||
printf("ctx->pix_fmt %d\n", vst.vCtx->pix_fmt);
|
|
||||||
|
|
||||||
INIT_LIST_HEAD(&vst.input_list);
|
INIT_LIST_HEAD(&vst.input_list);
|
||||||
INIT_LIST_HEAD(&vst.output_list);
|
INIT_LIST_HEAD(&vst.output_list);
|
||||||
@ -157,9 +141,16 @@ int main( int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
printf("Unsupported codec with id %d for input stream %d\n",
|
printf("Unsupported codec with id %d for input stream %d\n",
|
||||||
vst.vCtx->codec_id, vst.vStream);
|
vst.vCtx->codec_id, vst.vStream);
|
||||||
return -1; // Codec not found
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vst.Frame = av_frame_alloc();
|
||||||
|
if(vst.Frame == NULL)
|
||||||
|
{
|
||||||
|
printf("Cannot alloc video frame\n");
|
||||||
|
return -1;
|
||||||
|
};
|
||||||
|
|
||||||
if(fplay_init_context(&vst))
|
if(fplay_init_context(&vst))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
@ -170,8 +161,6 @@ int main( int argc, char *argv[])
|
|||||||
return -1; // Could not open codec
|
return -1; // Could not open codec
|
||||||
};
|
};
|
||||||
|
|
||||||
printf("ctx->pix_fmt %d\n", vst.vCtx->pix_fmt);
|
|
||||||
|
|
||||||
if (vst.aCtx->channels > 0)
|
if (vst.aCtx->channels > 0)
|
||||||
vst.aCtx->request_channels = FFMIN(2, vst.aCtx->channels);
|
vst.aCtx->request_channels = FFMIN(2, vst.aCtx->channels);
|
||||||
else
|
else
|
||||||
@ -223,10 +212,10 @@ int main( int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
else printf("Unsupported audio codec!\n");
|
else printf("Unsupported audio codec!\n");
|
||||||
|
|
||||||
if(!init_video(&vst))
|
mutex_lock(&vst.decoder_lock);
|
||||||
return 0;
|
create_thread(video_thread, &vst, 1024*1024);
|
||||||
|
if(mutex_lock_timeout(&vst.decoder_lock, 3000) == 0)
|
||||||
mutex_lock_timeout(&vst.decoder_lock, 3000);
|
return -1;
|
||||||
|
|
||||||
decoder(&vst);
|
decoder(&vst);
|
||||||
|
|
||||||
@ -369,7 +358,6 @@ void decoder(vst_t* vst)
|
|||||||
delay(1);
|
delay(1);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
yield();
|
yield();
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -27,7 +27,6 @@ typedef struct
|
|||||||
int index;
|
int index;
|
||||||
double pts;
|
double pts;
|
||||||
double pkt_pts;
|
double pkt_pts;
|
||||||
double pkt_dts;
|
|
||||||
volatile int ready;
|
volatile int ready;
|
||||||
}vframe_t;
|
}vframe_t;
|
||||||
|
|
||||||
@ -111,21 +110,24 @@ typedef struct {
|
|||||||
int put_packet(queue_t *q, AVPacket *pkt);
|
int put_packet(queue_t *q, AVPacket *pkt);
|
||||||
int get_packet(queue_t *q, AVPacket *pkt);
|
int get_packet(queue_t *q, AVPacket *pkt);
|
||||||
|
|
||||||
#define HWDEC_NUM_SURFACES 16
|
|
||||||
struct vstate
|
struct vstate
|
||||||
{
|
{
|
||||||
AVFormatContext *fCtx; /* format context */
|
AVFormatContext *fCtx; /* format context */
|
||||||
AVCodecContext *vCtx; /* video decoder context */
|
AVCodecContext *vCtx; /* video decoder context */
|
||||||
AVCodecContext *aCtx; /* audio decoder context */
|
AVCodecContext *aCtx; /* audio decoder context */
|
||||||
AVCodec *vCodec; /* video codec */
|
AVCodec *vCodec; /* video codec */
|
||||||
AVCodec *aCodec; /* audio codec */
|
AVCodec *aCodec; /* audio codec */
|
||||||
int vStream; /* video stream index */
|
char *input_file;
|
||||||
int aStream; /* audio stream index */
|
char *input_name;
|
||||||
|
int vStream; /* video stream index */
|
||||||
|
int aStream; /* audio stream index */
|
||||||
|
AVRational video_time_base;
|
||||||
|
AVRational audio_time_base;
|
||||||
|
|
||||||
queue_t q_video; /* video packets queue */
|
queue_t q_video; /* video packets queue */
|
||||||
queue_t q_audio; /* audio packets queue */
|
queue_t q_audio; /* audio packets queue */
|
||||||
|
|
||||||
mutex_t gpu_lock; /* gpu access lock. libdrm not yet thread safe :( */
|
mutex_t gpu_lock; /* gpu access lock. libdrm not yet thread safe :( */
|
||||||
mutex_t decoder_lock;
|
mutex_t decoder_lock;
|
||||||
|
|
||||||
mutex_t input_lock;
|
mutex_t input_lock;
|
||||||
@ -133,13 +135,18 @@ struct vstate
|
|||||||
struct list_head input_list;
|
struct list_head input_list;
|
||||||
struct list_head output_list;
|
struct list_head output_list;
|
||||||
|
|
||||||
|
AVFrame *Frame;
|
||||||
|
|
||||||
vframe_t *decoder_frame;
|
vframe_t *decoder_frame;
|
||||||
void *hwCtx; /* hardware context */
|
volatile int frames_count;
|
||||||
int hwdec:1; /* hardware decoder */
|
void *hwCtx; /* hardware context */
|
||||||
int blit_bitmap:1; /* hardware RGBA blitter */
|
int hwdec:1; /* hardware decoder */
|
||||||
int blit_texture:1; /* hardware RGBA blit and scale */
|
int blit_bitmap:1; /* hardware RGBA blitter */
|
||||||
int blit_planar:1; /* hardbare YUV blit and scale */
|
int blit_texture:1; /* hardware RGBA blit and scale */
|
||||||
|
int blit_planar:1; /* hardbare YUV blit and scale */
|
||||||
int frame_reorder:1;
|
int frame_reorder:1;
|
||||||
|
int nframes;
|
||||||
|
vframe_t vframes[16];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -149,7 +156,6 @@ struct vstate
|
|||||||
|
|
||||||
extern int threads_running;
|
extern int threads_running;
|
||||||
extern astream_t astream;
|
extern astream_t astream;
|
||||||
extern AVRational video_time_base;
|
|
||||||
|
|
||||||
render_t *create_render(vst_t *vst, window_t *win, uint32_t flags);
|
render_t *create_render(vst_t *vst, window_t *win, uint32_t flags);
|
||||||
void destroy_render(render_t *render);
|
void destroy_render(render_t *render);
|
||||||
@ -164,8 +170,8 @@ int init_audio(int format);
|
|||||||
int audio_thread(void *param);
|
int audio_thread(void *param);
|
||||||
void set_audio_volume(int left, int right);
|
void set_audio_volume(int left, int right);
|
||||||
|
|
||||||
int init_video(vst_t* vst);
|
|
||||||
int video_thread(void *param);
|
int video_thread(void *param);
|
||||||
|
void flush_video(vst_t* vst);
|
||||||
|
|
||||||
void decoder(vst_t *vst);
|
void decoder(vst_t *vst);
|
||||||
int decode_video(vst_t* vst);
|
int decode_video(vst_t* vst);
|
||||||
@ -180,6 +186,11 @@ static inline void GetNotify(void *event)
|
|||||||
::"a"(68),"b"(14),"c"(event));
|
::"a"(68),"b"(14),"c"(event));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline double get_audio_base(vst_t* vst)
|
||||||
|
{
|
||||||
|
return (double)av_q2d(vst->fCtx->streams[vst->aStream]->time_base)*1000;
|
||||||
|
};
|
||||||
|
|
||||||
void va_create_planar(vst_t *vst, vframe_t *vframe);
|
void va_create_planar(vst_t *vst, vframe_t *vframe);
|
||||||
|
|
||||||
int init_fontlib();
|
int init_fontlib();
|
||||||
|
@ -39,7 +39,7 @@ struct hw_profile
|
|||||||
static int drm_fd = 0;
|
static int drm_fd = 0;
|
||||||
static struct vaapi_context *v_context;
|
static struct vaapi_context *v_context;
|
||||||
|
|
||||||
static VASurfaceID v_surface_id[HWDEC_NUM_SURFACES];
|
static VASurfaceID v_surface_id[16];
|
||||||
|
|
||||||
#define HAS_HEVC VA_CHECK_VERSION(0, 38, 0)
|
#define HAS_HEVC VA_CHECK_VERSION(0, 38, 0)
|
||||||
#define HAS_VP9 (VA_CHECK_VERSION(0, 38, 1) && defined(FF_PROFILE_VP9_0))
|
#define HAS_VP9 (VA_CHECK_VERSION(0, 38, 1) && defined(FF_PROFILE_VP9_0))
|
||||||
@ -281,10 +281,10 @@ static int has_entrypoint(struct vaapi_context *vaapi, VAProfile profile, VAEntr
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vaapi_init_decoder(VAProfile profile,
|
static int vaapi_init_decoder(vst_t *vst,VAProfile profile,
|
||||||
VAEntrypoint entrypoint,
|
VAEntrypoint entrypoint,
|
||||||
unsigned int picture_width,
|
unsigned int picture_width,
|
||||||
unsigned int picture_height)
|
unsigned int picture_height)
|
||||||
{
|
{
|
||||||
struct vaapi_context* const vaapi = v_context;
|
struct vaapi_context* const vaapi = v_context;
|
||||||
VAConfigAttrib attrib;
|
VAConfigAttrib attrib;
|
||||||
@ -343,7 +343,7 @@ ENTER();
|
|||||||
|
|
||||||
printf("vaCreateSurfaces %dx%d\n",picture_width,picture_height);
|
printf("vaCreateSurfaces %dx%d\n",picture_width,picture_height);
|
||||||
status = vaCreateSurfaces(vaapi->display, VA_RT_FORMAT_YUV420, picture_width, picture_height,
|
status = vaCreateSurfaces(vaapi->display, VA_RT_FORMAT_YUV420, picture_width, picture_height,
|
||||||
v_surface_id,HWDEC_NUM_SURFACES,NULL,0);
|
v_surface_id,vst->nframes,NULL,0);
|
||||||
if (!vaapi_check_status(status, "vaCreateSurfaces()"))
|
if (!vaapi_check_status(status, "vaCreateSurfaces()"))
|
||||||
{
|
{
|
||||||
FAIL();
|
FAIL();
|
||||||
@ -378,7 +378,7 @@ ENTER();
|
|||||||
status = vaCreateContext(vaapi->display, config_id,
|
status = vaCreateContext(vaapi->display, config_id,
|
||||||
picture_width, picture_height,
|
picture_width, picture_height,
|
||||||
VA_PROGRESSIVE,
|
VA_PROGRESSIVE,
|
||||||
v_surface_id, HWDEC_NUM_SURFACES,
|
v_surface_id, vst->nframes,
|
||||||
&context_id);
|
&context_id);
|
||||||
if (!vaapi_check_status(status, "vaCreateContext()"))
|
if (!vaapi_check_status(status, "vaCreateContext()"))
|
||||||
{
|
{
|
||||||
@ -396,9 +396,9 @@ ENTER();
|
|||||||
static enum PixelFormat get_format(struct AVCodecContext *avctx,
|
static enum PixelFormat get_format(struct AVCodecContext *avctx,
|
||||||
const enum AVPixelFormat *fmt)
|
const enum AVPixelFormat *fmt)
|
||||||
{
|
{
|
||||||
|
vst_t *vst = (vst_t*)avctx->opaque;
|
||||||
VAProfile profile = VAProfileNone;
|
VAProfile profile = VAProfileNone;
|
||||||
|
|
||||||
ENTER();
|
|
||||||
|
|
||||||
for (int i = 0; fmt[i] != PIX_FMT_NONE; i++)
|
for (int i = 0; fmt[i] != PIX_FMT_NONE; i++)
|
||||||
{
|
{
|
||||||
@ -419,17 +419,15 @@ static enum PixelFormat get_format(struct AVCodecContext *avctx,
|
|||||||
hw_profiles[n].ff_profile == avctx->profile)
|
hw_profiles[n].ff_profile == avctx->profile)
|
||||||
{
|
{
|
||||||
profile = hw_profiles[n].va_profile;
|
profile = hw_profiles[n].va_profile;
|
||||||
if (vaapi_init_decoder(profile, VAEntrypointVLD, avctx->width, avctx->height) == 0)
|
if (vaapi_init_decoder(vst, profile, VAEntrypointVLD, avctx->width, avctx->height) == 0)
|
||||||
{
|
{
|
||||||
avctx->hwaccel_context = v_context;
|
avctx->hwaccel_context = v_context;
|
||||||
LEAVE();
|
|
||||||
return fmt[i]; ;
|
return fmt[i]; ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
FAIL();
|
|
||||||
return PIX_FMT_NONE;
|
return PIX_FMT_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -472,6 +470,8 @@ int fplay_init_context(vst_t *vst)
|
|||||||
{
|
{
|
||||||
AVCodecContext *vCtx = vst->vCtx;
|
AVCodecContext *vCtx = vst->vCtx;
|
||||||
|
|
||||||
|
vst->nframes = 4;
|
||||||
|
|
||||||
if(va_check_codec_support(vCtx->codec_id))
|
if(va_check_codec_support(vCtx->codec_id))
|
||||||
{
|
{
|
||||||
VADisplay dpy;
|
VADisplay dpy;
|
||||||
@ -481,9 +481,12 @@ int fplay_init_context(vst_t *vst)
|
|||||||
|
|
||||||
if(vst->hwCtx != NULL)
|
if(vst->hwCtx != NULL)
|
||||||
{
|
{
|
||||||
for(int i = 0; i < HWDEC_NUM_SURFACES; i++)
|
if(vCtx->codec_id == AV_CODEC_ID_H264)
|
||||||
|
vst->nframes = 16;
|
||||||
|
|
||||||
|
for(int i = 0; i < vst->nframes; i++)
|
||||||
{
|
{
|
||||||
vframe_t *vframe = calloc(1, sizeof(*vframe));
|
vframe_t *vframe = &vst->vframes[i];
|
||||||
|
|
||||||
vframe->format = AV_PIX_FMT_NONE;
|
vframe->format = AV_PIX_FMT_NONE;
|
||||||
vframe->is_hw_pic = 1;
|
vframe->is_hw_pic = 1;
|
||||||
@ -494,6 +497,7 @@ int fplay_init_context(vst_t *vst)
|
|||||||
};
|
};
|
||||||
|
|
||||||
vst->hwdec = 1;
|
vst->hwdec = 1;
|
||||||
|
vst->frame_reorder = 1;
|
||||||
vCtx->opaque = vst;
|
vCtx->opaque = vst;
|
||||||
vCtx->thread_count = 1;
|
vCtx->thread_count = 1;
|
||||||
vCtx->get_format = get_format;
|
vCtx->get_format = get_format;
|
||||||
@ -504,12 +508,12 @@ int fplay_init_context(vst_t *vst)
|
|||||||
|
|
||||||
vst->hwdec = 0;
|
vst->hwdec = 0;
|
||||||
|
|
||||||
for(int i = 0; i < HWDEC_NUM_SURFACES; i++)
|
for(int i = 0; i < vst->nframes; i++)
|
||||||
{
|
{
|
||||||
vframe_t *vframe;
|
vframe_t *vframe;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
vframe = calloc(1, sizeof(*vframe));
|
vframe = &vst->vframes[i];
|
||||||
|
|
||||||
ret = avpicture_alloc(&vframe->picture, vst->vCtx->pix_fmt,
|
ret = avpicture_alloc(&vframe->picture, vst->vCtx->pix_fmt,
|
||||||
vst->vCtx->width, vst->vCtx->height);
|
vst->vCtx->width, vst->vCtx->height);
|
||||||
|
@ -21,16 +21,10 @@ extern int64_t stream_duration;
|
|||||||
extern volatile int sound_level_0;
|
extern volatile int sound_level_0;
|
||||||
extern volatile int sound_level_1;
|
extern volatile int sound_level_1;
|
||||||
|
|
||||||
volatile int frames_count = 0;
|
|
||||||
|
|
||||||
struct SwsContext *cvt_ctx = NULL;
|
struct SwsContext *cvt_ctx = NULL;
|
||||||
|
|
||||||
|
|
||||||
render_t *main_render;
|
render_t *main_render;
|
||||||
|
|
||||||
AVRational video_time_base;
|
|
||||||
AVFrame *Frame;
|
|
||||||
|
|
||||||
void get_client_rect(rect_t *rc);
|
void get_client_rect(rect_t *rc);
|
||||||
void run_render(window_t *win, void *render);
|
void run_render(window_t *win, void *render);
|
||||||
void window_update_layout(window_t *win);
|
void window_update_layout(window_t *win);
|
||||||
@ -51,30 +45,12 @@ void flush_video(vst_t *vst)
|
|||||||
vframe->pts = 0;
|
vframe->pts = 0;
|
||||||
vframe->ready = 0;
|
vframe->ready = 0;
|
||||||
}
|
}
|
||||||
|
vst->frames_count = 0;
|
||||||
|
|
||||||
mutex_unlock(&vst->input_lock);
|
mutex_unlock(&vst->input_lock);
|
||||||
mutex_unlock(&vst->output_lock);
|
mutex_unlock(&vst->output_lock);
|
||||||
|
|
||||||
frames_count = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int init_video(vst_t *vst)
|
|
||||||
{
|
|
||||||
Frame = av_frame_alloc();
|
|
||||||
if ( Frame == NULL )
|
|
||||||
{
|
|
||||||
printf("Cannot alloc video frame\n\r");
|
|
||||||
return 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
mutex_lock(&vst->decoder_lock);
|
|
||||||
|
|
||||||
create_thread(video_thread, vst, 1024*1024);
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
};
|
|
||||||
|
|
||||||
static double dts = 0.0;
|
|
||||||
|
|
||||||
static vframe_t *get_input_frame(vst_t *vst)
|
static vframe_t *get_input_frame(vst_t *vst)
|
||||||
{
|
{
|
||||||
@ -115,31 +91,31 @@ static void put_output_frame(vst_t *vst, vframe_t *vframe)
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
vst->frames_count++;
|
||||||
mutex_unlock(&vst->output_lock);
|
mutex_unlock(&vst->output_lock);
|
||||||
};
|
};
|
||||||
|
|
||||||
int decode_video(vst_t* vst)
|
int decode_video(vst_t* vst)
|
||||||
{
|
{
|
||||||
AVPacket pkt;
|
|
||||||
double pts;
|
double pts;
|
||||||
|
AVPacket pkt;
|
||||||
|
|
||||||
int frameFinished;
|
int frameFinished;
|
||||||
|
|
||||||
if(vst->decoder_frame == NULL)
|
if(vst->decoder_frame == NULL)
|
||||||
vst->decoder_frame = get_input_frame(vst);
|
vst->decoder_frame = get_input_frame(vst);
|
||||||
|
|
||||||
if(vst->decoder_frame == NULL)
|
if(vst->decoder_frame == NULL)
|
||||||
return 0;
|
return -1;
|
||||||
|
|
||||||
if( get_packet(&vst->q_video, &pkt) == 0 )
|
if( get_packet(&vst->q_video, &pkt) == 0 )
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
frameFinished = 0;
|
frameFinished = 0;
|
||||||
if(dts == 0)
|
|
||||||
dts = pkt.pts;
|
|
||||||
|
|
||||||
mutex_lock(&vst->gpu_lock);
|
mutex_lock(&vst->gpu_lock);
|
||||||
|
|
||||||
if(avcodec_decode_video2(vst->vCtx, Frame, &frameFinished, &pkt) <= 0)
|
if(avcodec_decode_video2(vst->vCtx, vst->Frame, &frameFinished, &pkt) <= 0)
|
||||||
printf("video decoder error\n");
|
printf("video decoder error\n");
|
||||||
|
|
||||||
if(frameFinished)
|
if(frameFinished)
|
||||||
@ -150,22 +126,21 @@ int decode_video(vst_t* vst)
|
|||||||
if(vst->hwdec)
|
if(vst->hwdec)
|
||||||
pts = pkt.pts;
|
pts = pkt.pts;
|
||||||
else
|
else
|
||||||
pts = av_frame_get_best_effort_timestamp(Frame);
|
pts = av_frame_get_best_effort_timestamp(vst->Frame);
|
||||||
|
|
||||||
pts*= av_q2d(video_time_base);
|
pts*= av_q2d(vst->video_time_base);
|
||||||
|
|
||||||
dst_pic = &vframe->picture;
|
dst_pic = &vframe->picture;
|
||||||
|
|
||||||
if(vframe->is_hw_pic == 0)
|
if(vframe->is_hw_pic == 0)
|
||||||
av_image_copy(dst_pic->data, dst_pic->linesize,
|
av_image_copy(dst_pic->data, dst_pic->linesize,
|
||||||
(const uint8_t**)Frame->data,
|
(const uint8_t**)vst->Frame->data,
|
||||||
Frame->linesize, vst->vCtx->pix_fmt, vst->vCtx->width, vst->vCtx->height);
|
vst->Frame->linesize, vst->vCtx->pix_fmt, vst->vCtx->width, vst->vCtx->height);
|
||||||
else
|
else
|
||||||
va_create_planar(vst, vframe);
|
va_create_planar(vst, vframe);
|
||||||
|
|
||||||
vframe->pts = pts*1000.0;
|
vframe->pts = pts*1000.0;
|
||||||
vframe->pkt_pts = pkt.pts*av_q2d(video_time_base)*1000.0;
|
vframe->pkt_pts = pkt.pts*av_q2d(vst->video_time_base)*1000.0;
|
||||||
vframe->pkt_dts = dts*av_q2d(video_time_base)*1000.0;
|
|
||||||
vframe->ready = 1;
|
vframe->ready = 1;
|
||||||
|
|
||||||
put_output_frame(vst, vframe);
|
put_output_frame(vst, vframe);
|
||||||
@ -175,10 +150,8 @@ int decode_video(vst_t* vst)
|
|||||||
// vst->vframe[vst->dfx].pkt_pts, vst->vframe[vst->dfx].pkt_dts);
|
// vst->vframe[vst->dfx].pkt_pts, vst->vframe[vst->dfx].pkt_dts);
|
||||||
|
|
||||||
vst->decoder_frame = NULL;
|
vst->decoder_frame = NULL;
|
||||||
frames_count++;
|
|
||||||
dts = 0;
|
|
||||||
};
|
};
|
||||||
av_frame_unref(Frame);
|
av_frame_unref(vst->Frame);
|
||||||
mutex_unlock(&vst->gpu_lock);
|
mutex_unlock(&vst->gpu_lock);
|
||||||
|
|
||||||
av_free_packet(&pkt);
|
av_free_packet(&pkt);
|
||||||
@ -417,7 +390,7 @@ void render_time(render_t *render)
|
|||||||
delay(1);
|
delay(1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (decoder_state == STOP && frames_count == 0 &&
|
else if (decoder_state == STOP && vst->frames_count == 0 &&
|
||||||
player_state != STOP)
|
player_state != STOP)
|
||||||
{
|
{
|
||||||
player_stop();
|
player_stop();
|
||||||
@ -441,10 +414,11 @@ void render_time(render_t *render)
|
|||||||
|
|
||||||
vframe = list_first_entry(&vst->output_list, vframe_t, list);
|
vframe = list_first_entry(&vst->output_list, vframe_t, list);
|
||||||
list_del(&vframe->list);
|
list_del(&vframe->list);
|
||||||
|
vst->frames_count--;
|
||||||
mutex_unlock(&vst->output_lock);
|
mutex_unlock(&vst->output_lock);
|
||||||
|
|
||||||
ctime = get_master_clock();
|
ctime = get_master_clock();
|
||||||
fdelay = (vframe->pkt_pts - ctime);
|
fdelay = (vframe->pts - ctime);
|
||||||
|
|
||||||
if(fdelay > 15.0)
|
if(fdelay > 15.0)
|
||||||
{
|
{
|
||||||
@ -458,7 +432,7 @@ void render_time(render_t *render)
|
|||||||
|
|
||||||
if(main_render->win->win_state != FULLSCREEN)
|
if(main_render->win->win_state != FULLSCREEN)
|
||||||
{
|
{
|
||||||
prg->current = vframe->pkt_pts * 1000;
|
prg->current = vframe->pts * 1000;
|
||||||
lvl->current = vframe->index & 1 ? sound_level_1 : sound_level_0;
|
lvl->current = vframe->index & 1 ? sound_level_1 : sound_level_0;
|
||||||
|
|
||||||
send_message(&prg->ctrl, PRG_PROGRESS, 0, 0);
|
send_message(&prg->ctrl, PRG_PROGRESS, 0, 0);
|
||||||
@ -467,7 +441,6 @@ void render_time(render_t *render)
|
|||||||
send_message(&lvl->ctrl, MSG_PAINT, 0, 0);
|
send_message(&lvl->ctrl, MSG_PAINT, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
frames_count--;
|
|
||||||
vframe->ready = 0;
|
vframe->ready = 0;
|
||||||
|
|
||||||
mutex_lock(&vst->input_lock);
|
mutex_lock(&vst->input_lock);
|
||||||
@ -476,9 +449,6 @@ void render_time(render_t *render)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
extern char *movie_file;
|
|
||||||
|
|
||||||
int video_thread(void *param)
|
int video_thread(void *param)
|
||||||
{
|
{
|
||||||
vst_t *vst = param;
|
vst_t *vst = param;
|
||||||
@ -486,7 +456,7 @@ int video_thread(void *param)
|
|||||||
|
|
||||||
init_winlib();
|
init_winlib();
|
||||||
|
|
||||||
MainWindow = create_window(movie_file,0,
|
MainWindow = create_window(vst->input_name,0,
|
||||||
10,10,vst->vCtx->width,vst->vCtx->height+CAPTION_HEIGHT+PANEL_HEIGHT,MainWindowProc);
|
10,10,vst->vCtx->width,vst->vCtx->height+CAPTION_HEIGHT+PANEL_HEIGHT,MainWindowProc);
|
||||||
|
|
||||||
MainWindow->panel.prg->max = stream_duration;
|
MainWindow->panel.prg->max = stream_duration;
|
||||||
|
Loading…
Reference in New Issue
Block a user