#include <limits.h>
#include "libavutil/avstring.h"
#include "libavformat/avformat.h"
-#include "libavformat/rtsp.h"
#include "libavdevice/avdevice.h"
#include "libswscale/swscale.h"
#include "libavcodec/audioconvert.h"
+#include "libavcodec/colorspace.h"
#include "libavcodec/opt.h"
#include "cmdutils.h"
//#define DEBUG_SYNC
#define MAX_VIDEOQ_SIZE (5 * 256 * 1024)
-#define MAX_AUDIOQ_SIZE (5 * 16 * 1024)
+#define MAX_AUDIOQ_SIZE (20 * 16 * 1024)
#define MAX_SUBTITLEQ_SIZE (5 * 16 * 1024)
/* SDL audio buffer size, in samples. Should be small to have precise
uint8_t *audio_buf;
unsigned int audio_buf_size; /* in bytes */
int audio_buf_index; /* in bytes */
+ AVPacket audio_pkt_temp;
AVPacket audio_pkt;
- uint8_t *audio_pkt_data;
- int audio_pkt_size;
enum SampleFormat audio_src_fmt;
AVAudioConvert *reformat_ctx;
int pictq_size, pictq_rindex, pictq_windex;
SDL_mutex *pictq_mutex;
SDL_cond *pictq_cond;
+ struct SwsContext *img_convert_ctx;
// QETimer *video_timer;
char filename[1024];
static int wanted_subtitle_stream= -1;
static int seek_by_bytes;
static int display_disable;
-static int show_status;
+static int show_status = 1;
static int av_sync_type = AV_SYNC_AUDIO_MASTER;
static int64_t start_time = AV_NOPTS_VALUE;
static int debug = 0;
}
#endif
-
-
-#define SCALEBITS 10
-#define ONE_HALF (1 << (SCALEBITS - 1))
-#define FIX(x) ((int) ((x) * (1<<SCALEBITS) + 0.5))
-
-#define RGB_TO_Y_CCIR(r, g, b) \
-((FIX(0.29900*219.0/255.0) * (r) + FIX(0.58700*219.0/255.0) * (g) + \
- FIX(0.11400*219.0/255.0) * (b) + (ONE_HALF + (16 << SCALEBITS))) >> SCALEBITS)
-
-#define RGB_TO_U_CCIR(r1, g1, b1, shift)\
-(((- FIX(0.16874*224.0/255.0) * r1 - FIX(0.33126*224.0/255.0) * g1 + \
- FIX(0.50000*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
-
-#define RGB_TO_V_CCIR(r1, g1, b1, shift)\
-(((FIX(0.50000*224.0/255.0) * r1 - FIX(0.41869*224.0/255.0) * g1 - \
- FIX(0.08131*224.0/255.0) * b1 + (ONE_HALF << shift) - 1) >> (SCALEBITS + shift)) + 128)
-
#define ALPHA_BLEND(a, oldp, newp, s)\
((((oldp << s) * (255 - (a))) + (newp * (a))) / (255 << s))
double av_diff;
cur_time = av_gettime();
- if (!last_time || (cur_time - last_time) >= 500 * 1000) {
+ if (!last_time || (cur_time - last_time) >= 30000) {
aqsize = 0;
vqsize = 0;
sqsize = 0;
if (vp->bmp)
SDL_FreeYUVOverlay(vp->bmp);
-#if 0
- /* XXX: use generic function */
- /* XXX: disable overlay if no hardware acceleration or if RGB format */
- switch(is->video_st->codec->pix_fmt) {
- case PIX_FMT_YUV420P:
- case PIX_FMT_YUV422P:
- case PIX_FMT_YUV444P:
- case PIX_FMT_YUYV422:
- case PIX_FMT_YUV410P:
- case PIX_FMT_YUV411P:
- is_yuv = 1;
- break;
- default:
- is_yuv = 0;
- break;
- }
-#endif
vp->bmp = SDL_CreateYUVOverlay(is->video_st->codec->width,
is->video_st->codec->height,
SDL_YV12_OVERLAY,
{
VideoPicture *vp;
int dst_pix_fmt;
- AVPicture pict;
- static struct SwsContext *img_convert_ctx;
/* wait until we have space to put a new picture */
SDL_LockMutex(is->pictq_mutex);
/* if the frame is not skipped, then display it */
if (vp->bmp) {
+ AVPicture pict;
+
/* get a pointer on the bitmap */
SDL_LockYUVOverlay (vp->bmp);
dst_pix_fmt = PIX_FMT_YUV420P;
+ memset(&pict,0,sizeof(AVPicture));
pict.data[0] = vp->bmp->pixels[0];
pict.data[1] = vp->bmp->pixels[2];
pict.data[2] = vp->bmp->pixels[1];
pict.linesize[1] = vp->bmp->pitches[2];
pict.linesize[2] = vp->bmp->pitches[1];
sws_flags = av_get_int(sws_opts, "sws_flags", NULL);
- img_convert_ctx = sws_getCachedContext(img_convert_ctx,
+ is->img_convert_ctx = sws_getCachedContext(is->img_convert_ctx,
is->video_st->codec->width, is->video_st->codec->height,
is->video_st->codec->pix_fmt,
is->video_st->codec->width, is->video_st->codec->height,
dst_pix_fmt, sws_flags, NULL, NULL, NULL);
- if (img_convert_ctx == NULL) {
+ if (is->img_convert_ctx == NULL) {
fprintf(stderr, "Cannot initialize the conversion context\n");
exit(1);
}
- sws_scale(img_convert_ctx, src_frame->data, src_frame->linesize,
+ sws_scale(is->img_convert_ctx, src_frame->data, src_frame->linesize,
0, is->video_st->codec->height, pict.data, pict.linesize);
/* update the bitmap content */
SDL_UnlockYUVOverlay(vp->bmp);
/* NOTE: ipts is the PTS of the _first_ picture beginning in
this packet, if any */
is->video_st->codec->reordered_opaque= pkt->pts;
- len1 = avcodec_decode_video(is->video_st->codec,
+ len1 = avcodec_decode_video2(is->video_st->codec,
frame, &got_picture,
- pkt->data, pkt->size);
+ pkt);
if( (decoder_reorder_pts || pkt->dts == AV_NOPTS_VALUE)
&& frame->reordered_opaque != AV_NOPTS_VALUE)
if (pkt->pts != AV_NOPTS_VALUE)
pts = av_q2d(is->subtitle_st->time_base)*pkt->pts;
- len1 = avcodec_decode_subtitle(is->subtitle_st->codec,
+ len1 = avcodec_decode_subtitle2(is->subtitle_st->codec,
&sp->sub, &got_subtitle,
- pkt->data, pkt->size);
+ pkt);
// if (len1 < 0)
// break;
if (got_subtitle && sp->sub.format == 0) {
/* decode one audio frame and returns its uncompressed size */
static int audio_decode_frame(VideoState *is, double *pts_ptr)
{
+ AVPacket *pkt_temp = &is->audio_pkt_temp;
AVPacket *pkt = &is->audio_pkt;
AVCodecContext *dec= is->audio_st->codec;
int n, len1, data_size;
for(;;) {
/* NOTE: the audio packet can contain several frames */
- while (is->audio_pkt_size > 0) {
+ while (pkt_temp->size > 0) {
data_size = sizeof(is->audio_buf1);
- len1 = avcodec_decode_audio2(dec,
+ len1 = avcodec_decode_audio3(dec,
(int16_t *)is->audio_buf1, &data_size,
- is->audio_pkt_data, is->audio_pkt_size);
+ pkt_temp);
if (len1 < 0) {
/* if error, we skip the frame */
- is->audio_pkt_size = 0;
+ pkt_temp->size = 0;
break;
}
- is->audio_pkt_data += len1;
- is->audio_pkt_size -= len1;
+ pkt_temp->data += len1;
+ pkt_temp->size -= len1;
if (data_size <= 0)
continue;
continue;
}
- is->audio_pkt_data = pkt->data;
- is->audio_pkt_size = pkt->size;
+ pkt_temp->data = pkt->data;
+ pkt_temp->size = pkt->size;
/* if update the audio clock with the pts */
if (pkt->pts != AV_NOPTS_VALUE) {
}
}
-static void dump_stream_info(const AVFormatContext *s)
-{
- AVMetadataTag *tag = NULL;
- while ((tag=av_metadata_get(s->metadata,"",tag,AV_METADATA_IGNORE_SUFFIX)))
- fprintf(stderr, "%s: %s\n", tag->key, tag->value);
-}
-
/* since we have only one decoding thread, we can use a global
variable instead of a thread local variable */
static VideoState *global_video_state;
int err, i, ret, video_index, audio_index, subtitle_index;
AVPacket pkt1, *pkt = &pkt1;
AVFormatParameters params, *ap = ¶ms;
+ int eof=0;
video_index = -1;
audio_index = -1;
}
if (show_status) {
dump_format(ic, 0, is->filename, 0);
- dump_stream_info(ic);
}
/* open the streams */
}
}
is->seek_req = 0;
+ eof= 0;
}
/* if the queue are full, no need to read more */
SDL_Delay(10);
continue;
}
- if(url_feof(ic->pb)) {
- av_init_packet(pkt);
- pkt->data=NULL;
- pkt->size=0;
- pkt->stream_index= is->video_stream;
- packet_queue_put(&is->videoq, pkt);
+ if(url_feof(ic->pb) || eof) {
+ if(is->video_stream >= 0){
+ av_init_packet(pkt);
+ pkt->data=NULL;
+ pkt->size=0;
+ pkt->stream_index= is->video_stream;
+ packet_queue_put(&is->videoq, pkt);
+ }
+ SDL_Delay(10);
continue;
}
ret = av_read_frame(ic, pkt);
if (ret < 0) {
- if (ret != AVERROR_EOF && url_ferror(ic->pb) == 0) {
- SDL_Delay(100); /* wait for user event */
- continue;
- } else
+ if (ret == AVERROR_EOF)
+ eof=1;
+ if (url_ferror(ic->pb))
break;
+ SDL_Delay(100); /* wait for user event */
+ continue;
}
if (pkt->stream_index == is->audio_stream) {
packet_queue_put(&is->audioq, pkt);
SDL_DestroyCond(is->pictq_cond);
SDL_DestroyMutex(is->subpq_mutex);
SDL_DestroyCond(is->subpq_cond);
+ if (is->img_convert_ctx)
+ sws_freeContext(is->img_convert_ctx);
+ av_free(is);
}
static void stream_cycle_channel(VideoState *is, int codec_type)
static void do_exit(void)
{
+ int i;
if (cur_stream) {
stream_close(cur_stream);
cur_stream = NULL;
}
+ for (i = 0; i < CODEC_TYPE_NB; i++)
+ av_free(avcodec_opts[i]);
+ av_free(avformat_opts);
+ av_free(sws_opts);
if (show_status)
printf("\n");
SDL_Quit();
break;
case SDL_MOUSEBUTTONDOWN:
if (cur_stream) {
+ int64_t ts;
int ns, hh, mm, ss;
int tns, thh, tmm, tss;
tns = cur_stream->ic->duration/1000000LL;
ss = (ns%60);
fprintf(stderr, "Seek to %2.0f%% (%2d:%02d:%02d) of total duration (%2d:%02d:%02d) \n", frac*100,
hh, mm, ss, thh, tmm, tss);
- stream_seek(cur_stream, (int64_t)(cur_stream->ic->start_time+frac*cur_stream->ic->duration), 0);
+ ts = frac*cur_stream->ic->duration;
+ if (cur_stream->ic->start_time != AV_NOPTS_VALUE)
+ ts += cur_stream->ic->start_time;
+ stream_seek(cur_stream, ts, 0);
}
break;
case SDL_VIDEORESIZE:
{ "sync", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_sync}, "set audio-video sync. type (type=audio/video/ext)", "type" },
{ "threads", HAS_ARG | OPT_FUNC2 | OPT_EXPERT, {(void*)opt_thread_count}, "thread count", "count" },
{ "default", OPT_FUNC2 | HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {(void*)opt_default}, "generic catch all option", "" },
+ { "loglevel", HAS_ARG | OPT_FUNC2, {(void*)opt_loglevel}, "set libav* logging level", "logging level number or string" },
{ NULL, },
};