redbutton-devel Mailing List for RedButton MHEG Engine (Page 24)
Brought to you by:
skilvington
You can subscribe to this list here.
| 2006 |
Jan
(1) |
Feb
(4) |
Mar
(27) |
Apr
(6) |
May
(46) |
Jun
(45) |
Jul
(7) |
Aug
(4) |
Sep
(7) |
Oct
(5) |
Nov
(10) |
Dec
(11) |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2007 |
Jan
(49) |
Feb
(29) |
Mar
(35) |
Apr
(43) |
May
(23) |
Jun
(4) |
Jul
(1) |
Aug
(58) |
Sep
(66) |
Oct
(27) |
Nov
(15) |
Dec
(1) |
| 2008 |
Jan
(11) |
Feb
|
Mar
(8) |
Apr
|
May
|
Jun
(30) |
Jul
(1) |
Aug
(1) |
Sep
(1) |
Oct
|
Nov
(3) |
Dec
(6) |
| 2009 |
Jan
(6) |
Feb
(1) |
Mar
(2) |
Apr
(5) |
May
(2) |
Jun
(1) |
Jul
(7) |
Aug
|
Sep
(2) |
Oct
(2) |
Nov
|
Dec
(6) |
| 2010 |
Jan
(6) |
Feb
|
Mar
(4) |
Apr
|
May
|
Jun
|
Jul
|
Aug
(6) |
Sep
(4) |
Oct
|
Nov
(11) |
Dec
(4) |
| 2011 |
Jan
|
Feb
(11) |
Mar
(8) |
Apr
|
May
|
Jun
(3) |
Jul
|
Aug
|
Sep
(4) |
Oct
|
Nov
(2) |
Dec
|
| 2012 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: <ski...@us...> - 2006-06-13 15:55:05
|
Revision: 107 Author: skilvington Date: 2006-06-13 08:54:52 -0700 (Tue, 13 Jun 2006) ViewCVS: http://svn.sourceforge.net/redbutton/?rev=107&view=rev Log Message: ----------- take account of audio sample format Modified Paths: -------------- redbutton-browser/trunk/MHEGStreamPlayer.c Modified: redbutton-browser/trunk/MHEGStreamPlayer.c =================================================================== --- redbutton-browser/trunk/MHEGStreamPlayer.c 2006-06-13 15:11:41 UTC (rev 106) +++ redbutton-browser/trunk/MHEGStreamPlayer.c 2006-06-13 15:54:52 UTC (rev 107) @@ -315,8 +315,13 @@ if(af->size > 0) { af->pts = pts; - /* 16-bit samples, but af->size is in bytes */ - pts += (af->size / 2.0) / (audio_codec_ctx->channels * audio_codec_ctx->sample_rate); + /* 16 or 32-bit samples, but af->size is in bytes */ + if(audio_codec_ctx->sample_fmt == SAMPLE_FMT_S16) + pts += (af->size / 2.0) / (audio_codec_ctx->channels * audio_codec_ctx->sample_rate); + else if(audio_codec_ctx->sample_fmt == SAMPLE_FMT_S32) + pts += (af->size / 4.0) / (audio_codec_ctx->channels * audio_codec_ctx->sample_rate); + else + fatal("Unsupported audio sample format (%d)", audio_codec_ctx->sample_fmt); pthread_mutex_lock(&p->audioq_lock); LIST_APPEND(&p->audioq, audio_frame); pthread_mutex_unlock(&p->audioq_lock); @@ -557,7 +562,7 @@ /* * audio thread - * takes audio samples of the audioq and feeds them into the sound card as fast as possible + * takes audio samples off the audioq and feeds them into the sound card as fast as possible * MHEGAudioOuput_addSamples() will block while the sound card buffer is full */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <ski...@us...> - 2006-06-13 15:11:52
|
Revision: 106 Author: skilvington Date: 2006-06-13 08:11:41 -0700 (Tue, 13 Jun 2006) ViewCVS: http://svn.sourceforge.net/redbutton/?rev=106&view=rev Log Message: ----------- modular X.org needs explicit -lXext Modified Paths: -------------- redbutton-browser/trunk/Makefile Modified: redbutton-browser/trunk/Makefile =================================================================== --- redbutton-browser/trunk/Makefile 2006-06-13 13:42:27 UTC (rev 105) +++ redbutton-browser/trunk/Makefile 2006-06-13 15:11:41 UTC (rev 106) @@ -4,7 +4,7 @@ DEFS=-D_REENTRANT -D_GNU_SOURCE #DEFS=-DDEBUG_ALLOC -D_REENTRANT -D_GNU_SOURCE INCS=`freetype-config --cflags` -LIBS=-lm -lz -L/usr/X11R6/lib -lX11 -lXt -lXrender -lXft -lpng -lmpeg2 -lmpeg2convert -lavformat -lavcodec -lasound -lpthread +LIBS=-lm -lz -L/usr/X11R6/lib -lX11 -lXext -lXt -lXrender -lXft -lpng -lmpeg2 -lmpeg2convert -lavformat -lavcodec -lasound -lpthread CLASSES=ActionClass.o \ ApplicationClass.o \ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <ski...@us...> - 2006-06-13 13:42:40
|
Revision: 105 Author: skilvington Date: 2006-06-13 06:42:27 -0700 (Tue, 13 Jun 2006) ViewCVS: http://svn.sourceforge.net/redbutton/?rev=105&view=rev Log Message: ----------- describe features of latest release Modified Paths: -------------- www/index.html Modified: www/index.html =================================================================== --- www/index.html 2006-06-13 13:19:52 UTC (rev 104) +++ www/index.html 2006-06-13 13:42:27 UTC (rev 105) @@ -141,19 +141,22 @@ <P> To run it you need an X server that supports the Xrender extension and you need to have libpng, libmpeg2 and freetype2 installed. <H2>Notes</H2> -It'll only draw text, rectangles and bitmaps at the moment and some of the ElementaryActions are not yet implemented. -However, it is enough to be usable. -The main things missing are video and audio streams, at the moment it'll just draw a green box where any video should be. +It does not implement the whole MHEG spec. +However, it seems to be enough to view everything that is currently being broadcast on the 'Freeview' channels in the UK. +If it comes across something that is not yet implemented it will print out a message on the console. Let us know if you find anything it can't do. <P> -The SVN version now plays video and audio streams. -Note that it does not currently use any acceleration that your graphics card may provide -so it'll drop frames in full screen mode unless you have a very fast processor +It does not retune to different channels yet if the app requests it. +It will print out a message saying what service ID it needs to tune to, +but you will have to retune manually and restart it. +<P> +It does not currently use any acceleration that your graphics card may provide +so it'll drop video frames in full screen mode unless you have a very fast processor (or your full screen X resolution is set to 720x576 pixels). <P> It will only display apps that conform to the UK MHEG Profile (available from <A href="http://www.dtg.org.uk/">www.dtg.org.uk</A>). <P> -If you get a blank screen when it starts, try pressing 'r' (for BBC) or 't' (for ITV/C4) to activate +When it starts you will probably need to press 'r' (for BBC) or 't' (for ITV/C4) to activate any MHEG app that may be waiting for you to do something. <P> The default font for the UK MHEG Profile is Tiresias Screenfont which was This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <ski...@us...> - 2006-06-13 13:27:24
|
Revision: 102 Author: skilvington Date: 2006-06-13 06:13:56 -0700 (Tue, 13 Jun 2006) ViewCVS: http://svn.sourceforge.net/redbutton/?rev=102&view=rev Log Message: ----------- svn version now syncs audio and video Modified Paths: -------------- www/index.html Modified: www/index.html =================================================================== --- www/index.html 2006-06-13 11:18:47 UTC (rev 101) +++ www/index.html 2006-06-13 13:13:56 UTC (rev 102) @@ -145,7 +145,7 @@ However, it is enough to be usable. The main things missing are video and audio streams, at the moment it'll just draw a green box where any video should be. <P> -The SVN version now plays video and audio streams (although they are not synchronised yet). +The SVN version now plays video and audio streams. Note that it does not currently use any acceleration that your graphics card may provide so it'll drop frames in full screen mode unless you have a very fast processor (or your full screen X resolution is set to 720x576 pixels). This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <ski...@us...> - 2006-06-13 13:27:21
|
Revision: 104 Author: skilvington Date: 2006-06-13 06:19:52 -0700 (Tue, 13 Jun 2006) ViewCVS: http://svn.sourceforge.net/redbutton/?rev=104&view=rev Log Message: ----------- Tagged release 20060613 Added Paths: ----------- redbutton-download/tags/redbutton-download-20060613/ Copied: redbutton-download/tags/redbutton-download-20060613 (from rev 103, redbutton-download/trunk) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <ski...@us...> - 2006-06-13 13:27:20
|
Revision: 103 Author: skilvington Date: 2006-06-13 06:18:57 -0700 (Tue, 13 Jun 2006) ViewCVS: http://svn.sourceforge.net/redbutton/?rev=103&view=rev Log Message: ----------- Tagged release 20060613 Added Paths: ----------- redbutton-browser/tags/redbutton-browser-20060613/ Copied: redbutton-browser/tags/redbutton-browser-20060613 (from rev 102, redbutton-browser/trunk) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <ski...@us...> - 2006-06-13 11:18:58
|
Revision: 101 Author: skilvington Date: 2006-06-13 04:18:47 -0700 (Tue, 13 Jun 2006) ViewCVS: http://svn.sourceforge.net/redbutton/?rev=101&view=rev Log Message: ----------- synchronise audio with video Modified Paths: -------------- redbutton-browser/trunk/MHEGStreamPlayer.c redbutton-browser/trunk/MHEGStreamPlayer.h Modified: redbutton-browser/trunk/MHEGStreamPlayer.c =================================================================== --- redbutton-browser/trunk/MHEGStreamPlayer.c 2006-06-13 09:05:02 UTC (rev 100) +++ redbutton-browser/trunk/MHEGStreamPlayer.c 2006-06-13 11:18:47 UTC (rev 101) @@ -18,6 +18,8 @@ static void *video_thread(void *); static void *audio_thread(void *); +static void set_avsync_base(MHEGStreamPlayer *, double, int64_t); + static void thread_usleep(unsigned long); static enum CodecID find_av_codec_id(int); @@ -91,6 +93,9 @@ p->audio_codec = NULL; + pthread_mutex_init(&p->base_lock, NULL); + pthread_cond_init(&p->base_cond, NULL); + pthread_mutex_init(&p->videoq_lock, NULL); p->videoq = NULL; @@ -105,6 +110,9 @@ { MHEGStreamPlayer_stop(p); + pthread_mutex_destroy(&p->base_lock); + pthread_cond_destroy(&p->base_cond); + pthread_mutex_destroy(&p->videoq_lock); pthread_mutex_destroy(&p->audioq_lock); @@ -410,7 +418,12 @@ /* do we need to bomb out early */ if(p->stop) + { + /* wake up the audio thread */ + if(p->have_audio) + set_avsync_base(p, 0.0, 0); return NULL; + } /* assert */ if(p->videoq == NULL) @@ -485,6 +498,8 @@ out_height = (out_height * d->yres) / MHEG_YRES; } MHEGVideoOutput_prepareFrame(&vo, vf, out_width, out_height); + /* remember the PTS for this frame */ + last_pts = vf->pts; /* wait until it's time to display the frame */ now = av_gettime(); /* don't wait if this is the first frame */ @@ -497,13 +512,14 @@ /* remember when we should have displayed this frame */ last_time = this_time; } - else + else /* first frame */ { /* remember when we displayed this frame */ last_time = now; + /* tell the audio thread what the PTS and real time are for the first video frame */ + if(p->have_audio) + set_avsync_base(p, last_pts, last_time); } - /* remember the time stamp for this frame */ - last_pts = vf->pts; /* origin of VideoClass */ pthread_mutex_lock(&p->video->inst.bbox_lock); out_x = p->video->inst.Position.x_position; @@ -557,6 +573,10 @@ snd_pcm_format_t format = 0; /* keep the compiler happy */ unsigned int rate; unsigned int channels; + bool done; + int64_t now_time, next_time; + double now_pts, next_pts; + int usecs; if(!p->have_audio) return NULL; @@ -568,19 +588,43 @@ fatal("audio_thread: AudioClass is NULL"); /* do we need to sync the audio with the video */ -#if 0 if(p->have_video) { /* wait until the video thread tells us it has some frames buffered up */ -/* TODO */ - /* get the video's first PTS and first actual time stamp values */ -/* TODO */ -/* video thread should set base_pts and base_time from the values for the first frame it displays */ + pthread_mutex_lock(&p->base_lock); + pthread_cond_wait(&p->base_cond, &p->base_lock); + pthread_mutex_unlock(&p->base_lock); + /* video thread sets base_pts and base_time from the values for the first frame it displays */ base_time = p->base_time; base_pts = p->base_pts; + /* get rid of audio frames that we should have played already */ + done = false; + while(!done) + { + /* what PTS are we looking for */ + now_time = av_gettime(); + now_pts = base_pts + ((now_time - base_time) / 1000000.0); + /* remove frames we should have played already */ + pthread_mutex_lock(&p->audioq_lock); + while(p->audioq && p->audioq->item.pts < now_pts) + LIST_FREE_HEAD(&p->audioq, AudioFrame, free_AudioFrameListItem); + /* have we got the first audio sample to play yet */ + done = (p->audioq != NULL); + pthread_mutex_unlock(&p->audioq_lock); + if(!done) + pthread_yield(); + } + /* wait until it's time to play the first sample */ + pthread_mutex_lock(&p->audioq_lock); + next_pts = p->audioq->item.pts; + pthread_mutex_unlock(&p->audioq_lock); + next_time = base_time + ((next_pts - base_pts) * 1000000.0); + now_time = av_gettime(); + usecs = next_time - now_time; + if(usecs > 0) + thread_usleep(usecs); } else -#endif { /* wait until we have some audio frames buffered up */ do @@ -665,6 +709,27 @@ } /* + * set the base_pts and base_time values for the first video frame + * signal the values have been set via the base_cond variable + */ + +static void +set_avsync_base(MHEGStreamPlayer *p, double pts, int64_t realtime) +{ + pthread_mutex_lock(&p->base_lock); + + p->base_pts = pts; + p->base_time = realtime; + + /* tell the audio thread we have set the values */ + pthread_cond_signal(&p->base_cond); + + pthread_mutex_unlock(&p->base_lock); + + return; +} + +/* * usleep(usecs) * need to make sure the other threads get a go while we are sleeping */ Modified: redbutton-browser/trunk/MHEGStreamPlayer.h =================================================================== --- redbutton-browser/trunk/MHEGStreamPlayer.h 2006-06-13 09:05:02 UTC (rev 100) +++ redbutton-browser/trunk/MHEGStreamPlayer.h 2006-06-13 11:18:47 UTC (rev 101) @@ -68,6 +68,10 @@ pthread_t decode_tid; /* thread decoding the MPEG stream into audio/video frames */ pthread_t video_tid; /* thread displaying video frames on the screen */ pthread_t audio_tid; /* thread feeding audio frames into the sound card */ + pthread_mutex_t base_lock; /* used to sync audio and video */ + pthread_cond_t base_cond; /* the video thread tells the audio thread: */ + double base_pts; /* - the PTS of the first video frame */ + int64_t base_time; /* - the time the first video frame was displayed */ pthread_mutex_t videoq_lock; /* list of decoded video frames */ LIST_OF(VideoFrame) *videoq; /* head of list is next to be displayed */ pthread_mutex_t audioq_lock; /* list of decoded audio frames */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <ski...@us...> - 2006-06-13 09:05:14
|
Revision: 100 Author: skilvington Date: 2006-06-13 02:05:02 -0700 (Tue, 13 Jun 2006) ViewCVS: http://svn.sourceforge.net/redbutton/?rev=100&view=rev Log Message: ----------- TODO items Modified Paths: -------------- redbutton-download/trunk/TODO Modified: redbutton-download/trunk/TODO =================================================================== --- redbutton-download/trunk/TODO 2006-06-13 09:01:31 UTC (rev 99) +++ redbutton-download/trunk/TODO 2006-06-13 09:05:02 UTC (rev 100) @@ -1,3 +1,10 @@ +got an "Out of memory" error when doing avstream and video changed size +(start of C4 news) +can't see how avstream can cause an out of memory error + +Sky Teletext - can't find PIDs for tags 1 and 2 +BBC News Multiscreen - can't find default a/v PIDs + be able to read from a file have a verbose flag This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <ski...@us...> - 2006-06-13 09:01:41
|
Revision: 99 Author: skilvington Date: 2006-06-13 02:01:31 -0700 (Tue, 13 Jun 2006) ViewCVS: http://svn.sourceforge.net/redbutton/?rev=99&view=rev Log Message: ----------- missing space Modified Paths: -------------- redbutton-download/trunk/command.c Modified: redbutton-download/trunk/command.c =================================================================== --- redbutton-download/trunk/command.c 2006-06-12 18:05:47 UTC (rev 98) +++ redbutton-download/trunk/command.c 2006-06-13 09:01:31 UTC (rev 99) @@ -363,7 +363,7 @@ SEND_RESPONSE(200, "OK"); /* tell the client what PIDs and stream types the component tags resolved to */ - snprintf(hdr, sizeof(hdr), "AudioPID %u AudioType %u VideoPID %uVideoType %u\n", audio_pid, audio_type, video_pid, video_type); + snprintf(hdr, sizeof(hdr), "AudioPID %u AudioType %u VideoPID %u VideoType %u\n", audio_pid, audio_type, video_pid, video_type); fputs(hdr, client); /* shovel the transport stream down client_sock until the client closes it or we get an error */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <ski...@us...> - 2006-06-12 18:05:52
|
Revision: 98 Author: skilvington Date: 2006-06-12 11:05:47 -0700 (Mon, 12 Jun 2006) ViewCVS: http://svn.sourceforge.net/redbutton/?rev=98&view=rev Log Message: ----------- no need for rate hack Modified Paths: -------------- redbutton-browser/trunk/MHEGStreamPlayer.c Modified: redbutton-browser/trunk/MHEGStreamPlayer.c =================================================================== --- redbutton-browser/trunk/MHEGStreamPlayer.c 2006-06-12 16:18:28 UTC (rev 97) +++ redbutton-browser/trunk/MHEGStreamPlayer.c 2006-06-12 18:05:47 UTC (rev 98) @@ -628,9 +628,6 @@ verbose("MHEGStreamPlayer: audio params: format=%d rate=%d channels=%d", format, rate, channels); -/* TODO */ -/* hmmm... audio_time_base issue? */ -rate=(rate*10)/9; (void) MHEGAudioOutput_setParams(&ao, format, rate, channels); /* until we are told to stop */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <ski...@us...> - 2006-06-12 16:18:36
|
Revision: 97 Author: skilvington Date: 2006-06-12 09:18:28 -0700 (Mon, 12 Jun 2006) ViewCVS: http://svn.sourceforge.net/redbutton/?rev=97&view=rev Log Message: ----------- remove unneeded \n's Modified Paths: -------------- redbutton-browser/trunk/MHEGStreamPlayer.c Modified: redbutton-browser/trunk/MHEGStreamPlayer.c =================================================================== --- redbutton-browser/trunk/MHEGStreamPlayer.c 2006-06-12 12:36:10 UTC (rev 96) +++ redbutton-browser/trunk/MHEGStreamPlayer.c 2006-06-12 16:18:28 UTC (rev 97) @@ -263,7 +263,7 @@ fatal("Unsupported video codec"); if(avcodec_open(video_codec_ctx, codec) < 0) fatal("Unable to open video codec"); - verbose("MHEGStreamPlayer: Video: stream type=%d codec=%s\n", p->video_type, codec->name); + verbose("MHEGStreamPlayer: Video: stream type=%d codec=%s", p->video_type, codec->name); } if(p->audio_pid != -1) @@ -275,7 +275,7 @@ fatal("Unsupported audio codec"); if(avcodec_open(audio_codec_ctx, codec) < 0) fatal("Unable to open audio codec"); - verbose("MHEGStreamPlayer: Audio: stream type=%d codec=%s\n", p->audio_type, codec->name); + verbose("MHEGStreamPlayer: Audio: stream type=%d codec=%s", p->audio_type, codec->name); /* let the audio ouput thread know what the sample rate, etc are */ p->audio_codec = audio_codec_ctx; } @@ -626,7 +626,7 @@ rate = p->audio_codec->sample_rate; channels = p->audio_codec->channels; - verbose("MHEGStreamPlayer: audio params: format=%d rate=%d channels=%d\n", format, rate, channels); + verbose("MHEGStreamPlayer: audio params: format=%d rate=%d channels=%d", format, rate, channels); /* TODO */ /* hmmm... audio_time_base issue? */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <ski...@us...> - 2006-06-12 12:36:15
|
Revision: 96 Author: skilvington Date: 2006-06-12 05:36:10 -0700 (Mon, 12 Jun 2006) ViewCVS: http://svn.sourceforge.net/redbutton/?rev=96&view=rev Log Message: ----------- remove debug printf's Modified Paths: -------------- redbutton-browser/trunk/MHEGStreamPlayer.c Modified: redbutton-browser/trunk/MHEGStreamPlayer.c =================================================================== --- redbutton-browser/trunk/MHEGStreamPlayer.c 2006-06-12 12:28:12 UTC (rev 95) +++ redbutton-browser/trunk/MHEGStreamPlayer.c 2006-06-12 12:36:10 UTC (rev 96) @@ -291,13 +291,9 @@ /* get the next complete packet for one of the streams */ if(mpegts_demux_frame(tsdemux, &pkt) < 0) continue; -//if(pkt.dts == AV_NOPTS_VALUE) printf("NO DTS on PID %d!\n", pkt.stream_index); -//if(pkt.pts == AV_NOPTS_VALUE) printf("NO PTS on PID %d!\n", pkt.stream_index); -//printf("PTS=%lld DTS=%lld\n", pkt.pts, pkt.dts); /* see what stream we got a packet for */ if(pkt.stream_index == p->audio_pid && pkt.pts != AV_NOPTS_VALUE) { -//printf("decode: got audio packet\n"); pts = pkt.pts / audio_time_base; data = pkt.data; size = pkt.size; @@ -306,7 +302,6 @@ audio_frame = new_AudioFrameListItem(); af = &audio_frame->item; used = avcodec_decode_audio(audio_codec_ctx, af->data, &af->size, data, size); -//printf("decode audio: pts=%f used=%d (size=%d) audio_size=%d\n", pts, used, size, af->size); data += used; size -= used; if(af->size > 0) @@ -328,7 +323,6 @@ } else if(pkt.stream_index == p->video_pid && pkt.dts != AV_NOPTS_VALUE) { -//printf("decode: got video packet\n"); (void) avcodec_decode_video(video_codec_ctx, frame, &got_picture, pkt.data, pkt.size); if(got_picture) { @@ -337,14 +331,13 @@ pthread_mutex_lock(&p->videoq_lock); LIST_APPEND(&p->videoq, video_frame); pthread_mutex_unlock(&p->videoq_lock); -//printf("decode: got video frame: pts=%f (real pts=%f) width=%d height=%d\n", pts, pkt.pts / video_time_base, video_codec_ctx->width, video_codec_ctx->height); /* don't want one thread hogging the CPU time */ pthread_yield(); } } else { -//printf("decode: got unknown/untimed packet\n"); + verbose("MHEGStreamPlayer: decoder got unexpected/untimed packet"); } av_free_packet(&pkt); } @@ -466,10 +459,10 @@ */ drop_frame = (usecs < 0); if(drop_frame) + { verbose("MHEGStreamPlayer: dropped frame %u (usecs=%d)", nframes, usecs); -//if(drop_frame) -//printf("dropped frame %d: pts=%f last_pts=%f last_time=%lld this_time=%lld usecs=%d\n", nframes, vf->pts, last_pts, last_time, this_time, usecs); - if(!drop_frame) + } + else { /* scale the next frame if necessary */ pthread_mutex_lock(&p->video->inst.scaled_lock); @@ -499,7 +492,6 @@ { /* how many usecs do we need to wait */ usecs = this_time - now; -//printf("last_time=%lld this_time=%lld now=%lld sleep=%d\n", last_time, this_time, now, usecs); if(usecs > 0) thread_usleep(usecs); /* remember when we should have displayed this frame */ @@ -512,8 +504,6 @@ } /* remember the time stamp for this frame */ last_pts = vf->pts; -//now=av_gettime(); -//printf("display frame %d: pts=%f this_time=%lld real_time=%lld (diff=%lld)\n", nframes, vf->pts, last_time, now, now-last_time); /* origin of VideoClass */ pthread_mutex_lock(&p->video->inst.bbox_lock); out_x = p->video->inst.Position.x_position; @@ -567,8 +557,6 @@ snd_pcm_format_t format = 0; /* keep the compiler happy */ unsigned int rate; unsigned int channels; -// int64_t now; -// unsigned int nframes = 0; if(!p->have_audio) return NULL; @@ -661,8 +649,6 @@ pthread_yield(); continue; } -//now=av_gettime(); -//printf("audio: addSamples %d: pts=%f time=%lld\n", ++nframes, af->pts, now); /* TODO */ /* need to make sure pts is what we expect */ /* if we missed decoding a sample, play silence */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <ski...@us...> - 2006-06-12 12:28:20
|
Revision: 95 Author: skilvington Date: 2006-06-12 05:28:12 -0700 (Mon, 12 Jun 2006) ViewCVS: http://svn.sourceforge.net/redbutton/?rev=95&view=rev Log Message: ----------- svn version now does audio streams Modified Paths: -------------- www/index.html Modified: www/index.html =================================================================== --- www/index.html 2006-06-12 11:56:41 UTC (rev 94) +++ www/index.html 2006-06-12 12:28:12 UTC (rev 95) @@ -145,7 +145,7 @@ However, it is enough to be usable. The main things missing are video and audio streams, at the moment it'll just draw a green box where any video should be. <P> -The SVN version now does video (still no audio yet). +The SVN version now plays video and audio streams (although they are not synchronised yet). Note that it does not currently use any acceleration that your graphics card may provide so it'll drop frames in full screen mode unless you have a very fast processor (or your full screen X resolution is set to 720x576 pixels). This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <ski...@us...> - 2006-06-12 11:56:46
|
Revision: 94 Author: skilvington Date: 2006-06-12 04:56:41 -0700 (Mon, 12 Jun 2006) ViewCVS: http://svn.sourceforge.net/redbutton/?rev=94&view=rev Log Message: ----------- stop audio thread if stream ends during initial buffering Modified Paths: -------------- redbutton-browser/trunk/MHEGStreamPlayer.c redbutton-browser/trunk/MHEGStreamPlayer.h Modified: redbutton-browser/trunk/MHEGStreamPlayer.c =================================================================== --- redbutton-browser/trunk/MHEGStreamPlayer.c 2006-06-12 11:04:50 UTC (rev 93) +++ redbutton-browser/trunk/MHEGStreamPlayer.c 2006-06-12 11:56:41 UTC (rev 94) @@ -616,6 +616,10 @@ pthread_mutex_unlock(&p->audioq_lock); } + /* do we need to bomb out early */ + if(p->stop) + return NULL; + /* even if this fails, we still need to consume the audioq */ (void) MHEGAudioOutput_init(&ao); Modified: redbutton-browser/trunk/MHEGStreamPlayer.h =================================================================== --- redbutton-browser/trunk/MHEGStreamPlayer.h 2006-06-12 11:04:50 UTC (rev 93) +++ redbutton-browser/trunk/MHEGStreamPlayer.h 2006-06-12 11:56:41 UTC (rev 94) @@ -17,8 +17,7 @@ #define INIT_VIDEO_BUFFER_WAIT 1.0 /* seconds of audio to buffer before we start playing it (only used if we have no video) */ -//#define INIT_AUDIO_BUFFER_WAIT 1.0 -#define INIT_AUDIO_BUFFER_WAIT 0.5 +#define INIT_AUDIO_BUFFER_WAIT 1.0 /* list of decoded video frames to be displayed */ typedef struct This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <ski...@us...> - 2006-06-12 11:04:59
|
Revision: 93 Author: skilvington Date: 2006-06-12 04:04:50 -0700 (Mon, 12 Jun 2006) ViewCVS: http://svn.sourceforge.net/redbutton/?rev=93&view=rev Log Message: ----------- add audio output (not sync'ed with video yet) Modified Paths: -------------- redbutton-browser/trunk/MHEGStreamPlayer.c redbutton-browser/trunk/MHEGStreamPlayer.h Modified: redbutton-browser/trunk/MHEGStreamPlayer.c =================================================================== --- redbutton-browser/trunk/MHEGStreamPlayer.c 2006-06-11 09:05:19 UTC (rev 92) +++ redbutton-browser/trunk/MHEGStreamPlayer.c 2006-06-12 11:04:50 UTC (rev 93) @@ -9,12 +9,14 @@ #include "MHEGEngine.h" #include "MHEGStreamPlayer.h" #include "MHEGVideoOutput.h" +#include "MHEGAudioOutput.h" #include "mpegts.h" #include "utils.h" /* internal routines */ static void *decode_thread(void *); static void *video_thread(void *); +static void *audio_thread(void *); static void thread_usleep(unsigned long); static enum CodecID find_av_codec_id(int); @@ -87,6 +89,8 @@ p->video = NULL; p->audio = NULL; + p->audio_codec = NULL; + pthread_mutex_init(&p->videoq_lock, NULL); p->videoq = NULL; @@ -163,9 +167,10 @@ p->stop = false; /* - * we have two threads: - * decode_thread reads MPEG data from the TS and decodes it into YUV video frames + * we have three threads: + * decode_thread reads MPEG data from the TS and decodes it into YUV video frames and audio samples * video_thread takes YUV frames off the videoq list, converts them to RGB and displays them on the screen + * audio_thread takes audio samples off the audioq list and feeds them into the sound card */ if(pthread_create(&p->decode_tid, NULL, decode_thread, p) != 0) fatal("Unable to create MPEG decoder thread"); @@ -173,6 +178,9 @@ if(pthread_create(&p->video_tid, NULL, video_thread, p) != 0) fatal("Unable to create video output thread"); + if(pthread_create(&p->audio_tid, NULL, audio_thread, p) != 0) + fatal("Unable to create audio output thread"); + //{ // whole machine locks up if you do this // struct sched_param sp = {1}; @@ -198,6 +206,7 @@ /* wait for them to finish */ pthread_join(p->decode_tid, NULL); pthread_join(p->video_tid, NULL); + pthread_join(p->audio_tid, NULL); /* clean up */ LIST_FREE(&p->videoq, VideoFrame, free_VideoFrameListItem); @@ -217,8 +226,8 @@ /* * decode_thread * reads the MPEG TS file - * decodes the data into YUV video frames - * adds them to the tail of the videoq list + * decodes the data into YUV video frames and audio samples + * adds them to the tail of the videoq and audioq lists */ static void * @@ -267,6 +276,8 @@ if(avcodec_open(audio_codec_ctx, codec) < 0) fatal("Unable to open audio codec"); verbose("MHEGStreamPlayer: Audio: stream type=%d codec=%s\n", p->audio_type, codec->name); + /* let the audio ouput thread know what the sample rate, etc are */ + p->audio_codec = audio_codec_ctx; } if((frame = avcodec_alloc_frame()) == NULL) @@ -286,7 +297,6 @@ /* see what stream we got a packet for */ if(pkt.stream_index == p->audio_pid && pkt.pts != AV_NOPTS_VALUE) { -#if 0 //printf("decode: got audio packet\n"); pts = pkt.pts / audio_time_base; data = pkt.data; @@ -315,7 +325,6 @@ } /* don't want one thread hogging the CPU time */ pthread_yield(); -#endif } else if(pkt.stream_index == p->video_pid && pkt.dts != AV_NOPTS_VALUE) { @@ -399,7 +408,7 @@ else buffered = 0.0; pthread_mutex_unlock(&p->videoq_lock); - verbose("MHEGStreamPlayer: buffered %f seconds", buffered); + verbose("MHEGStreamPlayer: buffered %f seconds of video", buffered); /* let the decoder have a go */ if(buffered < INIT_VIDEO_BUFFER_WAIT) pthread_yield(); @@ -541,6 +550,134 @@ } /* + * audio thread + * takes audio samples of the audioq and feeds them into the sound card as fast as possible + * MHEGAudioOuput_addSamples() will block while the sound card buffer is full + */ + +static void * +audio_thread(void *arg) +{ + MHEGStreamPlayer *p = (MHEGStreamPlayer *) arg; + MHEGAudioOutput ao; + AudioFrame *af; + double buffered; + double base_pts; + int64_t base_time; + snd_pcm_format_t format = 0; /* keep the compiler happy */ + unsigned int rate; + unsigned int channels; +// int64_t now; +// unsigned int nframes = 0; + + if(!p->have_audio) + return NULL; + + verbose("MHEGStreamPlayer: audio thread started"); + + /* assert */ + if(p->audio == NULL) + fatal("audio_thread: AudioClass is NULL"); + + /* do we need to sync the audio with the video */ +#if 0 + if(p->have_video) + { + /* wait until the video thread tells us it has some frames buffered up */ +/* TODO */ + /* get the video's first PTS and first actual time stamp values */ +/* TODO */ +/* video thread should set base_pts and base_time from the values for the first frame it displays */ + base_time = p->base_time; + base_pts = p->base_pts; + } + else +#endif + { + /* wait until we have some audio frames buffered up */ + do + { + pthread_mutex_lock(&p->audioq_lock); + if(p->audioq != NULL) + buffered = p->audioq->prev->item.pts - p->audioq->item.pts; + else + buffered = 0.0; + pthread_mutex_unlock(&p->audioq_lock); + verbose("MHEGStreamPlayer: buffered %f seconds of audio", buffered); + /* let the decoder have a go */ + if(buffered < INIT_AUDIO_BUFFER_WAIT) + pthread_yield(); + } + while(!p->stop && buffered < INIT_AUDIO_BUFFER_WAIT); + /* the time that we played the first frame */ + base_time = av_gettime(); + pthread_mutex_lock(&p->audioq_lock); + base_pts = p->audioq->item.pts; + pthread_mutex_unlock(&p->audioq_lock); + } + + /* even if this fails, we still need to consume the audioq */ + (void) MHEGAudioOutput_init(&ao); + + /* assert - if audioq is not empty then the codec cannot be NULL */ + if(p->audio_codec == NULL) + fatal("audio_codec is NULL"); + + /* TODO will these be big endian on a big endian machine? */ + if(p->audio_codec->sample_fmt == SAMPLE_FMT_S16) + format = SND_PCM_FORMAT_S16_LE; + else if(p->audio_codec->sample_fmt == SAMPLE_FMT_S32) + format = SND_PCM_FORMAT_S32_LE; + else + fatal("Unsupported audio sample format (%d)", p->audio_codec->sample_fmt); + + rate = p->audio_codec->sample_rate; + channels = p->audio_codec->channels; + + verbose("MHEGStreamPlayer: audio params: format=%d rate=%d channels=%d\n", format, rate, channels); + +/* TODO */ +/* hmmm... audio_time_base issue? */ +rate=(rate*10)/9; + (void) MHEGAudioOutput_setParams(&ao, format, rate, channels); + + /* until we are told to stop */ + while(!p->stop) + { + /* get the next audio frame */ + pthread_mutex_lock(&p->audioq_lock); + af = (p->audioq != NULL) ? &p->audioq->item : NULL; + /* only we delete items from the audioq, so af will stay valid */ + pthread_mutex_unlock(&p->audioq_lock); + if(af == NULL) + { + /* if audio init failed, we will get this a lot */ +// verbose("MHEGStreamPlayer: audioq is empty"); + /* give the decoder a bit of time to catch up */ + pthread_yield(); + continue; + } +//now=av_gettime(); +//printf("audio: addSamples %d: pts=%f time=%lld\n", ++nframes, af->pts, now); +/* TODO */ +/* need to make sure pts is what we expect */ +/* if we missed decoding a sample, play silence */ + /* this will block until the sound card can take the data */ + MHEGAudioOutput_addSamples(&ao, af->data, af->size); + /* we can delete the frame from the queue now */ + pthread_mutex_lock(&p->audioq_lock); + LIST_FREE_HEAD(&p->audioq, AudioFrame, free_AudioFrameListItem); + pthread_mutex_unlock(&p->audioq_lock); + } + + MHEGAudioOutput_fini(&ao); + + verbose("MHEGStreamPlayer: audio thread stopped"); + + return NULL; +} + +/* * usleep(usecs) * need to make sure the other threads get a go while we are sleeping */ Modified: redbutton-browser/trunk/MHEGStreamPlayer.h =================================================================== --- redbutton-browser/trunk/MHEGStreamPlayer.h 2006-06-11 09:05:19 UTC (rev 92) +++ redbutton-browser/trunk/MHEGStreamPlayer.h 2006-06-12 11:04:50 UTC (rev 93) @@ -16,6 +16,10 @@ /* seconds of video to buffer before we start playing it */ #define INIT_VIDEO_BUFFER_WAIT 1.0 +/* seconds of audio to buffer before we start playing it (only used if we have no video) */ +//#define INIT_AUDIO_BUFFER_WAIT 1.0 +#define INIT_AUDIO_BUFFER_WAIT 0.5 + /* list of decoded video frames to be displayed */ typedef struct { @@ -60,12 +64,14 @@ int audio_tag; /* audio stream component tag (-1 => default for current service ID) */ int audio_pid; /* PID in MPEG Transport Stream (-1 => not yet known) */ int audio_type; /* audio stream type (-1 => not yet known) */ + AVCodecContext *audio_codec; /* audio ouput params */ FILE *ts; /* MPEG Transport Stream */ - pthread_t decode_tid; /* thread decoding the MPEG stream into frames */ - pthread_t video_tid; /* thread displaying frames on the screen */ + pthread_t decode_tid; /* thread decoding the MPEG stream into audio/video frames */ + pthread_t video_tid; /* thread displaying video frames on the screen */ + pthread_t audio_tid; /* thread feeding audio frames into the sound card */ pthread_mutex_t videoq_lock; /* list of decoded video frames */ LIST_OF(VideoFrame) *videoq; /* head of list is next to be displayed */ - pthread_mutex_t audioq_lock; /* list of decoded audio samples */ + pthread_mutex_t audioq_lock; /* list of decoded audio frames */ LIST_OF(AudioFrame) *audioq; /* head of list is next to be played */ } MHEGStreamPlayer; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <ski...@us...> - 2006-06-11 09:05:36
|
Revision: 92 Author: skilvington Date: 2006-06-11 02:05:19 -0700 (Sun, 11 Jun 2006) ViewCVS: http://svn.sourceforge.net/redbutton/?rev=92&view=rev Log Message: ----------- add ALSA audio output method (still doesn't play sound yet) Modified Paths: -------------- redbutton-browser/trunk/Makefile Added Paths: ----------- redbutton-browser/trunk/MHEGAudioOutput.c redbutton-browser/trunk/MHEGAudioOutput.h Added: redbutton-browser/trunk/MHEGAudioOutput.c =================================================================== --- redbutton-browser/trunk/MHEGAudioOutput.c (rev 0) +++ redbutton-browser/trunk/MHEGAudioOutput.c 2006-06-11 09:05:19 UTC (rev 92) @@ -0,0 +1,120 @@ +/* + * MHEGAudioOutput.c + */ + +#include <stdbool.h> +#include <stdint.h> +#include <stdio.h> +#include <alsa/asoundlib.h> + +#include "MHEGAudioOutput.h" +#include "MHEGEngine.h" +#include "utils.h" + +bool +MHEGAudioOutput_init(MHEGAudioOutput *a) +{ + int err; + + a->ctx = NULL; + + if((err = snd_pcm_open(&a->ctx, ALSA_AUDIO_DEVICE, SND_PCM_STREAM_PLAYBACK, 0)) < 0) + { + error("Unable to open audio device '%s': %s", ALSA_AUDIO_DEVICE, snd_strerror(err)); + return false; + } + + return true; +} + +void +MHEGAudioOutput_fini(MHEGAudioOutput *a) +{ + if(a->ctx != NULL) + { + snd_pcm_close(a->ctx); + a->ctx = NULL; + } + + return; +} + +bool +MHEGAudioOutput_setParams(MHEGAudioOutput *a, snd_pcm_format_t format, unsigned int rate, unsigned int channels) +{ + snd_pcm_hw_params_t *hw_params; + int err; + int dir; + + if(a->ctx == NULL) + return false; + + if((err = snd_pcm_hw_params_malloc(&hw_params)) < 0) + { + error("Unable to set audio parameters: %s", snd_strerror(err)); + return false; + } + + if((err = snd_pcm_hw_params_any(a->ctx, hw_params)) < 0) + { + error("Unable to set audio parameters: %s", snd_strerror(err)); + return false; + } + + /* interleaved samples */ + if((err = snd_pcm_hw_params_set_access(a->ctx, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) + { + error("Unable to set audio parameters: %s", snd_strerror(err)); + return false; + } + + if((err = snd_pcm_hw_params_set_format(a->ctx, hw_params, format)) < 0) + { + error("Unable to set audio parameters: %s", snd_strerror(err)); + return false; + } + + if((err = snd_pcm_hw_params_set_rate_near(a->ctx, hw_params, &rate, &dir)) < 0) + { + error("Unable to set audio parameters: %s", snd_strerror(err)); + return false; + } + + if((err = snd_pcm_hw_params_set_channels(a->ctx, hw_params, channels)) < 0) + { + error("Unable to set audio parameters: %s", snd_strerror(err)); + return false; + } + + if((err = snd_pcm_hw_params(a->ctx, hw_params)) < 0) + { + error("Unable to set audio parameters: %s", snd_strerror(err)); + return false; + } + + snd_pcm_hw_params_free(hw_params); + + return true; +} + +void +MHEGAudioOutput_addSamples(MHEGAudioOutput *a, uint16_t *samples, unsigned int nbytes) +{ + unsigned int nsamples; + + if(a->ctx == NULL) + return; + + /* convert bytes to samples */ + nsamples = snd_pcm_bytes_to_frames(a->ctx, nbytes); + + /* interleaved samples */ + while(snd_pcm_writei(a->ctx, samples, nsamples) < 0) + { + snd_pcm_prepare(a->ctx); + verbose("MHEGAudioOutput: buffer underrun"); + } + + return; +} + Added: redbutton-browser/trunk/MHEGAudioOutput.h =================================================================== --- redbutton-browser/trunk/MHEGAudioOutput.h (rev 0) +++ redbutton-browser/trunk/MHEGAudioOutput.h 2006-06-11 09:05:19 UTC (rev 92) @@ -0,0 +1,27 @@ +/* + * MHEGAudioOutput.h + */ + +#include <stdbool.h> +#include <stdint.h> +#include <alsa/asoundlib.h> + +#ifndef __MHEGAUDIOOUTPUT_H__ +#define __MHEGAUDIOOUTPUT_H__ + +typedef struct +{ + snd_pcm_t *ctx; +} MHEGAudioOutput; + +/* default ALSA device */ +#define ALSA_AUDIO_DEVICE "plughw" + +bool MHEGAudioOutput_init(MHEGAudioOutput *); +void MHEGAudioOutput_fini(MHEGAudioOutput *); + +bool MHEGAudioOutput_setParams(MHEGAudioOutput *, snd_pcm_format_t, unsigned int, unsigned int); + +void MHEGAudioOutput_addSamples(MHEGAudioOutput *, uint16_t *, unsigned int); + +#endif /* __MHEGAUDIOOUTPUT_H__ */ Modified: redbutton-browser/trunk/Makefile =================================================================== --- redbutton-browser/trunk/Makefile 2006-06-09 15:25:30 UTC (rev 91) +++ redbutton-browser/trunk/Makefile 2006-06-11 09:05:19 UTC (rev 92) @@ -4,7 +4,7 @@ DEFS=-D_REENTRANT -D_GNU_SOURCE #DEFS=-DDEBUG_ALLOC -D_REENTRANT -D_GNU_SOURCE INCS=`freetype-config --cflags` -LIBS=-lm -lz -L/usr/X11R6/lib -lX11 -lXt -lXrender -lXft -lpng -lmpeg2 -lmpeg2convert -lavformat -lavcodec -lpthread +LIBS=-lm -lz -L/usr/X11R6/lib -lX11 -lXt -lXrender -lXft -lpng -lmpeg2 -lmpeg2convert -lavformat -lavcodec -lasound -lpthread CLASSES=ActionClass.o \ ApplicationClass.o \ @@ -67,6 +67,7 @@ MHEGTimer.o \ MHEGStreamPlayer.o \ MHEGVideoOutput.o \ + MHEGAudioOutput.o \ ${CLASSES} \ ISO13522-MHEG-5.o \ der_decode.o \ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <ski...@us...> - 2006-06-09 15:25:44
|
Revision: 91 Author: skilvington Date: 2006-06-09 08:25:30 -0700 (Fri, 09 Jun 2006) ViewCVS: http://svn.sourceforge.net/redbutton/?rev=91&view=rev Log Message: ----------- rationalise includes Modified Paths: -------------- redbutton-browser/trunk/MHEGStreamPlayer.c redbutton-browser/trunk/MHEGStreamPlayer.h redbutton-browser/trunk/MHEGVideoOutput.h Modified: redbutton-browser/trunk/MHEGStreamPlayer.c =================================================================== --- redbutton-browser/trunk/MHEGStreamPlayer.c 2006-06-08 11:35:12 UTC (rev 90) +++ redbutton-browser/trunk/MHEGStreamPlayer.c 2006-06-09 15:25:30 UTC (rev 91) @@ -5,7 +5,6 @@ #include <string.h> #include <stdio.h> #include <X11/Xlib.h> -#include <X11/extensions/XShm.h> #include "MHEGEngine.h" #include "MHEGStreamPlayer.h" Modified: redbutton-browser/trunk/MHEGStreamPlayer.h =================================================================== --- redbutton-browser/trunk/MHEGStreamPlayer.h 2006-06-08 11:35:12 UTC (rev 90) +++ redbutton-browser/trunk/MHEGStreamPlayer.h 2006-06-09 15:25:30 UTC (rev 91) @@ -5,9 +5,9 @@ #ifndef __MHEGSTREAMPLAYER_H__ #define __MHEGSTREAMPLAYER_H__ +#include <stdint.h> #include <stdbool.h> #include <pthread.h> -#include <X11/Xlib.h> #include <ffmpeg/avformat.h> #include <ffmpeg/avcodec.h> Modified: redbutton-browser/trunk/MHEGVideoOutput.h =================================================================== --- redbutton-browser/trunk/MHEGVideoOutput.h 2006-06-08 11:35:12 UTC (rev 90) +++ redbutton-browser/trunk/MHEGVideoOutput.h 2006-06-09 15:25:30 UTC (rev 91) @@ -5,6 +5,11 @@ #ifndef __MHEGVIDEOOUTPUT_H__ #define __MHEGVIDEOOUTPUT_H__ +#include <stdint.h> +#include <X11/Xlib.h> +#include <X11/extensions/XShm.h> +#include <ffmpeg/avcodec.h> + typedef struct { unsigned int width; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <ski...@us...> - 2006-06-08 11:46:08
|
Revision: 89 Author: skilvington Date: 2006-06-08 04:01:51 -0700 (Thu, 08 Jun 2006) ViewCVS: http://svn.sourceforge.net/redbutton/?rev=89&view=rev Log Message: ----------- finally get audio PTS correct Modified Paths: -------------- redbutton-browser/trunk/MHEGStreamPlayer.c Modified: redbutton-browser/trunk/MHEGStreamPlayer.c =================================================================== --- redbutton-browser/trunk/MHEGStreamPlayer.c 2006-06-08 09:25:27 UTC (rev 88) +++ redbutton-browser/trunk/MHEGStreamPlayer.c 2006-06-08 11:01:51 UTC (rev 89) @@ -291,7 +291,7 @@ { #if 0 //printf("decode: got audio packet\n"); - pts = pkt.pts; + pts = pkt.pts / audio_time_base; data = pkt.data; size = pkt.size; while(size > 0) @@ -299,13 +299,14 @@ audio_frame = new_AudioFrameListItem(); af = &audio_frame->item; used = avcodec_decode_audio(audio_codec_ctx, af->data, &af->size, data, size); -//printf("decode audio: pts=%f used=%d (size=%d) audio_size=%d\n", pts / audio_time_base, used, size, af->size); +//printf("decode audio: pts=%f used=%d (size=%d) audio_size=%d\n", pts, used, size, af->size); data += used; size -= used; if(af->size > 0) { - pts += (af->size * 1000.0) / ((audio_codec_ctx->channels * 2) * audio_codec_ctx->sample_rate); - af->pts = pts / audio_time_base; + af->pts = pts; + /* 16-bit samples, but af->size is in bytes */ + pts += (af->size / 2.0) / (audio_codec_ctx->channels * audio_codec_ctx->sample_rate); pthread_mutex_lock(&p->audioq_lock); LIST_APPEND(&p->audioq, audio_frame); pthread_mutex_unlock(&p->audioq_lock); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <ski...@us...> - 2006-06-08 11:35:26
|
Revision: 90 Author: skilvington Date: 2006-06-08 04:35:12 -0700 (Thu, 08 Jun 2006) ViewCVS: http://svn.sourceforge.net/redbutton/?rev=90&view=rev Log Message: ----------- don't need to keep track of length of videoq Modified Paths: -------------- redbutton-browser/trunk/MHEGStreamPlayer.c redbutton-browser/trunk/MHEGStreamPlayer.h Modified: redbutton-browser/trunk/MHEGStreamPlayer.c =================================================================== --- redbutton-browser/trunk/MHEGStreamPlayer.c 2006-06-08 11:01:51 UTC (rev 89) +++ redbutton-browser/trunk/MHEGStreamPlayer.c 2006-06-08 11:35:12 UTC (rev 90) @@ -89,7 +89,6 @@ p->audio = NULL; pthread_mutex_init(&p->videoq_lock, NULL); - p->videoq_len = 0; p->videoq = NULL; pthread_mutex_init(&p->audioq_lock, NULL); @@ -202,7 +201,6 @@ pthread_join(p->video_tid, NULL); /* clean up */ - p->videoq_len = 0; LIST_FREE(&p->videoq, VideoFrame, free_VideoFrameListItem); LIST_FREE(&p->audioq, AudioFrame, free_AudioFrameListItem); @@ -329,9 +327,7 @@ pts = pkt.dts / video_time_base; video_frame = new_VideoFrameListItem(pts, video_codec_ctx->pix_fmt, video_codec_ctx->width, video_codec_ctx->height, frame); pthread_mutex_lock(&p->videoq_lock); - p->videoq_len ++; LIST_APPEND(&p->videoq, video_frame); -//printf("decode_thread: add frame: len=%u\n", p->videoq_len); pthread_mutex_unlock(&p->videoq_lock); //printf("decode: got video frame: pts=%f (real pts=%f) width=%d height=%d\n", pts, pkt.pts / video_time_base, video_codec_ctx->width, video_codec_ctx->height); /* don't want one thread hogging the CPU time */ @@ -532,11 +528,6 @@ } /* we can delete the frame from the queue now */ pthread_mutex_lock(&p->videoq_lock); -//printf("video_thread: free frame: len=%u\n", p->videoq_len); - /* assert */ - if(p->videoq_len == 0) - fatal("video_thread: videoq_len is 0"); - p->videoq_len --; LIST_FREE_HEAD(&p->videoq, VideoFrame, free_VideoFrameListItem); pthread_mutex_unlock(&p->videoq_lock); /* don't want one thread hogging the CPU time */ Modified: redbutton-browser/trunk/MHEGStreamPlayer.h =================================================================== --- redbutton-browser/trunk/MHEGStreamPlayer.h 2006-06-08 11:01:51 UTC (rev 89) +++ redbutton-browser/trunk/MHEGStreamPlayer.h 2006-06-08 11:35:12 UTC (rev 90) @@ -64,7 +64,6 @@ pthread_t decode_tid; /* thread decoding the MPEG stream into frames */ pthread_t video_tid; /* thread displaying frames on the screen */ pthread_mutex_t videoq_lock; /* list of decoded video frames */ - unsigned int videoq_len; /* number of frames on the videoq */ LIST_OF(VideoFrame) *videoq; /* head of list is next to be displayed */ pthread_mutex_t audioq_lock; /* list of decoded audio samples */ LIST_OF(AudioFrame) *audioq; /* head of list is next to be played */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <ski...@us...> - 2006-06-08 11:07:19
|
Revision: 88 Author: skilvington Date: 2006-06-08 02:25:27 -0700 (Thu, 08 Jun 2006) ViewCVS: http://svn.sourceforge.net/redbutton/?rev=88&view=rev Log Message: ----------- free audioq on stop Modified Paths: -------------- redbutton-browser/trunk/MHEGStreamPlayer.c Modified: redbutton-browser/trunk/MHEGStreamPlayer.c =================================================================== --- redbutton-browser/trunk/MHEGStreamPlayer.c 2006-06-07 16:09:27 UTC (rev 87) +++ redbutton-browser/trunk/MHEGStreamPlayer.c 2006-06-08 09:25:27 UTC (rev 88) @@ -204,6 +204,7 @@ /* clean up */ p->videoq_len = 0; LIST_FREE(&p->videoq, VideoFrame, free_VideoFrameListItem); + LIST_FREE(&p->audioq, AudioFrame, free_AudioFrameListItem); if(p->ts != NULL) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <ski...@us...> - 2006-06-08 02:43:32
|
Revision: 87 Author: skilvington Date: 2006-06-07 09:09:27 -0700 (Wed, 07 Jun 2006) ViewCVS: http://svn.sourceforge.net/redbutton/?rev=87&view=rev Log Message: ----------- avoid unnecessary memcpy when decoding audio Modified Paths: -------------- redbutton-browser/trunk/MHEGStreamPlayer.c redbutton-browser/trunk/MHEGStreamPlayer.h Modified: redbutton-browser/trunk/MHEGStreamPlayer.c =================================================================== --- redbutton-browser/trunk/MHEGStreamPlayer.c 2006-06-02 15:38:18 UTC (rev 86) +++ redbutton-browser/trunk/MHEGStreamPlayer.c 2006-06-07 16:09:27 UTC (rev 87) @@ -54,7 +54,27 @@ return; } +LIST_TYPE(AudioFrame) * +new_AudioFrameListItem(void) +{ + LIST_TYPE(AudioFrame) *af = safe_malloc(sizeof(LIST_TYPE(AudioFrame))); + + af->item.pts = AV_NOPTS_VALUE; + + af->item.size = 0; + + return af; +} + void +free_AudioFrameListItem(LIST_TYPE(AudioFrame) *af) +{ + safe_free(af); + + return; +} + +void MHEGStreamPlayer_init(MHEGStreamPlayer *p) { bzero(p, sizeof(MHEGStreamPlayer)); @@ -72,6 +92,9 @@ p->videoq_len = 0; p->videoq = NULL; + pthread_mutex_init(&p->audioq_lock, NULL); + p->audioq = NULL; + return; } @@ -81,6 +104,7 @@ MHEGStreamPlayer_stop(p); pthread_mutex_destroy(&p->videoq_lock); + pthread_mutex_destroy(&p->audioq_lock); return; } @@ -215,8 +239,8 @@ AVFrame *frame; LIST_TYPE(VideoFrame) *video_frame; int got_picture; - uint16_t audio_data[AVCODEC_MAX_AUDIO_FRAME_SIZE]; - int audio_size; + LIST_TYPE(AudioFrame) *audio_frame; + AudioFrame *af; int used; unsigned char *data; int size; @@ -264,27 +288,35 @@ /* see what stream we got a packet for */ if(pkt.stream_index == p->audio_pid && pkt.pts != AV_NOPTS_VALUE) { +#if 0 //printf("decode: got audio packet\n"); pts = pkt.pts; data = pkt.data; size = pkt.size; while(size > 0) { - used = avcodec_decode_audio(audio_codec_ctx, audio_data, &audio_size, data, size); -//printf("decode audio: pts=%f used=%d (size=%d) audio_size=%d\n", pts / audio_time_base, used, size, audio_size); + audio_frame = new_AudioFrameListItem(); + af = &audio_frame->item; + used = avcodec_decode_audio(audio_codec_ctx, af->data, &af->size, data, size); +//printf("decode audio: pts=%f used=%d (size=%d) audio_size=%d\n", pts / audio_time_base, used, size, af->size); data += used; size -= used; - if(audio_size > 0) + if(af->size > 0) { - pts += (audio_size * 1000.0) / ((audio_codec_ctx->channels * 2) * audio_codec_ctx->sample_rate); -// audio_frame = new_AudioFrameListItem(pts / audio_time_base, audio_data, audio_size); -// pthread_mutex_lock(&opts->audioq_lock); -// LIST_APPEND(&opts->audioq, audio_frame); -// pthread_mutex_unlock(&opts->audioq_lock); + pts += (af->size * 1000.0) / ((audio_codec_ctx->channels * 2) * audio_codec_ctx->sample_rate); + af->pts = pts / audio_time_base; + pthread_mutex_lock(&p->audioq_lock); + LIST_APPEND(&p->audioq, audio_frame); + pthread_mutex_unlock(&p->audioq_lock); } + else + { + free_AudioFrameListItem(audio_frame); + } } /* don't want one thread hogging the CPU time */ pthread_yield(); +#endif } else if(pkt.stream_index == p->video_pid && pkt.dts != AV_NOPTS_VALUE) { Modified: redbutton-browser/trunk/MHEGStreamPlayer.h =================================================================== --- redbutton-browser/trunk/MHEGStreamPlayer.h 2006-06-02 15:38:18 UTC (rev 86) +++ redbutton-browser/trunk/MHEGStreamPlayer.h 2006-06-07 16:09:27 UTC (rev 87) @@ -32,6 +32,19 @@ LIST_TYPE(VideoFrame) *new_VideoFrameListItem(double, enum PixelFormat, unsigned int, unsigned int, AVFrame *); void free_VideoFrameListItem(LIST_TYPE(VideoFrame) *); +/* list of decoded audio samples to play */ +typedef struct +{ + double pts; /* presentation time stamp */ + unsigned int size; /* size of data in bytes (not uint16_t's) */ + uint16_t data[AVCODEC_MAX_AUDIO_FRAME_SIZE]; +} AudioFrame; + +DEFINE_LIST_OF(AudioFrame); + +LIST_TYPE(AudioFrame) *new_AudioFrameListItem(void); +void free_AudioFrameListItem(LIST_TYPE(AudioFrame) *); + /* player state */ typedef struct { @@ -53,6 +66,8 @@ pthread_mutex_t videoq_lock; /* list of decoded video frames */ unsigned int videoq_len; /* number of frames on the videoq */ LIST_OF(VideoFrame) *videoq; /* head of list is next to be displayed */ + pthread_mutex_t audioq_lock; /* list of decoded audio samples */ + LIST_OF(AudioFrame) *audioq; /* head of list is next to be played */ } MHEGStreamPlayer; void MHEGStreamPlayer_init(MHEGStreamPlayer *); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <ski...@us...> - 2006-06-02 15:38:23
|
Revision: 86 Author: skilvington Date: 2006-06-02 08:38:18 -0700 (Fri, 02 Jun 2006) ViewCVS: http://svn.sourceforge.net/redbutton/?rev=86&view=rev Log Message: ----------- make the audio PTS maths a bit clearer Modified Paths: -------------- redbutton-browser/trunk/MHEGStreamPlayer.c Modified: redbutton-browser/trunk/MHEGStreamPlayer.c =================================================================== --- redbutton-browser/trunk/MHEGStreamPlayer.c 2006-06-02 15:29:30 UTC (rev 85) +++ redbutton-browser/trunk/MHEGStreamPlayer.c 2006-06-02 15:38:18 UTC (rev 86) @@ -276,7 +276,7 @@ size -= used; if(audio_size > 0) { - pts += ((audio_size * 1000.0) / (audio_codec_ctx->channels * 2) / audio_codec_ctx->sample_rate); + pts += (audio_size * 1000.0) / ((audio_codec_ctx->channels * 2) * audio_codec_ctx->sample_rate); // audio_frame = new_AudioFrameListItem(pts / audio_time_base, audio_data, audio_size); // pthread_mutex_lock(&opts->audioq_lock); // LIST_APPEND(&opts->audioq, audio_frame); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <ski...@us...> - 2006-06-02 15:29:40
|
Revision: 85 Author: skilvington Date: 2006-06-02 08:29:30 -0700 (Fri, 02 Jun 2006) ViewCVS: http://svn.sourceforge.net/redbutton/?rev=85&view=rev Log Message: ----------- decode audio (doesn't play it yet) Modified Paths: -------------- redbutton-browser/trunk/MHEGStreamPlayer.c Modified: redbutton-browser/trunk/MHEGStreamPlayer.c =================================================================== --- redbutton-browser/trunk/MHEGStreamPlayer.c 2006-06-02 11:01:46 UTC (rev 84) +++ redbutton-browser/trunk/MHEGStreamPlayer.c 2006-06-02 15:29:30 UTC (rev 85) @@ -210,10 +210,16 @@ enum CodecID codec_id; AVCodec *codec = NULL; double video_time_base = 90000.0; + double audio_time_base = 90000.0; double pts; AVFrame *frame; LIST_TYPE(VideoFrame) *video_frame; int got_picture; + uint16_t audio_data[AVCODEC_MAX_AUDIO_FRAME_SIZE]; + int audio_size; + int used; + unsigned char *data; + int size; verbose("MHEGStreamPlayer: decode thread started"); @@ -256,9 +262,29 @@ //if(pkt.pts == AV_NOPTS_VALUE) printf("NO PTS on PID %d!\n", pkt.stream_index); //printf("PTS=%lld DTS=%lld\n", pkt.pts, pkt.dts); /* see what stream we got a packet for */ - if(pkt.stream_index == p->audio_pid && pkt.dts != AV_NOPTS_VALUE) + if(pkt.stream_index == p->audio_pid && pkt.pts != AV_NOPTS_VALUE) { //printf("decode: got audio packet\n"); + pts = pkt.pts; + data = pkt.data; + size = pkt.size; + while(size > 0) + { + used = avcodec_decode_audio(audio_codec_ctx, audio_data, &audio_size, data, size); +//printf("decode audio: pts=%f used=%d (size=%d) audio_size=%d\n", pts / audio_time_base, used, size, audio_size); + data += used; + size -= used; + if(audio_size > 0) + { + pts += ((audio_size * 1000.0) / (audio_codec_ctx->channels * 2) / audio_codec_ctx->sample_rate); +// audio_frame = new_AudioFrameListItem(pts / audio_time_base, audio_data, audio_size); +// pthread_mutex_lock(&opts->audioq_lock); +// LIST_APPEND(&opts->audioq, audio_frame); +// pthread_mutex_unlock(&opts->audioq_lock); + } + } + /* don't want one thread hogging the CPU time */ + pthread_yield(); } else if(pkt.stream_index == p->video_pid && pkt.dts != AV_NOPTS_VALUE) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <ski...@us...> - 2006-06-02 11:01:54
|
Revision: 84 Author: skilvington Date: 2006-06-02 04:01:46 -0700 (Fri, 02 Jun 2006) ViewCVS: http://svn.sourceforge.net/redbutton/?rev=84&view=rev Log Message: ----------- pass the AudioClass to the stream player Modified Paths: -------------- redbutton-browser/trunk/MHEGStreamPlayer.c redbutton-browser/trunk/MHEGStreamPlayer.h redbutton-browser/trunk/StreamComponent.c Modified: redbutton-browser/trunk/MHEGStreamPlayer.c =================================================================== --- redbutton-browser/trunk/MHEGStreamPlayer.c 2006-05-31 13:35:40 UTC (rev 83) +++ redbutton-browser/trunk/MHEGStreamPlayer.c 2006-06-02 11:01:46 UTC (rev 84) @@ -66,6 +66,7 @@ p->have_audio = false; p->video = NULL; + p->audio = NULL; pthread_mutex_init(&p->videoq_lock, NULL); p->videoq_len = 0; @@ -85,30 +86,37 @@ } void -MHEGStreamPlayer_setVideoTag(MHEGStreamPlayer *p, VideoClass *video, int tag) +MHEGStreamPlayer_setVideoStream(MHEGStreamPlayer *p, VideoClass *video) { if(p->have_video) - error("MHEGStreamPlayer: more than one video stream; only using the last one (%d)", tag); + error("MHEGStreamPlayer: more than one video stream; only using the last one (%d)", video->component_tag); p->have_video = true; - p->video_tag = tag; - p->video_pid = -1; - p->video_type = -1; /* output size/position */ p->video = video; + /* the backend will tell us the PID and stream type when we start streaming it */ + p->video_tag = video->component_tag; + p->video_pid = -1; + p->video_type = -1; + return; } void -MHEGStreamPlayer_setAudioTag(MHEGStreamPlayer *p, int tag) +MHEGStreamPlayer_setAudioStream(MHEGStreamPlayer *p, AudioClass *audio) { if(p->have_audio) - error("MHEGStreamPlayer: more than one audio stream; only using the last one (%d)", tag); + error("MHEGStreamPlayer: more than one audio stream; only using the last one (%d)", audio->component_tag); p->have_audio = true; - p->audio_tag = tag; + + /* volume */ + p->audio = audio; + + /* the backend will tell us the PID and stream type when we start streaming it */ + p->audio_tag = audio->component_tag; p->audio_pid = -1; p->audio_type = -1; Modified: redbutton-browser/trunk/MHEGStreamPlayer.h =================================================================== --- redbutton-browser/trunk/MHEGStreamPlayer.h 2006-05-31 13:35:40 UTC (rev 83) +++ redbutton-browser/trunk/MHEGStreamPlayer.h 2006-06-02 11:01:46 UTC (rev 84) @@ -39,6 +39,8 @@ bool stop; /* true => stop playback */ bool have_video; /* false if we have no video stream */ bool have_audio; /* false if we have no audio stream */ + VideoClass *video; /* output size/position, maybe NULL if audio only */ + AudioClass *audio; /* output volume, maybe NULL if video only */ int video_tag; /* video stream component tag (-1 => default for current service ID) */ int video_pid; /* PID in MPEG Transport Stream (-1 => not yet known) */ int video_type; /* video stream type (-1 => not yet known) */ @@ -46,7 +48,6 @@ int audio_pid; /* PID in MPEG Transport Stream (-1 => not yet known) */ int audio_type; /* audio stream type (-1 => not yet known) */ FILE *ts; /* MPEG Transport Stream */ - VideoClass *video; /* output size/position, maybe NULL if audio only */ pthread_t decode_tid; /* thread decoding the MPEG stream into frames */ pthread_t video_tid; /* thread displaying frames on the screen */ pthread_mutex_t videoq_lock; /* list of decoded video frames */ @@ -57,8 +58,8 @@ void MHEGStreamPlayer_init(MHEGStreamPlayer *); void MHEGStreamPlayer_fini(MHEGStreamPlayer *); -void MHEGStreamPlayer_setVideoTag(MHEGStreamPlayer *, VideoClass *, int); -void MHEGStreamPlayer_setAudioTag(MHEGStreamPlayer *, int); +void MHEGStreamPlayer_setVideoStream(MHEGStreamPlayer *, VideoClass *); +void MHEGStreamPlayer_setAudioStream(MHEGStreamPlayer *, AudioClass *); void MHEGStreamPlayer_play(MHEGStreamPlayer *); void MHEGStreamPlayer_stop(MHEGStreamPlayer *); Modified: redbutton-browser/trunk/StreamComponent.c =================================================================== --- redbutton-browser/trunk/StreamComponent.c 2006-05-31 13:35:40 UTC (rev 83) +++ redbutton-browser/trunk/StreamComponent.c 2006-06-02 11:01:46 UTC (rev 84) @@ -105,11 +105,11 @@ switch(s->choice) { case StreamComponent_audio: - MHEGStreamPlayer_setAudioTag(player, s->u.audio.component_tag); + MHEGStreamPlayer_setAudioStream(player, &s->u.audio); break; case StreamComponent_video: - MHEGStreamPlayer_setVideoTag(player, &s->u.video, s->u.video.component_tag); + MHEGStreamPlayer_setVideoStream(player, &s->u.video); break; case StreamComponent_rtgraphics: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <ski...@us...> - 2006-05-31 13:35:44
|
Revision: 83 Author: skilvington Date: 2006-05-31 06:35:40 -0700 (Wed, 31 May 2006) ViewCVS: http://svn.sourceforge.net/redbutton/?rev=83&view=rev Log Message: ----------- local rb-download's need to listen for rb-browser's so they can stream video/audio Modified Paths: -------------- www/index.html Modified: www/index.html =================================================================== --- www/index.html 2006-05-31 13:27:14 UTC (rev 82) +++ www/index.html 2006-05-31 13:35:40 UTC (rev 83) @@ -95,7 +95,7 @@ and <service_gateway> should be an entry in the services directory. Eg, on a single host, do this: <PRE> -rb-download 4165 > /dev/null & +rb-download -l 4165 > /dev/null & rb-browser services/4165 </PRE> To run the frontend on a different host, do this on the backend: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |