Thread: [Redbutton-devel] SF.net SVN: redbutton: [93] redbutton-browser/trunk (Page 2)
Brought to you by:
skilvington
|
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-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-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-14 09:37:36
|
Revision: 109 Author: skilvington Date: 2006-06-14 02:37:29 -0700 (Wed, 14 Jun 2006) ViewCVS: http://svn.sourceforge.net/redbutton/?rev=109&view=rev Log Message: ----------- recognise long and short ResidentProgram names Modified Paths: -------------- redbutton-browser/trunk/ResidentProgramClass.c redbutton-browser/trunk/TODO redbutton-browser/trunk/der_decode.c redbutton-browser/trunk/der_decode.h Modified: redbutton-browser/trunk/ResidentProgramClass.c =================================================================== --- redbutton-browser/trunk/ResidentProgramClass.c 2006-06-14 08:32:17 UTC (rev 108) +++ redbutton-browser/trunk/ResidentProgramClass.c 2006-06-14 09:37:29 UTC (rev 109) @@ -234,7 +234,7 @@ } /* - * run the given program (identified by the 3 character name field in the ResidentProgramClass) + * run the given program (identified by the name field in the ResidentProgramClass) * returns true if the program succeeds * sets the parameters to the values described by the UK MHEG Profile * caller_gid is used to resolve Generic variables in the parameters @@ -243,35 +243,36 @@ struct { - char name[3]; + char *short_name; + char *long_name; bool (*func)(LIST_OF(Parameter) *, OctetString *); } resident_progs[] = { - { "GCD", prog_GetCurrentDate }, - { "FDa", prog_FormatDate }, - { "GDW", prog_GetDayOfWeek }, - { "Rnd", prog_Random }, - { "CTC", prog_CastToContentRef }, - { "CTO", prog_CastToObjectRef }, - { "GSL", prog_GetStringLength }, - { "GSS", prog_GetSubString }, - { "SSS", prog_SearchSubString }, - { "SES", prog_SearchAndExtractSubString }, - { "GSI", prog_SI_GetServiceIndex }, - { "TIn", prog_SI_TuneIndex }, - { "TII", prog_SI_TuneIndexInfo }, - { "BSI", prog_SI_GetBasicSI }, - { "GBI", prog_GetBootInfo }, - { "CCR", prog_CheckContentRef }, - { "CGR", prog_CheckGroupIDRef }, - { "VTG", prog_VideoToGraphics }, - { "SWA", prog_SetWidescreenAlignment }, - { "GDA", prog_GetDisplayAspectRatio }, - { "CIS", prog_CI_SendMessage }, - { "SSM", prog_SetSubtitleMode }, - { "WAI", prog_WhoAmI }, - { "DBG", prog_Debug }, - { "", NULL } + { "GCD", "GetCurrentDate", prog_GetCurrentDate }, + { "FDa", "FormatDate", prog_FormatDate }, + { "GDW", "GetDayOfWeek", prog_GetDayOfWeek }, + { "Rnd", "Random", prog_Random }, + { "CTC", "CastToContentRef", prog_CastToContentRef }, + { "CTO", "CastToObjectRef", prog_CastToObjectRef }, + { "GSL", "GetStringLength", prog_GetStringLength }, + { "GSS", "GetSubString", prog_GetSubString }, + { "SSS", "SearchSubString", prog_SearchSubString }, + { "SES", "SearchAndExtractSubString", prog_SearchAndExtractSubString }, + { "GSI", "SI_GetServiceIndex", prog_SI_GetServiceIndex }, + { "TIn", "SI_TuneIndex", prog_SI_TuneIndex }, + { "TII", "SI_TuneIndexInfo", prog_SI_TuneIndexInfo }, + { "BSI", "SI_GetBasicSI", prog_SI_GetBasicSI }, + { "GBI", "GetBootInfo", prog_GetBootInfo }, + { "CCR", "CheckContentRef", prog_CheckContentRef }, + { "CGR", "CheckGroupIDRef", prog_CheckGroupIDRef }, + { "VTG", "VideoToGraphics", prog_VideoToGraphics }, + { "SWA", "SetWidescreenAlignment", prog_SetWidescreenAlignment }, + { "GDA", "GetDisplayAspectRatio", prog_GetDisplayAspectRatio }, + { "CIS", "CI_SendMessage", prog_CI_SendMessage }, + { "SSM", "SetSubtitleMode", prog_SetSubtitleMode }, + { "WAI", "WhoAmI", prog_WhoAmI }, + { "DBG", "Debug", prog_Debug }, + { "", "", NULL } }; bool @@ -283,18 +284,14 @@ /* remember if we were forked or not */ p->inst.forked = forked; - /* check the name is in the form we expect */ - if(p->name.size != 3) + /* find it */ + for(i=0; resident_progs[i].func!=NULL; i++) { - error("Unknown ResidentProgram: '%.*s'", p->name.size, p->name.data); - return false; + if(OctetString_strcmp(&p->name, resident_progs[i].short_name) == 0 + || OctetString_strcmp(&p->name, resident_progs[i].long_name) == 0) + break; } - /* find it */ - i = 0; - while(resident_progs[i].func && strncmp(resident_progs[i].name, p->name.data, 3) != 0) - i ++; - /* run it */ if(resident_progs[i].func) { Modified: redbutton-browser/trunk/TODO =================================================================== --- redbutton-browser/trunk/TODO 2006-06-14 08:32:17 UTC (rev 108) +++ redbutton-browser/trunk/TODO 2006-06-14 09:37:29 UTC (rev 109) @@ -1,3 +1,8 @@ +if openStream fails - need to make sure either: +contents picture gets filled with black, or +VideoClass_render does not make a transparent rectangle in the overlay picture + + in all VisibleClass objects only redraw them in SetPosition/SetBoxSize/etc if they actually move/change size/etc Modified: redbutton-browser/trunk/der_decode.c =================================================================== --- redbutton-browser/trunk/der_decode.c 2006-06-14 08:32:17 UTC (rev 108) +++ redbutton-browser/trunk/der_decode.c 2006-06-14 09:37:29 UTC (rev 109) @@ -219,6 +219,21 @@ } /* + * compare the OctetString with the given \0 terminated C string + */ + +int +OctetString_strcmp(OctetString *oct, char *str) +{ + size_t len = strlen(str); + + if(oct->size != len) + return oct->size - len; + else + return memcmp(oct->data, str, len); +} + +/* * assumes its okay to call der_realloc(dst->data, x) * if dst is not initialised, you should use OctetString_dup instead * src can be NULL, but dst must be valid Modified: redbutton-browser/trunk/der_decode.h =================================================================== --- redbutton-browser/trunk/der_decode.h 2006-06-14 08:32:17 UTC (rev 108) +++ redbutton-browser/trunk/der_decode.h 2006-06-14 09:37:29 UTC (rev 109) @@ -50,6 +50,8 @@ void free_OctetString(OctetString *); int OctetString_cmp(OctetString *, OctetString *); +int OctetString_strcmp(OctetString *, char *); + bool OctetString_copy(OctetString *, OctetString *); void OctetString_dup(OctetString *, OctetString *); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <ski...@us...> - 2006-06-28 16:27:42
|
Revision: 126 Author: skilvington Date: 2006-06-28 09:27:17 -0700 (Wed, 28 Jun 2006) ViewCVS: http://svn.sourceforge.net/redbutton/?rev=126&view=rev Log Message: ----------- add a mechanism for setting a clip rectangle on the overlay Modified Paths: -------------- redbutton-browser/trunk/MHEGDisplay.c redbutton-browser/trunk/MHEGDisplay.h Modified: redbutton-browser/trunk/MHEGDisplay.c =================================================================== --- redbutton-browser/trunk/MHEGDisplay.c 2006-06-27 16:21:54 UTC (rev 125) +++ redbutton-browser/trunk/MHEGDisplay.c 2006-06-28 16:27:17 UTC (rev 126) @@ -383,7 +383,42 @@ } /* + * set the clip rectangle for all subsequent drawing on the overlay * coords should be in the range 0-MHEG_XRES, 0-MHEG_YRES + */ + +void +MHEGDisplay_setClipRectangle(MHEGDisplay *d, XYPosition *pos, OriginalBoxSize *box) +{ + XRectangle clip; + + /* scale if fullscreen */ + clip.x = (pos->x_position * d->xres) / MHEG_XRES; + clip.y = (pos->y_position * d->yres) / MHEG_YRES; + clip.width = (box->x_length * d->xres) / MHEG_XRES; + clip.height = (box->y_length * d->yres) / MHEG_YRES; + +/* TODO */ +/* this will effect the XRenderComposite() call in _refresh() */ + XRenderSetPictureClipRectangles(d->dpy, d->overlay_pic, 0, 0, &clip, 1); + + return; +} + +/* + * remove the clip rectangle from the overlay + */ + +void +MHEGDisplay_unsetClipRectangle(MHEGDisplay *d) +{ + XRenderSetPictureClipRectangles(d->dpy, d->overlay_pic, 0, 0, NULL, 0); + + return; +} + +/* + * coords should be in the range 0-MHEG_XRES, 0-MHEG_YRES * width is the line width in pixels * style should be LineStyle_solid/dashed/dotted */ Modified: redbutton-browser/trunk/MHEGDisplay.h =================================================================== --- redbutton-browser/trunk/MHEGDisplay.h 2006-06-27 16:21:54 UTC (rev 125) +++ redbutton-browser/trunk/MHEGDisplay.h 2006-06-28 16:27:17 UTC (rev 126) @@ -60,6 +60,8 @@ void MHEGDisplay_refresh(MHEGDisplay *, XYPosition *, OriginalBoxSize *); /* drawing routines */ +void MHEGDisplay_setClipRectangle(MHEGDisplay *, XYPosition *, OriginalBoxSize *); +void MHEGDisplay_unsetClipRectangle(MHEGDisplay *); void MHEGDisplay_drawHoriLine(MHEGDisplay *, XYPosition *, unsigned int, int, int, MHEGColour *); void MHEGDisplay_drawVertLine(MHEGDisplay *, XYPosition *, unsigned int, int, int, MHEGColour *); void MHEGDisplay_fillTransparentRectangle(MHEGDisplay *, XYPosition *, OriginalBoxSize *); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <ski...@us...> - 2006-06-29 13:25:21
|
Revision: 127 Author: skilvington Date: 2006-06-29 06:25:13 -0700 (Thu, 29 Jun 2006) ViewCVS: http://svn.sourceforge.net/redbutton/?rev=127&view=rev Log Message: ----------- only refresh MHEG overlay when we have finished drawing it Modified Paths: -------------- redbutton-browser/trunk/MHEGDisplay.c redbutton-browser/trunk/MHEGDisplay.h redbutton-browser/trunk/MHEGEngine.c redbutton-browser/trunk/TODO Modified: redbutton-browser/trunk/MHEGDisplay.c =================================================================== --- redbutton-browser/trunk/MHEGDisplay.c 2006-06-28 16:27:17 UTC (rev 126) +++ redbutton-browser/trunk/MHEGDisplay.c 2006-06-29 13:25:13 UTC (rev 127) @@ -80,7 +80,6 @@ XGCValues gcvals; XRenderPictFormat *pic_format; XRenderPictureAttributes pa; - Pixmap overlay; Pixmap textfg; /* fake argc, argv for XtDisplayInitialize */ int argc = 0; @@ -227,8 +226,10 @@ /* create a 32-bit XRender Picture to draw the MHEG objects on */ pic_format = XRenderFindStandardFormat(d->dpy, PictStandardARGB32); - overlay = XCreatePixmap(d->dpy, d->win, d->xres, d->yres, 32); - d->overlay_pic = XRenderCreatePicture(d->dpy, overlay, pic_format, 0, NULL); + d->next_overlay = XCreatePixmap(d->dpy, d->win, d->xres, d->yres, 32); + d->next_overlay_pic = XRenderCreatePicture(d->dpy, d->next_overlay, pic_format, 0, NULL); + d->used_overlay = XCreatePixmap(d->dpy, d->win, d->xres, d->yres, 32); + d->used_overlay_pic = XRenderCreatePicture(d->dpy, d->used_overlay, pic_format, 0, NULL); /* a 1x1 Picture to hold the text foreground colour */ textfg = XCreatePixmap(d->dpy, d->win, 1, 1, 32); @@ -238,6 +239,9 @@ /* a GC to draw on the Window */ d->win_gc = XCreateGC(d->dpy, d->win, 0, &gcvals); + /* a GC to XCopyArea next_overlay to used_overlay (need to avoid any XRender clip mask on next_overlay) */ + d->overlay_gc = XCreateGC(d->dpy, d->next_overlay, 0, &gcvals); + /* get the window on the screen */ XMapWindow(d->dpy, d->win); @@ -371,10 +375,10 @@ /* * if video is being displayed, the current frame will already be in d->contents - * (drawn by the video thread or VideoClass_render) + * (drawn by the video thread) * overlay the MHEG objects onto the video in d->contents */ - XRenderComposite(d->dpy, PictOpOver, d->overlay_pic, None, d->contents_pic, x, y, x, y, x, y, w, h); + XRenderComposite(d->dpy, PictOpOver, d->used_overlay_pic, None, d->contents_pic, x, y, x, y, x, y, w, h); /* copy the Window contents onto the screen */ XCopyArea(d->dpy, d->contents, d->win, d->win_gc, x, y, w, h, x, y); @@ -383,6 +387,15 @@ } /* + * all these drawing routines draw onto next_overlay_pic + * all coords should be in the range 0-MHEG_XRES, 0-MHEG_YRES + * the drawing routines themselves will scale the coords to full screen if needed + * you have to call MHEGDisplay_useOverlay() when you have finished drawing + * this copies next_overlay onto used_overlay + * used_overlay_pic is composited onto any video and put on the screen by MHEGDisplay_refresh() + */ + +/* * set the clip rectangle for all subsequent drawing on the overlay * coords should be in the range 0-MHEG_XRES, 0-MHEG_YRES */ @@ -398,9 +411,7 @@ clip.width = (box->x_length * d->xres) / MHEG_XRES; clip.height = (box->y_length * d->yres) / MHEG_YRES; -/* TODO */ -/* this will effect the XRenderComposite() call in _refresh() */ - XRenderSetPictureClipRectangles(d->dpy, d->overlay_pic, 0, 0, &clip, 1); + XRenderSetPictureClipRectangles(d->dpy, d->next_overlay_pic, 0, 0, &clip, 1); return; } @@ -412,7 +423,7 @@ void MHEGDisplay_unsetClipRectangle(MHEGDisplay *d) { - XRenderSetPictureClipRectangles(d->dpy, d->overlay_pic, 0, 0, NULL, 0); + XRenderSetPictureClipRectangles(d->dpy, d->next_overlay_pic, 0, 0, NULL, 0); return; } @@ -449,7 +460,7 @@ printf("TODO: LineStyle %d\n", style); /* draw a rectangle */ - XRenderFillRectangle(d->dpy, PictOpOver, d->overlay_pic, &rcol, x, y, w, h); + XRenderFillRectangle(d->dpy, PictOpOver, d->next_overlay_pic, &rcol, x, y, w, h); return; } @@ -486,7 +497,7 @@ printf("TODO: LineStyle %d\n", style); /* draw a rectangle */ - XRenderFillRectangle(d->dpy, PictOpOver, d->overlay_pic, &rcol, x, y, w, h); + XRenderFillRectangle(d->dpy, PictOpOver, d->next_overlay_pic, &rcol, x, y, w, h); return; } @@ -515,7 +526,7 @@ w = (box->x_length * d->xres) / MHEG_XRES; h = (box->y_length * d->yres) / MHEG_YRES; - XRenderFillRectangle(d->dpy, PictOpOver, d->overlay_pic, &rcol, x, y, w, h); + XRenderFillRectangle(d->dpy, PictOpOver, d->next_overlay_pic, &rcol, x, y, w, h); return; } @@ -539,7 +550,7 @@ w = (box->x_length * d->xres) / MHEG_XRES; h = (box->y_length * d->yres) / MHEG_YRES; - XRenderFillRectangle(d->dpy, PictOpSrc, d->overlay_pic, &rcol, x, y, w, h); + XRenderFillRectangle(d->dpy, PictOpSrc, d->next_overlay_pic, &rcol, x, y, w, h); return; } @@ -570,7 +581,7 @@ dst_x = (dst->x_position * d->xres) / MHEG_XRES; dst_y = (dst->y_position * d->yres) / MHEG_YRES; - XRenderComposite(d->dpy, PictOpOver, bitmap->image_pic, None, d->overlay_pic, + XRenderComposite(d->dpy, PictOpOver, bitmap->image_pic, None, d->next_overlay_pic, src_x, src_y, src_x, src_y, dst_x, dst_y, w, h); @@ -670,7 +681,7 @@ /* round up/down the X coord */ scrn_x = (x * d->xres) / MHEG_XRES; scrn_x = (scrn_x + (face->units_per_EM / 2)) / face->units_per_EM; - XftGlyphRender(d->dpy, PictOpOver, d->textfg_pic, font->font, d->overlay_pic, + XftGlyphRender(d->dpy, PictOpOver, d->textfg_pic, font->font, d->next_overlay_pic, 0, 0, orig_x + scrn_x, y, &glyph, 1); face = XftLockFace(font->font); @@ -690,6 +701,20 @@ } /* + * copy the contents of next_overlay onto used_overlay + * ie all drawing done since the last call to this will appear on the screen at the next refresh() + */ + +void +MHEGDisplay_useOverlay(MHEGDisplay *d) +{ + /* avoid any XRender clip mask */ + XCopyArea(d->dpy, d->next_overlay, d->used_overlay, d->overlay_gc, 0, 0, d->xres, d->yres, 0, 0); + + return; +} + +/* * convert the given PNG data to an internal format * returns NULL on error */ Modified: redbutton-browser/trunk/MHEGDisplay.h =================================================================== --- redbutton-browser/trunk/MHEGDisplay.h 2006-06-28 16:27:17 UTC (rev 126) +++ redbutton-browser/trunk/MHEGDisplay.h 2006-06-29 13:25:13 UTC (rev 127) @@ -47,7 +47,11 @@ Colormap cmap; /* None, unless we needed to create a Colormap for our Visual */ Pixmap contents; /* current contents of the Window */ Picture contents_pic; /* XRender wrapper for the contents, this is what we composite on */ - Picture overlay_pic; /* draw MHEG objects on here and overlay it on any video */ + Pixmap next_overlay; /* all MHEG objects are drawn on next_overlay */ + Picture next_overlay_pic; /* via this XRender wrapper */ + Pixmap used_overlay; /* when MHEGDisplay_useOverlay() is called, next_overlay is copied here */ + Picture used_overlay_pic; /* used_overlay_pic is composited onto the video */ + GC overlay_gc; /* GC to XCopyArea next_overlay to used_overlay */ Picture textfg_pic; /* 1x1 solid foreground colour for text */ MHEGKeyMapEntry *keymap; /* keyboard mapping */ } MHEGDisplay; @@ -62,6 +66,7 @@ /* drawing routines */ void MHEGDisplay_setClipRectangle(MHEGDisplay *, XYPosition *, OriginalBoxSize *); void MHEGDisplay_unsetClipRectangle(MHEGDisplay *); + void MHEGDisplay_drawHoriLine(MHEGDisplay *, XYPosition *, unsigned int, int, int, MHEGColour *); void MHEGDisplay_drawVertLine(MHEGDisplay *, XYPosition *, unsigned int, int, int, MHEGColour *); void MHEGDisplay_fillTransparentRectangle(MHEGDisplay *, XYPosition *, OriginalBoxSize *); @@ -69,6 +74,8 @@ void MHEGDisplay_drawBitmap(MHEGDisplay *, XYPosition *, OriginalBoxSize *, MHEGBitmap *, XYPosition *); void MHEGDisplay_drawTextElement(MHEGDisplay *, XYPosition *, MHEGFont *, MHEGTextElement *, bool); +void MHEGDisplay_useOverlay(MHEGDisplay *); + /* convert PNG and MPEG I-frames to internal format */ MHEGBitmap *MHEGDisplay_newPNGBitmap(MHEGDisplay *, OctetString *); MHEGBitmap *MHEGDisplay_newMPEGBitmap(MHEGDisplay *, OctetString *); Modified: redbutton-browser/trunk/MHEGEngine.c =================================================================== --- redbutton-browser/trunk/MHEGEngine.c 2006-06-28 16:27:17 UTC (rev 126) +++ redbutton-browser/trunk/MHEGEngine.c 2006-06-29 13:25:13 UTC (rev 127) @@ -649,13 +649,6 @@ if(app->inst.LockCount > 0) return; -/**************************************************************************************/ -/* could do: */ -/* MHEGDisplay_setClipRectangle(pos, box); */ -/* rather than relying on every _render() method to make sure they dont draw outside the area */ -/* we also need to make sure the _render methods dont draw outside their own bounding boxes */ -/**************************************************************************************/ - /* any undrawn on background is black */ MHEGColour_black(&black); MHEGDisplay_fillRectangle(&engine.display, pos, box, &black); @@ -673,6 +666,9 @@ stack = stack->next; } + /* use the new objects we have just drawn */ + MHEGDisplay_useOverlay(&engine.display); + /* refresh the screen */ MHEGDisplay_refresh(&engine.display, pos, box); Modified: redbutton-browser/trunk/TODO =================================================================== --- redbutton-browser/trunk/TODO 2006-06-28 16:27:17 UTC (rev 126) +++ redbutton-browser/trunk/TODO 2006-06-29 13:25:13 UTC (rev 127) @@ -1,3 +1,7 @@ +use setClipRectangle on the intersection area in each _render() method +(remember to unsetClipRectangle at the end of _render) + + if openStream fails - need to make sure either: contents picture gets filled with black, or VideoClass_render does not make a transparent rectangle in the overlay picture This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <ski...@us...> - 2006-06-29 16:15:49
|
Revision: 128 Author: skilvington Date: 2006-06-29 09:15:27 -0700 (Thu, 29 Jun 2006) ViewCVS: http://svn.sourceforge.net/redbutton/?rev=128&view=rev Log Message: ----------- use clip rectangles to ensure objects don't draw outside their bboxes Modified Paths: -------------- redbutton-browser/trunk/BitmapClass.c redbutton-browser/trunk/DynamicLineArtClass.c redbutton-browser/trunk/EntryFieldClass.c redbutton-browser/trunk/HyperTextClass.c redbutton-browser/trunk/MHEGDisplay.c redbutton-browser/trunk/MHEGFont.c redbutton-browser/trunk/RectangleClass.c redbutton-browser/trunk/SliderClass.c redbutton-browser/trunk/TODO redbutton-browser/trunk/TextClass.c redbutton-browser/trunk/VideoClass.c Modified: redbutton-browser/trunk/BitmapClass.c =================================================================== --- redbutton-browser/trunk/BitmapClass.c 2006-06-29 13:25:13 UTC (rev 127) +++ redbutton-browser/trunk/BitmapClass.c 2006-06-29 16:15:27 UTC (rev 128) @@ -471,6 +471,8 @@ if(!intersects(pos, box, &t->inst.Position, &t->inst.BoxSize, &ins_pos, &ins_box)) return; + MHEGDisplay_setClipRectangle(d, &ins_pos, &ins_box); + /* work out where the intersection starts on the bitmap */ src.x_position = ins_pos.x_position - t->inst.Position.x_position; src.y_position = ins_pos.y_position - t->inst.Position.y_position; @@ -485,6 +487,8 @@ MHEGDisplay_drawBitmap(d, &src, &ins_box, t->inst.Bitmap, &ins_pos); + MHEGDisplay_unsetClipRectangle(d); + return; } Modified: redbutton-browser/trunk/DynamicLineArtClass.c =================================================================== --- redbutton-browser/trunk/DynamicLineArtClass.c 2006-06-29 13:25:13 UTC (rev 127) +++ redbutton-browser/trunk/DynamicLineArtClass.c 2006-06-29 16:15:27 UTC (rev 128) @@ -395,8 +395,13 @@ if(!intersects(pos, box, &t->inst.Position, &t->inst.BoxSize, &ins_pos, &ins_box)) return; + MHEGDisplay_setClipRectangle(d, &ins_pos, &ins_box); + /* TODO */ printf("TODO: DynamicLineArtClass_render\n"); + + MHEGDisplay_unsetClipRectangle(d); + return; } Modified: redbutton-browser/trunk/EntryFieldClass.c =================================================================== --- redbutton-browser/trunk/EntryFieldClass.c 2006-06-29 13:25:13 UTC (rev 127) +++ redbutton-browser/trunk/EntryFieldClass.c 2006-06-29 16:15:27 UTC (rev 128) @@ -559,10 +559,21 @@ void EntryFieldClass_render(EntryFieldClass *t, MHEGDisplay *d, XYPosition *pos, OriginalBoxSize *box) { + XYPosition ins_pos; + OriginalBoxSize ins_box; + verbose("EntryFieldClass: %s; render", ExternalReference_name(&t->rootClass.inst.ref)); + if(!intersects(pos, box, &t->inst.Position, &t->inst.BoxSize, &ins_pos, &ins_box)) + return; + + MHEGDisplay_setClipRectangle(d, &ins_pos, &ins_box); + /* TODO */ printf("TODO: EntryFieldClass_render\n"); + + MHEGDisplay_unsetClipRectangle(d); + return; } Modified: redbutton-browser/trunk/HyperTextClass.c =================================================================== --- redbutton-browser/trunk/HyperTextClass.c 2006-06-29 13:25:13 UTC (rev 127) +++ redbutton-browser/trunk/HyperTextClass.c 2006-06-29 16:15:27 UTC (rev 128) @@ -553,10 +553,21 @@ void HyperTextClass_render(HyperTextClass *t, MHEGDisplay *d, XYPosition *pos, OriginalBoxSize *box) { + XYPosition ins_pos; + OriginalBoxSize ins_box; + verbose("HyperTextClass: %s; render", ExternalReference_name(&t->rootClass.inst.ref)); + if(!intersects(pos, box, &t->inst.Position, &t->inst.BoxSize, &ins_pos, &ins_box)) + return; + + MHEGDisplay_setClipRectangle(d, &ins_pos, &ins_box); + /* TODO */ printf("TODO: HyperTextClass_render\n"); + + MHEGDisplay_unsetClipRectangle(d); + return; } Modified: redbutton-browser/trunk/MHEGDisplay.c =================================================================== --- redbutton-browser/trunk/MHEGDisplay.c 2006-06-29 13:25:13 UTC (rev 127) +++ redbutton-browser/trunk/MHEGDisplay.c 2006-06-29 16:15:27 UTC (rev 128) @@ -423,8 +423,17 @@ void MHEGDisplay_unsetClipRectangle(MHEGDisplay *d) { - XRenderSetPictureClipRectangles(d->dpy, d->next_overlay_pic, 0, 0, NULL, 0); + /* + * this doesn't work... + * XRenderSetPictureClipRectangles(d->dpy, d->next_overlay_pic, 0, 0, NULL, 0); + */ + XRenderPictureAttributes attr; + + attr.clip_mask = None; + + XRenderChangePicture(d->dpy, d->next_overlay_pic, CPClipMask, &attr); + return; } Modified: redbutton-browser/trunk/MHEGFont.c =================================================================== --- redbutton-browser/trunk/MHEGFont.c 2006-06-29 13:25:13 UTC (rev 127) +++ redbutton-browser/trunk/MHEGFont.c 2006-06-29 16:15:27 UTC (rev 128) @@ -428,7 +428,7 @@ /* TODO */ /* truncation: ie remove chars outside box */ -/* if we set a clip rectangle in MHEGEngine_redrawArea it will solve the problem */ +/* setting the clip rectangle in TextClass_render solves the problem */ /* but UK profile says we shouldn't draw any partial characters */ return elem_list; Modified: redbutton-browser/trunk/RectangleClass.c =================================================================== --- redbutton-browser/trunk/RectangleClass.c 2006-06-29 13:25:13 UTC (rev 127) +++ redbutton-browser/trunk/RectangleClass.c 2006-06-29 16:15:27 UTC (rev 128) @@ -390,6 +390,8 @@ if(!intersects(pos, box, &t->inst.Position, &t->inst.BoxSize, &ins_pos, &ins_box)) return; + MHEGDisplay_setClipRectangle(d, &ins_pos, &ins_box); + /* fill it */ MHEGDisplay_fillRectangle(d, &ins_pos, &ins_box, &t->inst.RefFillColour); @@ -414,6 +416,8 @@ len = t->inst.BoxSize.x_length - t->inst.LineWidth; MHEGDisplay_drawHoriLine(d, &p, len, t->inst.LineWidth, t->inst.LineStyle, &t->inst.RefLineColour); + MHEGDisplay_unsetClipRectangle(d); + return; } Modified: redbutton-browser/trunk/SliderClass.c =================================================================== --- redbutton-browser/trunk/SliderClass.c 2006-06-29 13:25:13 UTC (rev 127) +++ redbutton-browser/trunk/SliderClass.c 2006-06-29 16:15:27 UTC (rev 128) @@ -375,11 +375,21 @@ void SliderClass_render(SliderClass *t, MHEGDisplay *d, XYPosition *pos, OriginalBoxSize *box) { + XYPosition ins_pos; + OriginalBoxSize ins_box; + verbose("SliderClass: %s; render", ExternalReference_name(&t->rootClass.inst.ref)); + if(!intersects(pos, box, &t->inst.Position, &t->inst.BoxSize, &ins_pos, &ins_box)) + return; + + MHEGDisplay_setClipRectangle(d, &ins_pos, &ins_box); + /* TODO */ printf("TODO: SliderClass_render\n"); + + MHEGDisplay_unsetClipRectangle(d); + return; } - Modified: redbutton-browser/trunk/TODO =================================================================== --- redbutton-browser/trunk/TODO 2006-06-29 13:25:13 UTC (rev 127) +++ redbutton-browser/trunk/TODO 2006-06-29 16:15:27 UTC (rev 128) @@ -1,7 +1,3 @@ -use setClipRectangle on the intersection area in each _render() method -(remember to unsetClipRectangle at the end of _render) - - if openStream fails - need to make sure either: contents picture gets filled with black, or VideoClass_render does not make a transparent rectangle in the overlay picture Modified: redbutton-browser/trunk/TextClass.c =================================================================== --- redbutton-browser/trunk/TextClass.c 2006-06-29 13:25:13 UTC (rev 127) +++ redbutton-browser/trunk/TextClass.c 2006-06-29 16:15:27 UTC (rev 128) @@ -590,6 +590,8 @@ if(!intersects(pos, box, &t->inst.Position, &t->inst.BoxSize, &ins_pos, &ins_box)) return; + MHEGDisplay_setClipRectangle(d, &ins_pos, &ins_box); + /* draw the background */ MHEGDisplay_fillRectangle(d, &ins_pos, &ins_box, &t->inst.BackgroundColour); @@ -612,6 +614,8 @@ element = element->next; } + MHEGDisplay_unsetClipRectangle(d); + return; } Modified: redbutton-browser/trunk/VideoClass.c =================================================================== --- redbutton-browser/trunk/VideoClass.c 2006-06-29 13:25:13 UTC (rev 127) +++ redbutton-browser/trunk/VideoClass.c 2006-06-29 16:15:27 UTC (rev 128) @@ -379,12 +379,6 @@ if(!intersects(pos, box, &t->inst.Position, &t->inst.BoxSize, &ins_pos, &ins_box)) return; - /* draw the video frame onto the Window contents Pixmap */ -// need to do the equivalent of this, but not here -// => get rid of VideoClass.inst.player too -// if(t->inst.player != NULL) -// MHEGStreamPlayer_drawCurrentFrame(t->inst.player); - /* make a transparent hole in the MHEG overlay so we can see the video below it */ MHEGDisplay_fillTransparentRectangle(d, &ins_pos, &ins_box); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <ski...@us...> - 2006-07-12 15:33:45
|
Revision: 130 Author: skilvington Date: 2006-07-12 08:33:36 -0700 (Wed, 12 Jul 2006) ViewCVS: http://svn.sourceforge.net/redbutton/?rev=130&view=rev Log Message: ----------- tidy up cmd line option parsing Modified Paths: -------------- redbutton-browser/trunk/MHEGEngine.c redbutton-browser/trunk/MHEGEngine.h redbutton-browser/trunk/rb-browser.c Modified: redbutton-browser/trunk/MHEGEngine.c =================================================================== --- redbutton-browser/trunk/MHEGEngine.c 2006-07-04 08:56:19 UTC (rev 129) +++ redbutton-browser/trunk/MHEGEngine.c 2006-07-12 15:33:36 UTC (rev 130) @@ -164,16 +164,16 @@ static MHEGEngine engine; void -MHEGEngine_init(bool remote, char *srg_loc, int verbose, unsigned int timeout, bool fullscreen, char *keymap) +MHEGEngine_init(MHEGEngineOptions *opts) { bzero(&engine, sizeof(MHEGEngine)); - engine.verbose = verbose; - engine.timeout = timeout; + engine.verbose = opts->verbose; + engine.timeout = opts->timeout; - MHEGDisplay_init(&engine.display, fullscreen, keymap); + MHEGDisplay_init(&engine.display, opts->fullscreen, opts->keymap); - MHEGBackend_init(&engine.backend, remote, srg_loc); + MHEGBackend_init(&engine.backend, opts->remote, opts->srg_loc); MHEGApp_init(&engine.active_app); Modified: redbutton-browser/trunk/MHEGEngine.h =================================================================== --- redbutton-browser/trunk/MHEGEngine.h 2006-07-04 08:56:19 UTC (rev 129) +++ redbutton-browser/trunk/MHEGEngine.h 2006-07-12 15:33:36 UTC (rev 130) @@ -76,6 +76,17 @@ #define ContentHook_Stream_MPEG 10 #define ContentHook_Stream_File 11 +/* cmd line options */ +typedef struct +{ + bool remote; /* or local rb-download backend */ + char *srg_loc; /* service gateway location: directory for local; host[:port] for remote */ + int verbose; /* -v flag */ + unsigned int timeout; /* seconds to poll for missing content before generating a ContentRefError */ + bool fullscreen; /* scale to fullscreen? */ + char *keymap; /* keymap config file to use (NULL for default) */ +} MHEGEngineOptions; + /* a list of files we are waiting for, and the objects that want them */ typedef struct { @@ -169,7 +180,7 @@ } MHEGEngine; /* prototypes */ -void MHEGEngine_init(bool, char *, int, unsigned int, bool, char *); +void MHEGEngine_init(MHEGEngineOptions *); int MHEGEngine_run(OctetString *); void MHEGEngine_fini(); Modified: redbutton-browser/trunk/rb-browser.c =================================================================== --- redbutton-browser/trunk/rb-browser.c 2006-07-04 08:56:19 UTC (rev 129) +++ redbutton-browser/trunk/rb-browser.c 2006-07-12 15:33:36 UTC (rev 130) @@ -27,13 +27,8 @@ main(int argc, char *argv[]) { char *prog_name = argv[0]; + MHEGEngineOptions opts; int arg; - bool remote = false; - int v = 0; - bool f = false; - unsigned int timeout = MISSING_CONTENT_TIMEOUT; - char *keymap = NULL; - char *srg_dir; size_t last; int rc; int i; @@ -50,28 +45,37 @@ if(NULL != 0) fatal("%s needs to be compiled with a libc that makes NULL == 0", prog_name); + /* default options */ + bzero(&opts, sizeof(MHEGEngineOptions)); + opts.remote = false; + opts.srg_loc = NULL; /* must be given on cmd line */ + opts.verbose = 0; + opts.fullscreen = false; + opts.timeout = MISSING_CONTENT_TIMEOUT; + opts.keymap = NULL; + while((arg = getopt(argc, argv, "rvfk:t:")) != EOF) { switch(arg) { case 'r': - remote = true; + opts.remote = true; break; case 'v': - v ++; + opts.verbose ++; break; case 'f': - f = true; + opts.fullscreen = true; break; case 'k': - keymap = optarg; + opts.keymap = optarg; break; case 't': - timeout = strtoul(optarg, NULL, 0); + opts.timeout = strtoul(optarg, NULL, 0); break; default: @@ -83,14 +87,17 @@ if(optind != argc - 1) usage(prog_name); - srg_dir = argv[optind]; + opts.srg_loc = argv[optind]; - /* chop off any trailing / chars */ - last = strlen(srg_dir) - 1; - while(last > 0 && srg_dir[last] == '/') - srg_dir[last--] = '\0'; + /* chop off any trailing / chars for local directory name */ + if(!opts.remote) + { + last = strlen(opts.srg_loc) - 1; + while(last > 0 && opts.srg_loc[last] == '/') + opts.srg_loc[last--] = '\0'; + } - MHEGEngine_init(remote, srg_dir, v, timeout, f, keymap); + MHEGEngine_init(&opts); /* search for the boot object */ found = false; @@ -108,7 +115,7 @@ } else { - error("Unable to find boot object in '%s'", srg_dir); + error("Unable to find boot object in service gateway '%s'", opts.srg_loc); rc = EXIT_FAILURE; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <ski...@us...> - 2006-07-28 11:31:25
|
Revision: 132 Author: skilvington Date: 2006-07-28 04:30:58 -0700 (Fri, 28 Jul 2006) ViewCVS: http://svn.sourceforge.net/redbutton/?rev=132&view=rev Log Message: ----------- enable the use of different video output methods Modified Paths: -------------- redbutton-browser/trunk/MHEGEngine.c redbutton-browser/trunk/MHEGEngine.h redbutton-browser/trunk/MHEGStreamPlayer.c redbutton-browser/trunk/MHEGVideoOutput.c redbutton-browser/trunk/MHEGVideoOutput.h redbutton-browser/trunk/Makefile redbutton-browser/trunk/rb-browser.c Added Paths: ----------- redbutton-browser/trunk/videoout_null.c redbutton-browser/trunk/videoout_null.h redbutton-browser/trunk/videoout_xshm.c redbutton-browser/trunk/videoout_xshm.h Modified: redbutton-browser/trunk/MHEGEngine.c =================================================================== --- redbutton-browser/trunk/MHEGEngine.c 2006-07-19 15:53:27 UTC (rev 131) +++ redbutton-browser/trunk/MHEGEngine.c 2006-07-28 11:30:58 UTC (rev 132) @@ -173,6 +173,8 @@ MHEGDisplay_init(&engine.display, opts->fullscreen, opts->keymap); + engine.vo_method = MHEGVideoOutputMethod_fromString(opts->vo_method); + MHEGBackend_init(&engine.backend, opts->remote, opts->srg_loc); MHEGApp_init(&engine.active_app); @@ -283,6 +285,12 @@ return &engine.display; } +MHEGVideoOutputMethod * +MHEGEngine_getVideoOutputMethod(void) +{ + return engine.vo_method; +} + /* * according to the ISO MHEG spec this should be part of the SceneClass * but we need info about the current app etc too Modified: redbutton-browser/trunk/MHEGEngine.h =================================================================== --- redbutton-browser/trunk/MHEGEngine.h 2006-07-19 15:53:27 UTC (rev 131) +++ redbutton-browser/trunk/MHEGEngine.h 2006-07-28 11:30:58 UTC (rev 132) @@ -11,6 +11,7 @@ #include "ISO13522-MHEG-5.h" #include "MHEGDisplay.h" +#include "MHEGVideoOutput.h" #include "MHEGBackend.h" #include "MHEGApp.h" #include "der_decode.h" @@ -84,6 +85,7 @@ int verbose; /* -v flag */ unsigned int timeout; /* seconds to poll for missing content before generating a ContentRefError */ bool fullscreen; /* scale to fullscreen? */ + char *vo_method; /* MHEGVideoOutputMethod name (NULL for default) */ char *keymap; /* keymap config file to use (NULL for default) */ } MHEGEngineOptions; @@ -165,6 +167,7 @@ int verbose; /* -v cmd line flag */ unsigned int timeout; /* how long to poll for missing content before generating an error */ MHEGDisplay display; /* make porting easier */ + MHEGVideoOutputMethod *vo_method; /* video output method (resolved from name given in MHEGEngineOptions) */ MHEGBackend backend; /* local or remote access to DSMCC carousel and MPEG streams */ MHEGApp active_app; /* application we are currently running */ QuitReason quit_reason; /* do we need to stop the current app */ @@ -185,6 +188,7 @@ void MHEGEngine_fini(); MHEGDisplay *MHEGEngine_getDisplay(void); +MHEGVideoOutputMethod *MHEGEngine_getVideoOutputMethod(void); void MHEGEngine_TransitionTo(TransitionTo *, OctetString *); Modified: redbutton-browser/trunk/MHEGStreamPlayer.c =================================================================== --- redbutton-browser/trunk/MHEGStreamPlayer.c 2006-07-19 15:53:27 UTC (rev 131) +++ redbutton-browser/trunk/MHEGStreamPlayer.c 2006-07-28 11:30:58 UTC (rev 132) @@ -445,7 +445,7 @@ fatal("video_thread: no frames!"); /* initialise the video output method */ - MHEGVideoOutput_init(&vo); + MHEGVideoOutput_init(&vo, MHEGEngine_getVideoOutputMethod()); /* the time that we displayed the previous frame */ last_time = 0; Modified: redbutton-browser/trunk/MHEGVideoOutput.c =================================================================== --- redbutton-browser/trunk/MHEGVideoOutput.c 2006-07-19 15:53:27 UTC (rev 131) +++ redbutton-browser/trunk/MHEGVideoOutput.c 2006-07-28 11:30:58 UTC (rev 132) @@ -2,268 +2,105 @@ * MHEGVideoOutput.c */ -#include <sys/ipc.h> -#include <sys/shm.h> -#include <X11/Xlib.h> -#include <X11/Xutil.h> -#include <X11/extensions/XShm.h> -#include <ffmpeg/avformat.h> +#include <stdbool.h> +#include <string.h> #include "MHEGEngine.h" #include "MHEGVideoOutput.h" +#include "videoout_null.h" +#include "videoout_xshm.h" #include "utils.h" -void x11_shm_init(MHEGVideoOutput *); -void x11_shm_fini(MHEGVideoOutput *); -void x11_shm_prepareFrame(MHEGVideoOutput *, VideoFrame *, unsigned int, unsigned int); -void x11_shm_drawFrame(MHEGVideoOutput *, int, int); - -static void x11_shm_create_frame(MHEGVideoOutput *, unsigned int, unsigned int); -static void x11_shm_resize_frame(MHEGVideoOutput *, unsigned int, unsigned int); -static void x11_shm_destroy_frame(MHEGVideoOutput *); - -static enum PixelFormat find_av_pix_fmt(int, unsigned long, unsigned long, unsigned long); - -void -MHEGVideoOutput_init(MHEGVideoOutput *v) +static struct { - return x11_shm_init(v); -} - -void -MHEGVideoOutput_fini(MHEGVideoOutput *v) + char *name; + char *desc; + MHEGVideoOutputMethod *fns; +} vo_methods[] = { - return x11_shm_fini(v); -} + { "null", "No video output", &vo_null_fns}, + { "xshm", "Uses X11 Shared Memory", &vo_xshm_fns}, + { NULL, NULL} +}; -/* - * get ready to draw the given frame at the given output size - */ +#define DEFAULT_VO_METHOD &vo_xshm_fns -void -MHEGVideoOutput_prepareFrame(MHEGVideoOutput *v, VideoFrame *f, unsigned int out_width, unsigned int out_height) -{ - return x11_shm_prepareFrame(v, f, out_width, out_height); -} - /* - * draw the frame set up by MHEGVideoOutput_prepareFrame() at the given position on the contents Pixmap + * pass NULL to use the default */ -void -MHEGVideoOutput_drawFrame(MHEGVideoOutput *v, int x, int y) +MHEGVideoOutputMethod * +MHEGVideoOutputMethod_fromString(char *name) { - return x11_shm_drawFrame(v, x, y); -} + unsigned int i; -void -x11_shm_init(MHEGVideoOutput *v) -{ - v->current_frame = NULL; + if(name == NULL) + return DEFAULT_VO_METHOD; - v->resize_ctx = NULL; - v->resized_data = NULL; + for(i=0; vo_methods[i].name; i++) + if(strcasecmp(name, vo_methods[i].name) == 0) + return vo_methods[i].fns; - return; -} + fatal("Unknown video output method '%s'. %s", name, MHEGVideoOutputMethod_getUsage()); -void -x11_shm_fini(MHEGVideoOutput *v) -{ - if(v->resize_ctx != NULL) - { - img_resample_close(v->resize_ctx); - safe_free(v->resized_data); - } - - if(v->current_frame != NULL) - x11_shm_destroy_frame(v); - - return; + /* not reached */ + return NULL; } -void -x11_shm_prepareFrame(MHEGVideoOutput *v, VideoFrame *f, unsigned int out_width, unsigned int out_height) +/* must be big enough to hold the names of them all */ +static char _usage[512]; + +char * +MHEGVideoOutputMethod_getUsage(void) { - AVPicture *yuv_frame; - int resized_size; + unsigned int i; + char method[80]; - /* have we created the output frame yet */ - if(v->current_frame == NULL) - x11_shm_create_frame(v, out_width, out_height); + snprintf(_usage, sizeof(_usage), "Available video output methods are:"); - /* see if the output size has changed since the last frame */ - if(v->current_frame->width != out_width || v->current_frame->height != out_height) - x11_shm_resize_frame(v, out_width, out_height); - - /* see if the input size is different than the output size */ - if(f->width != out_width || f->height != out_height) + for(i=0; vo_methods[i].name; i++) { - /* have the resize input or output dimensions changed */ - if(v->resize_ctx == NULL - || v->resize_in.width != f->width || v->resize_in.height != f->height - || v->resize_out.width != out_width || v->resize_out.height != out_height) - { - /* get rid of any existing resize context */ - if(v->resize_ctx != NULL) - img_resample_close(v->resize_ctx); - if((v->resize_ctx = img_resample_init(out_width, out_height, f->width, f->height)) == NULL) - fatal("Out of memory"); - /* remember the resize input and output dimensions */ - v->resize_in.width = f->width; - v->resize_in.height = f->height; - v->resize_out.width = out_width; - v->resize_out.height = out_height; - /* somewhere to store the resized frame */ - if((resized_size = avpicture_get_size(f->pix_fmt, out_width, out_height)) < 0) - fatal("x11_shm_prepareFrame: invalid frame size"); - v->resized_data = safe_realloc(v->resized_data, resized_size); - avpicture_fill(&v->resized_frame, v->resized_data, f->pix_fmt, out_width, out_height); - } - /* resize it */ - img_resample(v->resize_ctx, &v->resized_frame, &f->frame); - yuv_frame = &v->resized_frame; + bool dflt = (vo_methods[i].fns == DEFAULT_VO_METHOD); + snprintf(method, sizeof(method), "\n%s\t%s%s", vo_methods[i].name, vo_methods[i].desc, dflt ? " (default)" : ""); + /* assumes _usage[] is big enough */ + strcat(_usage, method); } - else - { - yuv_frame = &f->frame; - } - /* convert the frame to RGB */ - img_convert(&v->rgb_frame, v->out_format, yuv_frame, f->pix_fmt, out_width, out_height); - - return; + return _usage; } void -x11_shm_drawFrame(MHEGVideoOutput *v, int x, int y) +MHEGVideoOutput_init(MHEGVideoOutput *v, MHEGVideoOutputMethod *fns) { - MHEGDisplay *d = MHEGEngine_getDisplay(); - unsigned int out_width; - unsigned int out_height; + v->fns = fns; + v->ctx = (*(v->fns->init))(); - if(v->current_frame != NULL) - { - /* video frame is already scaled as needed */ - out_width = v->current_frame->width; - out_height = v->current_frame->height; - /* draw it onto the Window contents Pixmap */ - XShmPutImage(d->dpy, d->contents, d->win_gc, v->current_frame, 0, 0, x, y, out_width, out_height, False); - /* get it drawn straight away */ - XFlush(d->dpy); - } - return; } -static void -x11_shm_create_frame(MHEGVideoOutput *v, unsigned int out_width, unsigned int out_height) +void +MHEGVideoOutput_fini(MHEGVideoOutput *v) { - MHEGDisplay *d = MHEGEngine_getDisplay(); - int rgb_size; - - if((v->current_frame = XShmCreateImage(d->dpy, d->vis, d->depth, ZPixmap, NULL, &v->shm, out_width, out_height)) == NULL) - fatal("XShmCreateImage failed"); - - /* work out what ffmpeg pixel format matches our XImage format */ - if((v->out_format = find_av_pix_fmt(v->current_frame->bits_per_pixel, - d->vis->red_mask, d->vis->green_mask, d->vis->blue_mask)) == PIX_FMT_NONE) - fatal("Unsupported XImage pixel format"); - - rgb_size = v->current_frame->bytes_per_line * out_height; - - if(rgb_size != avpicture_get_size(v->out_format, out_width, out_height)) - fatal("XImage and ffmpeg pixel formats differ"); - - if((v->shm.shmid = shmget(IPC_PRIVATE, rgb_size, IPC_CREAT | 0777)) == -1) - fatal("shmget failed"); - if((v->shm.shmaddr = shmat(v->shm.shmid, NULL, 0)) == (void *) -1) - fatal("shmat failed"); - v->shm.readOnly = True; - if(!XShmAttach(d->dpy, &v->shm)) - fatal("XShmAttach failed"); - - /* we made sure these pixel formats are the same */ - v->current_frame->data = v->shm.shmaddr; - avpicture_fill(&v->rgb_frame, v->shm.shmaddr, v->out_format, out_width, out_height); - - return; + return (*(v->fns->fini))(v->ctx); } -static void -x11_shm_resize_frame(MHEGVideoOutput *v, unsigned int out_width, unsigned int out_height) -{ -/* TODO */ -/* better if create_frame makes the max size shm we will need (ie d->xres, d->yres) */ -/* then this just updates the XImage and AVFrame params in current_frame and rgb_frame */ +/* + * get ready to draw the given frame at the given output size + */ - if(v->current_frame != NULL) - x11_shm_destroy_frame(v); - - x11_shm_create_frame(v, out_width, out_height); - - return; -} - -static void -x11_shm_destroy_frame(MHEGVideoOutput *v) +void +MHEGVideoOutput_prepareFrame(MHEGVideoOutput *v, VideoFrame *f, unsigned int out_width, unsigned int out_height) { - MHEGDisplay *d = MHEGEngine_getDisplay(); - - /* get rid of the current frame */ - /* the XImage data is our shared memory, make sure XDestroyImage doesn't try to free it */ - v->current_frame->data = NULL; - XDestroyImage(v->current_frame); - /* make sure no-one tries to use it */ - v->current_frame = NULL; - - /* get rid of the shared memory */ - XShmDetach(d->dpy, &v->shm); - shmdt(v->shm.shmaddr); - shmctl(v->shm.shmid, IPC_RMID, NULL); - - return; + return (*(v->fns->prepareFrame))(v->ctx, f, out_width, out_height); } /* - * returns a PIX_FMT_xxx type that matches the given bits per pixel and RGB bit mask values - * returns PIX_FMT_NONE if none match + * draw the frame set up by MHEGVideoOutput_prepareFrame() at the given position on the contents Pixmap */ -static enum PixelFormat -find_av_pix_fmt(int bpp, unsigned long rmask, unsigned long gmask, unsigned long bmask) +void +MHEGVideoOutput_drawFrame(MHEGVideoOutput *v, int x, int y) { - enum PixelFormat fmt; - - fmt = PIX_FMT_NONE; - switch(bpp) - { - case 32: - if(rmask == 0xff0000 && gmask == 0xff00 && bmask == 0xff) - fmt = PIX_FMT_RGBA32; - break; - - case 24: - if(rmask == 0xff0000 && gmask == 0xff00 && bmask == 0xff) - fmt = PIX_FMT_RGB24; - else if(rmask == 0xff && gmask == 0xff00 && bmask == 0xff0000) - fmt = PIX_FMT_BGR24; - break; - - case 16: - if(rmask == 0xf800 && gmask == 0x07e0 && bmask == 0x001f) - fmt = PIX_FMT_RGB565; - else if(rmask == 0x7c00 && gmask == 0x03e0 && bmask == 0x001f) - fmt = PIX_FMT_RGB555; - break; - - default: - break; - } - - if(fmt == PIX_FMT_NONE) - error("Unsupported pixel format (bpp=%d r=%lx g=%lx b=%lx)", bpp, rmask, gmask, bmask); - - return fmt; + return (*(v->fns->drawFrame))(v->ctx, x, y); } Modified: redbutton-browser/trunk/MHEGVideoOutput.h =================================================================== --- redbutton-browser/trunk/MHEGVideoOutput.h 2006-07-19 15:53:27 UTC (rev 131) +++ redbutton-browser/trunk/MHEGVideoOutput.h 2006-07-28 11:30:58 UTC (rev 132) @@ -5,31 +5,28 @@ #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; - unsigned int height; -} FrameSize; - -typedef struct -{ - XImage *current_frame; /* frame we are currently displaying */ - XShmSegmentInfo shm; /* shared memory used by current_frame */ - AVPicture rgb_frame; /* ffmpeg wrapper for current_frame SHM data */ - enum PixelFormat out_format; /* rgb_frame ffmpeg pixel format */ - ImgReSampleContext *resize_ctx; /* NULL if we do not need to resize the frame */ - FrameSize resize_in; /* resize_ctx input dimensions */ - FrameSize resize_out; /* resize_ctx output dimensions */ - AVPicture resized_frame; /* resized output frame */ - uint8_t *resized_data; /* resized_frame data buffer */ + void *ctx; /* context passed to MHEGVideoOutputFns */ + struct MHEGVideoOutputFns + { + /* return a new ctx */ + void *(*init)(void); + /* free the given ctx */ + void (*fini)(void *); + /* get ready to draw the given YUV frame at the given size */ + void (*prepareFrame)(void *, VideoFrame *, unsigned int, unsigned int); + /* draw the frame setup by prepareFrame at the given location */ + void (*drawFrame)(void *, int, int); + } *fns; } MHEGVideoOutput; -void MHEGVideoOutput_init(MHEGVideoOutput *); +typedef struct MHEGVideoOutputFns MHEGVideoOutputMethod; + +MHEGVideoOutputMethod *MHEGVideoOutputMethod_fromString(char *); +char *MHEGVideoOutputMethod_getUsage(void); + +void MHEGVideoOutput_init(MHEGVideoOutput *, MHEGVideoOutputMethod *); void MHEGVideoOutput_fini(MHEGVideoOutput *); void MHEGVideoOutput_prepareFrame(MHEGVideoOutput *, VideoFrame *, unsigned int, unsigned int); Modified: redbutton-browser/trunk/Makefile =================================================================== --- redbutton-browser/trunk/Makefile 2006-07-19 15:53:27 UTC (rev 131) +++ redbutton-browser/trunk/Makefile 2006-07-28 11:30:58 UTC (rev 132) @@ -70,6 +70,8 @@ MHEGTimer.o \ MHEGStreamPlayer.o \ MHEGVideoOutput.o \ + videoout_null.o \ + videoout_xshm.o \ MHEGAudioOutput.o \ ${CLASSES} \ ISO13522-MHEG-5.o \ Modified: redbutton-browser/trunk/rb-browser.c =================================================================== --- redbutton-browser/trunk/rb-browser.c 2006-07-19 15:53:27 UTC (rev 131) +++ redbutton-browser/trunk/rb-browser.c 2006-07-28 11:30:58 UTC (rev 132) @@ -1,8 +1,10 @@ /* - * rb-browser [-v] [-f] [-k <keymap_file>] [-t <timeout>] [-r] <service_gateway> + * rb-browser [-v] [-f] [-o <video-output-method>] [-k <keymap_file>] [-t <timeout>] [-r] <service_gateway> * * -v is verbose/debug mode * -f is full screen, otherwise it uses a window + * -o allws you to choose a video output method if the default is not supported/too slow on your graphics card + * (do 'rb-browser -o' for a list of available methods) * -k changes the default key map to the given file * (use rb-keymap to generate a keymap config file) * -t is how long to poll for missing files before generating a ContentRefError (default 10 seconds) @@ -51,10 +53,11 @@ opts.srg_loc = NULL; /* must be given on cmd line */ opts.verbose = 0; opts.fullscreen = false; + opts.vo_method = NULL; opts.timeout = MISSING_CONTENT_TIMEOUT; opts.keymap = NULL; - while((arg = getopt(argc, argv, "rvfk:t:")) != EOF) + while((arg = getopt(argc, argv, "rvfo:k:t:")) != EOF) { switch(arg) { @@ -70,6 +73,10 @@ opts.fullscreen = true; break; + case 'o': + opts.vo_method = optarg; + break; + case 'k': opts.keymap = optarg; break; @@ -128,6 +135,15 @@ void usage(char *prog_name) { - fatal("Usage: %s [-v] [-f] [-k <keymap_file>] [-t <timeout>] [-r] <service_gateway>", prog_name); + fatal("Usage: %s " + "[-v] " + "[-f] " + "[-o <video-output-method>] " + "[-k <keymap_file>] " + "[-t <timeout>] " + "[-r] " + "<service_gateway>\n\n" + "%s", + prog_name, MHEGVideoOutputMethod_getUsage()); } Added: redbutton-browser/trunk/videoout_null.c =================================================================== --- redbutton-browser/trunk/videoout_null.c (rev 0) +++ redbutton-browser/trunk/videoout_null.c 2006-07-28 11:30:58 UTC (rev 132) @@ -0,0 +1,76 @@ +/* + * videoout_null.c + */ + +#include <X11/Xlib.h> + +#include "MHEGEngine.h" +#include "MHEGVideoOutput.h" +#include "videoout_null.h" +#include "utils.h" + +void *vo_null_init(void); +void vo_null_fini(void *); +void vo_null_prepareFrame(void *, VideoFrame *, unsigned int, unsigned int); +void vo_null_drawFrame(void *, int, int); + +MHEGVideoOutputMethod vo_null_fns = +{ + vo_null_init, + vo_null_fini, + vo_null_prepareFrame, + vo_null_drawFrame +}; + +void * +vo_null_init(void) +{ + vo_null_ctx *v = safe_mallocz(sizeof(vo_null_ctx)); + MHEGDisplay *d = MHEGEngine_getDisplay(); + XGCValues gcvals; + + gcvals.foreground = BlackPixel(d->dpy, DefaultScreen(d->dpy)); + v->gc = XCreateGC(d->dpy, d->contents, GCForeground, &gcvals); + + return v; +} + +void +vo_null_fini(void *ctx) +{ + vo_null_ctx *v = (vo_null_ctx *) ctx; + MHEGDisplay *d = MHEGEngine_getDisplay(); + + if(v->gc != None) + XFreeGC(d->dpy, v->gc); + + safe_free(ctx); + + return; +} + +void +vo_null_prepareFrame(void *ctx, VideoFrame *f, unsigned int out_width, unsigned int out_height) +{ + vo_null_ctx *v = (vo_null_ctx *) ctx; + + v->width = out_width; + v->height = out_height; + + return; +} + +void +vo_null_drawFrame(void *ctx, int x, int y) +{ + vo_null_ctx *v = (vo_null_ctx *) ctx; + MHEGDisplay *d = MHEGEngine_getDisplay(); + + /* draw an empty rectangle onto the Window contents Pixmap */ + XFillRectangle(d->dpy, d->contents, v->gc, x, y, v->width, v->height); + + /* get it drawn straight away */ + XFlush(d->dpy); + + return; +} Added: redbutton-browser/trunk/videoout_null.h =================================================================== --- redbutton-browser/trunk/videoout_null.h (rev 0) +++ redbutton-browser/trunk/videoout_null.h 2006-07-28 11:30:58 UTC (rev 132) @@ -0,0 +1,19 @@ +/* + * videoout_null.h + */ + +#ifndef __VIDEOOUT_NULL_H__ +#define __VIDEOOUT_NULL_H__ + +#include <X11/Xlib.h> + +typedef struct +{ + GC gc; /* GC to draw on the content Pixmap */ + unsigned int width; /* size to output blank frame */ + unsigned int height; +} vo_null_ctx; + +extern MHEGVideoOutputMethod vo_null_fns; + +#endif /* __VIDEOOUT_NULL_H__ */ Added: redbutton-browser/trunk/videoout_xshm.c =================================================================== --- redbutton-browser/trunk/videoout_xshm.c (rev 0) +++ redbutton-browser/trunk/videoout_xshm.c 2006-07-28 11:30:58 UTC (rev 132) @@ -0,0 +1,254 @@ +/* + * videoout_xshm.c + */ + +#include <sys/ipc.h> +#include <sys/shm.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <X11/extensions/XShm.h> +#include <ffmpeg/avformat.h> + +#include "MHEGEngine.h" +#include "MHEGVideoOutput.h" +#include "videoout_xshm.h" +#include "utils.h" + +void *vo_xshm_init(void); +void vo_xshm_fini(void *); +void vo_xshm_prepareFrame(void *, VideoFrame *, unsigned int, unsigned int); +void vo_xshm_drawFrame(void *, int, int); + +MHEGVideoOutputMethod vo_xshm_fns = +{ + vo_xshm_init, + vo_xshm_fini, + vo_xshm_prepareFrame, + vo_xshm_drawFrame +}; + +static void vo_xshm_create_frame(vo_xshm_ctx *, unsigned int, unsigned int); +static void vo_xshm_resize_frame(vo_xshm_ctx *, unsigned int, unsigned int); +static void vo_xshm_destroy_frame(vo_xshm_ctx *); + +static enum PixelFormat find_av_pix_fmt(int, unsigned long, unsigned long, unsigned long); + +void * +vo_xshm_init(void) +{ + vo_xshm_ctx *v = safe_mallocz(sizeof(vo_xshm_ctx)); + + v->current_frame = NULL; + + v->resize_ctx = NULL; + v->resized_data = NULL; + + return v; +} + +void +vo_xshm_fini(void *ctx) +{ + vo_xshm_ctx *v = (vo_xshm_ctx *) ctx; + + if(v->resize_ctx != NULL) + { + img_resample_close(v->resize_ctx); + safe_free(v->resized_data); + } + + if(v->current_frame != NULL) + vo_xshm_destroy_frame(v); + + safe_free(ctx); + + return; +} + +void +vo_xshm_prepareFrame(void *ctx, VideoFrame *f, unsigned int out_width, unsigned int out_height) +{ + vo_xshm_ctx *v = (vo_xshm_ctx *) ctx; + AVPicture *yuv_frame; + int resized_size; + + /* have we created the output frame yet */ + if(v->current_frame == NULL) + vo_xshm_create_frame(v, out_width, out_height); + + /* see if the output size has changed since the last frame */ + if(v->current_frame->width != out_width || v->current_frame->height != out_height) + vo_xshm_resize_frame(v, out_width, out_height); + + /* see if the input size is different than the output size */ + if(f->width != out_width || f->height != out_height) + { + /* have the resize input or output dimensions changed */ + if(v->resize_ctx == NULL + || v->resize_in.width != f->width || v->resize_in.height != f->height + || v->resize_out.width != out_width || v->resize_out.height != out_height) + { + /* get rid of any existing resize context */ + if(v->resize_ctx != NULL) + img_resample_close(v->resize_ctx); + if((v->resize_ctx = img_resample_init(out_width, out_height, f->width, f->height)) == NULL) + fatal("Out of memory"); + /* remember the resize input and output dimensions */ + v->resize_in.width = f->width; + v->resize_in.height = f->height; + v->resize_out.width = out_width; + v->resize_out.height = out_height; + /* somewhere to store the resized frame */ + if((resized_size = avpicture_get_size(f->pix_fmt, out_width, out_height)) < 0) + fatal("x11_shm_prepareFrame: invalid frame size"); + v->resized_data = safe_realloc(v->resized_data, resized_size); + avpicture_fill(&v->resized_frame, v->resized_data, f->pix_fmt, out_width, out_height); + } + /* resize it */ + img_resample(v->resize_ctx, &v->resized_frame, &f->frame); + yuv_frame = &v->resized_frame; + } + else + { + yuv_frame = &f->frame; + } + + /* convert the frame to RGB */ + img_convert(&v->rgb_frame, v->out_format, yuv_frame, f->pix_fmt, out_width, out_height); + + return; +} + +void +vo_xshm_drawFrame(void *ctx, int x, int y) +{ + vo_xshm_ctx *v = (vo_xshm_ctx *) ctx; + MHEGDisplay *d = MHEGEngine_getDisplay(); + unsigned int out_width; + unsigned int out_height; + + if(v->current_frame != NULL) + { + /* video frame is already scaled as needed */ + out_width = v->current_frame->width; + out_height = v->current_frame->height; + /* draw it onto the Window contents Pixmap */ + XShmPutImage(d->dpy, d->contents, d->win_gc, v->current_frame, 0, 0, x, y, out_width, out_height, False); + /* get it drawn straight away */ + XFlush(d->dpy); + } + + return; +} + +static void +vo_xshm_create_frame(vo_xshm_ctx *v, unsigned int out_width, unsigned int out_height) +{ + MHEGDisplay *d = MHEGEngine_getDisplay(); + int rgb_size; + + if((v->current_frame = XShmCreateImage(d->dpy, d->vis, d->depth, ZPixmap, NULL, &v->shm, out_width, out_height)) == NULL) + fatal("XShmCreateImage failed"); + + /* work out what ffmpeg pixel format matches our XImage format */ + if((v->out_format = find_av_pix_fmt(v->current_frame->bits_per_pixel, + d->vis->red_mask, d->vis->green_mask, d->vis->blue_mask)) == PIX_FMT_NONE) + fatal("Unsupported XImage pixel format"); + + rgb_size = v->current_frame->bytes_per_line * out_height; + + if(rgb_size != avpicture_get_size(v->out_format, out_width, out_height)) + fatal("XImage and ffmpeg pixel formats differ"); + + if((v->shm.shmid = shmget(IPC_PRIVATE, rgb_size, IPC_CREAT | 0777)) == -1) + fatal("shmget failed"); + if((v->shm.shmaddr = shmat(v->shm.shmid, NULL, 0)) == (void *) -1) + fatal("shmat failed"); + v->shm.readOnly = True; + if(!XShmAttach(d->dpy, &v->shm)) + fatal("XShmAttach failed"); + + /* we made sure these pixel formats are the same */ + v->current_frame->data = v->shm.shmaddr; + avpicture_fill(&v->rgb_frame, v->shm.shmaddr, v->out_format, out_width, out_height); + + return; +} + +static void +vo_xshm_resize_frame(vo_xshm_ctx *v, unsigned int out_width, unsigned int out_height) +{ +/* TODO */ +/* better if create_frame makes the max size shm we will need (ie d->xres, d->yres) */ +/* then this just updates the XImage and AVFrame params in current_frame and rgb_frame */ + + if(v->current_frame != NULL) + vo_xshm_destroy_frame(v); + + vo_xshm_create_frame(v, out_width, out_height); + + return; +} + +static void +vo_xshm_destroy_frame(vo_xshm_ctx *v) +{ + MHEGDisplay *d = MHEGEngine_getDisplay(); + + /* get rid of the current frame */ + /* the XImage data is our shared memory, make sure XDestroyImage doesn't try to free it */ + v->current_frame->data = NULL; + XDestroyImage(v->current_frame); + /* make sure no-one tries to use it */ + v->current_frame = NULL; + + /* get rid of the shared memory */ + XShmDetach(d->dpy, &v->shm); + shmdt(v->shm.shmaddr); + shmctl(v->shm.shmid, IPC_RMID, NULL); + + return; +} + +/* + * returns a PIX_FMT_xxx type that matches the given bits per pixel and RGB bit mask values + * returns PIX_FMT_NONE if none match + */ + +static enum PixelFormat +find_av_pix_fmt(int bpp, unsigned long rmask, unsigned long gmask, unsigned long bmask) +{ + enum PixelFormat fmt; + + fmt = PIX_FMT_NONE; + switch(bpp) + { + case 32: + if(rmask == 0xff0000 && gmask == 0xff00 && bmask == 0xff) + fmt = PIX_FMT_RGBA32; + break; + + case 24: + if(rmask == 0xff0000 && gmask == 0xff00 && bmask == 0xff) + fmt = PIX_FMT_RGB24; + else if(rmask == 0xff && gmask == 0xff00 && bmask == 0xff0000) + fmt = PIX_FMT_BGR24; + break; + + case 16: + if(rmask == 0xf800 && gmask == 0x07e0 && bmask == 0x001f) + fmt = PIX_FMT_RGB565; + else if(rmask == 0x7c00 && gmask == 0x03e0 && bmask == 0x001f) + fmt = PIX_FMT_RGB555; + break; + + default: + break; + } + + if(fmt == PIX_FMT_NONE) + error("Unsupported pixel format (bpp=%d r=%lx g=%lx b=%lx)", bpp, rmask, gmask, bmask); + + return fmt; +} + Added: redbutton-browser/trunk/videoout_xshm.h =================================================================== --- redbutton-browser/trunk/videoout_xshm.h (rev 0) +++ redbutton-browser/trunk/videoout_xshm.h 2006-07-28 11:30:58 UTC (rev 132) @@ -0,0 +1,34 @@ +/* + * videoout_xshm.h + */ + +#ifndef __VIDEOOUT_XSHM_H__ +#define __VIDEOOUT_XSHM_H__ + +#include <stdint.h> +#include <X11/Xlib.h> +#include <X11/extensions/XShm.h> +#include <ffmpeg/avcodec.h> + +typedef struct +{ + unsigned int width; + unsigned int height; +} FrameSize; + +typedef struct +{ + XImage *current_frame; /* frame we are currently displaying */ + XShmSegmentInfo shm; /* shared memory used by current_frame */ + AVPicture rgb_frame; /* ffmpeg wrapper for current_frame SHM data */ + enum PixelFormat out_format; /* rgb_frame ffmpeg pixel format */ + ImgReSampleContext *resize_ctx; /* NULL if we do not need to resize the frame */ + FrameSize resize_in; /* resize_ctx input dimensions */ + FrameSize resize_out; /* resize_ctx output dimensions */ + AVPicture resized_frame; /* resized output frame */ + uint8_t *resized_data; /* resized_frame data buffer */ +} vo_xshm_ctx; + +extern MHEGVideoOutputMethod vo_xshm_fns; + +#endif /* __VIDEOOUT_XSHM_H__ */ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <ski...@us...> - 2006-07-28 21:17:48
|
Revision: 133 Author: skilvington Date: 2006-07-28 14:17:34 -0700 (Fri, 28 Jul 2006) ViewCVS: http://svn.sourceforge.net/redbutton/?rev=133&view=rev Log Message: ----------- fix typos from previous commit Modified Paths: -------------- redbutton-browser/trunk/MHEGVideoOutput.c redbutton-browser/trunk/rb-browser.c redbutton-browser/trunk/videoout_xshm.c Modified: redbutton-browser/trunk/MHEGVideoOutput.c =================================================================== --- redbutton-browser/trunk/MHEGVideoOutput.c 2006-07-28 11:30:58 UTC (rev 132) +++ redbutton-browser/trunk/MHEGVideoOutput.c 2006-07-28 21:17:34 UTC (rev 133) @@ -72,6 +72,10 @@ void MHEGVideoOutput_init(MHEGVideoOutput *v, MHEGVideoOutputMethod *fns) { + /* assert */ + if(fns == NULL) + fatal("MHEGVideoOutput_init: video output method not defined"); + v->fns = fns; v->ctx = (*(v->fns->init))(); Modified: redbutton-browser/trunk/rb-browser.c =================================================================== --- redbutton-browser/trunk/rb-browser.c 2006-07-28 11:30:58 UTC (rev 132) +++ redbutton-browser/trunk/rb-browser.c 2006-07-28 21:17:34 UTC (rev 133) @@ -3,7 +3,7 @@ * * -v is verbose/debug mode * -f is full screen, otherwise it uses a window - * -o allws you to choose a video output method if the default is not supported/too slow on your graphics card + * -o allows you to choose a video output method if the default is not supported/too slow on your graphics card * (do 'rb-browser -o' for a list of available methods) * -k changes the default key map to the given file * (use rb-keymap to generate a keymap config file) Modified: redbutton-browser/trunk/videoout_xshm.c =================================================================== --- redbutton-browser/trunk/videoout_xshm.c 2006-07-28 11:30:58 UTC (rev 132) +++ redbutton-browser/trunk/videoout_xshm.c 2006-07-28 21:17:34 UTC (rev 133) @@ -100,7 +100,7 @@ v->resize_out.height = out_height; /* somewhere to store the resized frame */ if((resized_size = avpicture_get_size(f->pix_fmt, out_width, out_height)) < 0) - fatal("x11_shm_prepareFrame: invalid frame size"); + fatal("vo_xshm_prepareFrame: invalid frame size"); v->resized_data = safe_realloc(v->resized_data, resized_size); avpicture_fill(&v->resized_frame, v->resized_data, f->pix_fmt, out_width, out_height); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <ski...@us...> - 2006-08-25 15:34:25
|
Revision: 138 Author: skilvington Date: 2006-08-25 08:34:16 -0700 (Fri, 25 Aug 2006) ViewCVS: http://svn.sourceforge.net/redbutton/?rev=138&view=rev Log Message: ----------- don't try to display video if we failed to open the MPEG stream Modified Paths: -------------- redbutton-browser/trunk/MHEGStreamPlayer.c redbutton-browser/trunk/VideoClass.c redbutton-browser/trunk/add_instance_vars.conf Modified: redbutton-browser/trunk/MHEGStreamPlayer.c =================================================================== --- redbutton-browser/trunk/MHEGStreamPlayer.c 2006-08-25 10:35:11 UTC (rev 137) +++ redbutton-browser/trunk/MHEGStreamPlayer.c 2006-08-25 15:34:16 UTC (rev 138) @@ -164,6 +164,10 @@ { verbose("MHEGStreamPlayer_play: audio_tag=%d video_tag=%d", p->audio_tag, p->video_tag); + /* make sure the VideoClass doesn't try to draw anything yet */ + if(p->video != NULL) + p->video->inst.no_video = true; + p->audio_pid = p->audio_tag; p->video_pid = p->video_tag; if((p->ts = MHEGEngine_openStream(p->have_audio, &p->audio_pid, &p->audio_type, @@ -173,6 +177,10 @@ return; } + /* let the VideoClass know we now have a video stream */ + if(p->video != NULL) + p->video->inst.no_video = false; + p->playing = true; p->stop = false; Modified: redbutton-browser/trunk/VideoClass.c =================================================================== --- redbutton-browser/trunk/VideoClass.c 2006-08-25 10:35:11 UTC (rev 137) +++ redbutton-browser/trunk/VideoClass.c 2006-08-25 15:34:16 UTC (rev 138) @@ -34,6 +34,8 @@ pthread_mutex_init(&v->scaled_lock, NULL); v->scaled = false; + v->no_video = false; + return; } @@ -376,6 +378,10 @@ verbose("VideoClass: %s; render", ExternalReference_name(&t->rootClass.inst.ref)); + /* if the MHEGStreamPlayer failed to open the video stream, don't display anything */ + if(t->inst.no_video) + return; + if(!intersects(pos, box, &t->inst.Position, &t->inst.BoxSize, &ins_pos, &ins_box)) return; Modified: redbutton-browser/trunk/add_instance_vars.conf =================================================================== --- redbutton-browser/trunk/add_instance_vars.conf 2006-08-25 10:35:11 UTC (rev 137) +++ redbutton-browser/trunk/add_instance_vars.conf 2006-08-25 15:34:16 UTC (rev 138) @@ -184,6 +184,8 @@ bool scaled; unsigned int scaled_width; unsigned int scaled_height; + /* this gets set if the MHEGStreamPlayer fails to open the video stream */ + bool no_video; } VideoClassInstanceVars; </VideoClass> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
|
From: <ski...@us...> - 2006-09-01 16:10:22
|
Revision: 141
http://svn.sourceforge.net/redbutton/?rev=141&view=rev
Author: skilvington
Date: 2006-09-01 09:08:41 -0700 (Fri, 01 Sep 2006)
Log Message:
-----------
use ffmpeg to decode MPEG I-frame bitmaps rather than libmpeg2 (also gets the colours correct now)
Modified Paths:
--------------
redbutton-browser/trunk/MHEGDisplay.c
redbutton-browser/trunk/Makefile
Modified: redbutton-browser/trunk/MHEGDisplay.c
===================================================================
--- redbutton-browser/trunk/MHEGDisplay.c 2006-09-01 16:07:41 UTC (rev 140)
+++ redbutton-browser/trunk/MHEGDisplay.c 2006-09-01 16:08:41 UTC (rev 141)
@@ -13,8 +13,6 @@
#include <X11/Intrinsic.h>
#include <X11/Shell.h>
#include <X11/keysym.h>
-#include <mpeg2dec/mpeg2.h>
-#include <mpeg2dec/mpeg2convert.h>
#include <ffmpeg/avformat.h>
#include "MHEGEngine.h"
@@ -767,78 +765,95 @@
MHEGDisplay_newMPEGBitmap(MHEGDisplay *d, OctetString *mpeg)
{
MHEGBitmap *b;
- mpeg2dec_t *decoder;
- const mpeg2_info_t *info;
- bool done;
- unsigned int width = 0; /* keep the compiler happy */
- unsigned int height = 0; /* keep the compiler happy */
- unsigned char *rgba = NULL; /* keep the compiler happy */
+ AVCodecContext *codec_ctx;
+ AVCodec *codec;
+ AVFrame *yuv_frame;
+ AVFrame *rgb_frame;
+ unsigned char *data;
+ unsigned int size;
+ int used;
+ int got_picture;
+ unsigned int width;
+ unsigned int height;
+ int nbytes;
+ unsigned char *rgba = NULL;
unsigned int i;
/* nothing to do */
if(mpeg == NULL || mpeg->size == 0)
return NULL;
- /* use libmpeg2 to convert the data into a standard format we can use as an XImage */
- if((decoder = mpeg2_init()) == NULL)
- {
- error("Unable to initialise MPEG decoder");
- return NULL;
- }
- info = mpeg2_info(decoder);
+ /* use ffmpeg to convert the data into a standard format we can use as an XImage */
+ if((codec_ctx = avcodec_alloc_context()) == NULL)
+ fatal("Out of memory");
- /* feed all the data into the buffer */
- mpeg2_buffer(decoder, mpeg->data, mpeg->data + mpeg->size);
+ if((codec = avcodec_find_decoder(CODEC_ID_MPEG2VIDEO)) == NULL)
+ fatal("Unable to initialise MPEG decoder");
- done = false;
+ if(avcodec_open(codec_ctx, codec) < 0)
+ fatal("Unable to open video codec");
+
+ if((yuv_frame = avcodec_alloc_frame()) == NULL)
+ fatal("Out of memory");
+ if((rgb_frame = avcodec_alloc_frame()) == NULL)
+ fatal("Out of memory");
+
+ /* decode the YUV frame */
+ data = mpeg->data;
+ size = mpeg->size;
do
{
- mpeg2_state_t state = mpeg2_parse(decoder);
- switch(state)
+ used = avcodec_decode_video(codec_ctx, yuv_frame, &got_picture, data, size);
+ data += used;
+ size -= used;
+ }
+ while(!got_picture && size > 0);
+ /* need to call it one final time with size=0, to actually get the frame */
+ if(!got_picture)
+ (void) avcodec_decode_video(codec_ctx, yuv_frame, &got_picture, data, size);
+
+ if(!got_picture)
+ {
+ error("Unable to decode MPEG image");
+ b = NULL;
+ }
+ else
+ {
+ /* convert to RGBA */
+ width = codec_ctx->width;
+ height = codec_ctx->height;
+ if((nbytes = avpicture_get_size(PIX_FMT_RGBA32, width, height)) < 0)
+ fatal("Invalid MPEG image");
+ rgba = safe_malloc(nbytes);
+ avpicture_fill((AVPicture *) rgb_frame, rgba, PIX_FMT_RGBA32, width, height);
+ img_convert((AVPicture *) rgb_frame, PIX_FMT_RGBA32, (AVPicture*) yuv_frame, codec_ctx->pix_fmt, width, height);
+ /*
+ * ffmpeg always stores PIX_FMT_RGBA32 as
+ * (A << 24) | (R << 16) | (G << 8) | B
+ * no matter what byte order our CPU uses. ie,
+ * it is stored as BGRA on little endian CPU architectures and ARGB on big endian CPUs
+ * we need RGBA, so swap the components as needed
+ */
+ for(i=0; i<width*height; i++)
{
- case STATE_BUFFER:
- /*
- * we've already filled the buffer with all the data
- * if the decoder needs more, the data is probably invalid
- */
- error("Unable to decode MPEG image");
- mpeg2_close(decoder);
- return NULL;
-
- case STATE_SEQUENCE:
- mpeg2_convert(decoder, mpeg2convert_rgb32, NULL);
- break;
-
- case STATE_SLICE:
- case STATE_END:
- case STATE_INVALID_END:
- /* do we have a picture */
- if(info->display_fbuf)
- {
- width = info->sequence->width;
- height = info->sequence->height;
- rgba = info->display_fbuf->buf[0];
- /* set the alpha channel values to opaque */
- for(i=0; i<width*height; i++)
- rgba[(i * 4) + 3] = 0xff;
- done = true;
- }
- break;
-
- default:
- break;
+ uint32_t pix = *((uint32_t *) &rgba[(i * 4)]);
+ rgba[(i * 4) + 0] = (pix >> 16) & 0xff; /* R */
+ rgba[(i * 4) + 1] = (pix >> 8) & 0xff; /* G */
+ rgba[(i * 4) + 2] = pix & 0xff; /* B */
+ rgba[(i * 4) + 3] = 0xff; /* opaque */
}
+ /*
+ * we now have an array of 32-bit RGBA pixels in network byte order
+ * ie if pix is a char *: pix[0] = R, pix[1] = G, pix[2] = B, pix[3] = A
+ */
+ b = MHEGBitmap_fromRGBA(d, rgba, width, height);
}
- while(!done);
- /*
- * we now have an array of 32-bit RGBA pixels in network byte order
- * ie if pix is a char *: pix[0] = R, pix[1] = G, pix[2] = B, pix[3] = A
- */
- b = MHEGBitmap_fromRGBA(d, rgba, width, height);
-
/* clean up */
- mpeg2_close(decoder);
+ safe_free(rgba);
+ av_free(yuv_frame);
+ av_free(rgb_frame);
+ avcodec_close(codec_ctx);
return b;
}
Modified: redbutton-browser/trunk/Makefile
===================================================================
--- redbutton-browser/trunk/Makefile 2006-09-01 16:07:41 UTC (rev 140)
+++ redbutton-browser/trunk/Makefile 2006-09-01 16:08:41 UTC (rev 141)
@@ -7,7 +7,7 @@
# safe_malloc debugging
#DEFS=-DDEBUG_ALLOC -D_REENTRANT -D_GNU_SOURCE
INCS=`freetype-config --cflags`
-LIBS=-lm -lz -L/usr/X11R6/lib -lX11 -lXext -lXt -lXrender -lXft -lpng -lmpeg2 -lmpeg2convert -lavformat -lavcodec -lasound -lpthread
+LIBS=-lm -lz -L/usr/X11R6/lib -lX11 -lXext -lXt -lXrender -lXft -lpng -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-10-08 08:45:28
|
Revision: 147
http://svn.sourceforge.net/redbutton/?rev=147&view=rev
Author: skilvington
Date: 2006-10-08 01:45:09 -0700 (Sun, 08 Oct 2006)
Log Message:
-----------
corrigendum says ignore context-changing actions in OnStartUp and OnCloseDown
Modified Paths:
--------------
redbutton-browser/trunk/ActionClass.c
redbutton-browser/trunk/MHEGEngine.c
redbutton-browser/trunk/TokenGroupClass.c
Modified: redbutton-browser/trunk/ActionClass.c
===================================================================
--- redbutton-browser/trunk/ActionClass.c 2006-09-20 09:00:19 UTC (rev 146)
+++ redbutton-browser/trunk/ActionClass.c 2006-10-08 08:45:09 UTC (rev 147)
@@ -9,6 +9,9 @@
/*
* caller_gid should be the group identifier of the object containing the ActionClass
* it is used to resolve the ObjectReference's in the ElementaryAction's
+ * this function should only be called to run OnStartUp and OnCloseDown actions
+ * all other times (ie CallActionSlot) use MHEGEngine_addToTempActionQ instead
+ * Corrigendum says we should ignore context changing actions - TransitionTo, Launch, Spawn and Quit
*/
void
@@ -18,7 +21,14 @@
while(list)
{
- ElementaryAction_execute(&list->item, caller_gid);
+ unsigned int type = list->item.choice;
+ if(type == ElementaryAction_transition_to
+ || type == ElementaryAction_launch
+ || type == ElementaryAction_spawn
+ || type == ElementaryAction_quit)
+ error("ActionClass: ignoring %s in OnStartup/OnCloseDown actions", ElementaryAction_name(&list->item));
+ else
+ ElementaryAction_execute(&list->item, caller_gid);
list = list->next;
}
Modified: redbutton-browser/trunk/MHEGEngine.c
===================================================================
--- redbutton-browser/trunk/MHEGEngine.c 2006-09-20 09:00:19 UTC (rev 146)
+++ redbutton-browser/trunk/MHEGEngine.c 2006-10-08 08:45:09 UTC (rev 147)
@@ -348,14 +348,6 @@
safe_free(scene_id.data);
return;
}
-#if 0
-/* TODO */
-/* should we do this before or after we destroy the current scene? */
- /* empty the Async event queue and any pending actions */
- LIST_FREE(&engine.async_eventq, MHEGAsyncEvent, free_MHEGAsyncEventListItem);
- LIST_FREE(&engine.main_actionq, MHEGAction, free_MHEGActionListItem);
- LIST_FREE(&engine.temp_actionq, MHEGAction, free_MHEGActionListItem);
-#endif
/*
* do Deactivation of all Ingredients in the current app that are not shared
* in the reverse order they appear in the items list
@@ -377,9 +369,7 @@
SceneClass_Deactivation(current_scene);
SceneClass_Destruction(current_scene);
}
-/* TODO */
-/* should we do this before or after we destroy the current scene? */
- /* empty the Async event queue and any pending actions */
+ /* now the old scene is destroyed, empty the Async event queue and any pending actions */
LIST_FREE(&engine.async_eventq, MHEGAsyncEvent, free_MHEGAsyncEventListItem);
LIST_FREE(&engine.main_actionq, MHEGAction, free_MHEGActionListItem);
LIST_FREE(&engine.temp_actionq, MHEGAction, free_MHEGActionListItem);
Modified: redbutton-browser/trunk/TokenGroupClass.c
===================================================================
--- redbutton-browser/trunk/TokenGroupClass.c 2006-09-20 09:00:19 UTC (rev 146)
+++ redbutton-browser/trunk/TokenGroupClass.c 2006-10-08 08:45:09 UTC (rev 147)
@@ -314,7 +314,8 @@
* if the action is not Null, add the ElementaryActions to temp_actionq
* note, just doing:
* ActionClass_execute(&action->item.u.action_class, &t->rootClass.inst.ref.group_identifier);
- * does not work - it makes some BBC apps get into an infinite loop
+ * is not the same as adding the actions to the queue
+ * (also ActionClass_execute will ignore context changing actions - TransitionTo, Launch, Spawn and Quit)
*/
if(action->item.choice == ActionSlot_action_class)
MHEGEngine_addToTempActionQ(&action->item.u.action_class, &t->rootClass.inst.ref.group_identifier);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2006-11-05 10:30:54
|
Revision: 149
http://svn.sourceforge.net/redbutton/?rev=149&view=rev
Author: skilvington
Date: 2006-11-05 02:30:39 -0800 (Sun, 05 Nov 2006)
Log Message:
-----------
don't convert pixel formats more than we need to
Modified Paths:
--------------
redbutton-browser/trunk/MHEGDisplay.c
redbutton-browser/trunk/utils.c
redbutton-browser/trunk/utils.h
redbutton-browser/trunk/videoout_xshm.c
Modified: redbutton-browser/trunk/MHEGDisplay.c
===================================================================
--- redbutton-browser/trunk/MHEGDisplay.c 2006-10-12 10:00:30 UTC (rev 148)
+++ redbutton-browser/trunk/MHEGDisplay.c 2006-11-05 10:30:39 UTC (rev 149)
@@ -756,13 +756,28 @@
*/
for(i=0; i<width*height; i++)
{
- uint8_t r = rgba[(i * 4) + 0];
- uint8_t g = rgba[(i * 4) + 1];
- uint8_t b = rgba[(i * 4) + 2];
- uint8_t a = rgba[(i * 4) + 3];
-/* TODO */
-/* if we still need to do r=g=b=0 when a=0, do it here */
- uint32_t pix = (a << 24) | (r << 16) | (g << 8) | b;
+ uint8_t a, r, g, b;
+ uint32_t pix;
+ /*
+ * if the pixel is transparent, set the RGB components to 0
+ * otherwise, if we scale up the bitmap in fullscreen mode,
+ * we may end up with a border around the image
+ * this happens, for example, with the BBC's "Press Red" image
+ * it has a transparent box around it, but the RGB values are not 0 in the transparent area
+ * when we scale it up we get a pink border around it
+ */
+ a = rgba[(i * 4) + 3];
+ if(a == 0)
+ {
+ pix = 0;
+ }
+ else
+ {
+ r = rgba[(i * 4) + 0];
+ g = rgba[(i * 4) + 1];
+ b = rgba[(i * 4) + 2];
+ pix = (a << 24) | (r << 16) | (g << 8) | b;
+ }
*((uint32_t *) &rgba[i * 4]) = pix;
}
@@ -890,6 +905,7 @@
unsigned int i, npixs;
XImage *ximg;
XRenderPictFormat *pic_format;
+ enum PixelFormat av_format;
GC gc;
bitmap = safe_malloc(sizeof(MHEGBitmap));
@@ -897,41 +913,44 @@
/* find a matching XRender pixel format */
pic_format = XRenderFindStandardFormat(d->dpy, PictStandardARGB32);
+ av_format = find_av_pix_fmt(32,
+ pic_format->direct.redMask << pic_format->direct.red,
+ pic_format->direct.greenMask << pic_format->direct.green,
+ pic_format->direct.blueMask << pic_format->direct.blue);
/* copy the RGBA values into a block we can use as XImage data */
npixs = width * height;
/* 4 bytes per pixel */
xdata = safe_malloc(npixs * 4);
- /*
- * copy the pixels, converting them to our XRender RGBA order as we go
- * even if the XRender pixel layout is the same as the ffmpeg one we still process each pixel
- * because we want to make sure transparent pixels have 0 for their RGB components
- * otherwise, if we scale up the bitmap in fullscreen mode and apply our bilinear filter,
- * we may end up with a border around the image
- * this happens, for example, with the BBC's "Press Red" image
- * it has a transparent box around it, but the RGB values are not 0 in the transparent area
- * when we scale it up we get a pink border around it
- */
- for(i=0; i<npixs; i++)
+ /* are the pixel layouts exactly the same */
+ if(av_format == PIX_FMT_RGBA32)
{
- rgba_pix = *((uint32_t *) &rgba[i * 4]);
- a = (rgba_pix >> 24) & 0xff;
- r = (rgba_pix >> 16) & 0xff;
- g = (rgba_pix >> 8) & 0xff;
- b = rgba_pix & 0xff;
- /* is it transparent */
- if(a == 0)
+ memcpy(xdata, rgba, npixs * 4);
+ }
+ else
+ {
+ /* swap the RGBA components as needed */
+ for(i=0; i<npixs; i++)
{
- xpix = 0;
+ rgba_pix = *((uint32_t *) &rgba[i * 4]);
+ a = (rgba_pix >> 24) & 0xff;
+ r = (rgba_pix >> 16) & 0xff;
+ g = (rgba_pix >> 8) & 0xff;
+ b = rgba_pix & 0xff;
+ /* is it transparent */
+ if(a == 0)
+ {
+ xpix = 0;
+ }
+ else
+ {
+ xpix = a << pic_format->direct.alpha;
+ xpix |= r << pic_format->direct.red;
+ xpix |= g << pic_format->direct.green;
+ xpix |= b << pic_format->direct.blue;
+ }
+ *((uint32_t *) &xdata[i * 4]) = xpix;
}
- else
- {
- xpix = a << pic_format->direct.alpha;
- xpix |= r << pic_format->direct.red;
- xpix |= g << pic_format->direct.green;
- xpix |= b << pic_format->direct.blue;
- }
- *((uint32_t *) &xdata[i * 4]) = xpix;
}
/* get X to draw the XImage onto a Pixmap */
Modified: redbutton-browser/trunk/utils.c
===================================================================
--- redbutton-browser/trunk/utils.c 2006-10-12 10:00:30 UTC (rev 148)
+++ redbutton-browser/trunk/utils.c 2006-11-05 10:30:39 UTC (rev 149)
@@ -31,6 +31,48 @@
#include "utils.h"
/*
+ * returns a PIX_FMT_xxx type that matches the given bits per pixel and RGB bit mask values
+ * returns PIX_FMT_NONE if none match
+ */
+
+enum PixelFormat
+find_av_pix_fmt(int bpp, unsigned long rmask, unsigned long gmask, unsigned long bmask)
+{
+ enum PixelFormat fmt;
+
+ fmt = PIX_FMT_NONE;
+ switch(bpp)
+ {
+ case 32:
+ if(rmask == 0xff0000 && gmask == 0xff00 && bmask == 0xff)
+ fmt = PIX_FMT_RGBA32;
+ break;
+
+ case 24:
+ if(rmask == 0xff0000 && gmask == 0xff00 && bmask == 0xff)
+ fmt = PIX_FMT_RGB24;
+ else if(rmask == 0xff && gmask == 0xff00 && bmask == 0xff0000)
+ fmt = PIX_FMT_BGR24;
+ break;
+
+ case 16:
+ if(rmask == 0xf800 && gmask == 0x07e0 && bmask == 0x001f)
+ fmt = PIX_FMT_RGB565;
+ else if(rmask == 0x7c00 && gmask == 0x03e0 && bmask == 0x001f)
+ fmt = PIX_FMT_RGB555;
+ break;
+
+ default:
+ break;
+ }
+
+ if(fmt == PIX_FMT_NONE)
+ error("Unsupported pixel format (bpp=%d r=%lx g=%lx b=%lx)", bpp, rmask, gmask, bmask);
+
+ return fmt;
+}
+
+/*
* returns 15 for 'f' etc
*/
Modified: redbutton-browser/trunk/utils.h
===================================================================
--- redbutton-browser/trunk/utils.h 2006-10-12 10:00:30 UTC (rev 148)
+++ redbutton-browser/trunk/utils.h 2006-11-05 10:30:39 UTC (rev 149)
@@ -25,6 +25,7 @@
#include <stdlib.h>
#include <stdarg.h>
+#include <ffmpeg/avformat.h>
#ifndef MIN
#define MIN(a, b) ((a) < (b) ? (a) : (b))
@@ -33,6 +34,8 @@
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#endif
+enum PixelFormat find_av_pix_fmt(int, unsigned long, unsigned long, unsigned long);
+
unsigned int char2hex(unsigned char);
int next_utf8(unsigned char *, int, int *);
Modified: redbutton-browser/trunk/videoout_xshm.c
===================================================================
--- redbutton-browser/trunk/videoout_xshm.c 2006-10-12 10:00:30 UTC (rev 148)
+++ redbutton-browser/trunk/videoout_xshm.c 2006-11-05 10:30:39 UTC (rev 149)
@@ -31,8 +31,6 @@
static void vo_xshm_resize_frame(vo_xshm_ctx *, unsigned int, unsigned int);
static void vo_xshm_destroy_frame(vo_xshm_ctx *);
-static enum PixelFormat find_av_pix_fmt(int, unsigned long, unsigned long, unsigned long);
-
void *
vo_xshm_init(void)
{
@@ -210,45 +208,3 @@
return;
}
-/*
- * returns a PIX_FMT_xxx type that matches the given bits per pixel and RGB bit mask values
- * returns PIX_FMT_NONE if none match
- */
-
-static enum PixelFormat
-find_av_pix_fmt(int bpp, unsigned long rmask, unsigned long gmask, unsigned long bmask)
-{
- enum PixelFormat fmt;
-
- fmt = PIX_FMT_NONE;
- switch(bpp)
- {
- case 32:
- if(rmask == 0xff0000 && gmask == 0xff00 && bmask == 0xff)
- fmt = PIX_FMT_RGBA32;
- break;
-
- case 24:
- if(rmask == 0xff0000 && gmask == 0xff00 && bmask == 0xff)
- fmt = PIX_FMT_RGB24;
- else if(rmask == 0xff && gmask == 0xff00 && bmask == 0xff0000)
- fmt = PIX_FMT_BGR24;
- break;
-
- case 16:
- if(rmask == 0xf800 && gmask == 0x07e0 && bmask == 0x001f)
- fmt = PIX_FMT_RGB565;
- else if(rmask == 0x7c00 && gmask == 0x03e0 && bmask == 0x001f)
- fmt = PIX_FMT_RGB555;
- break;
-
- default:
- break;
- }
-
- if(fmt == PIX_FMT_NONE)
- error("Unsupported pixel format (bpp=%d r=%lx g=%lx b=%lx)", bpp, rmask, gmask, bmask);
-
- return fmt;
-}
-
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: Mario R. <mar...@go...> - 2006-11-05 18:45:33
|
Not sure whether it has anything to do, but the behaviour has improved: - BBC ONE I get a smooth video - ITV1 video still bad, fixed on the first image - I can actually close the application with the mouse click - When I am on page 120 of ITV I get a strange behviour. If I press <- -> only it goes smoothly across the 14 pages. But if I use pressing all 4 arrows (one at a time of course), like down till the bottom and then right right (or more complex combinations of the arrows) it does not go through all 14 pages but it follows some strange path. Until I finally go to an other page and back again to 120 where it is ok. - still a lot of [mp3 @ 0xb7e71984]incorrect frame size On 11/5/06, ski...@us... <ski...@us...> wrote: > Revision: 149 > http://svn.sourceforge.net/redbutton/?rev=149&view=rev > Author: skilvington > Date: 2006-11-05 02:30:39 -0800 (Sun, 05 Nov 2006) > > Log Message: > ----------- > don't convert pixel formats more than we need to > > Modified Paths: > -------------- > redbutton-browser/trunk/MHEGDisplay.c > redbutton-browser/trunk/utils.c > redbutton-browser/trunk/utils.h > redbutton-browser/trunk/videoout_xshm.c > > Modified: redbutton-browser/trunk/MHEGDisplay.c > =================================================================== > --- redbutton-browser/trunk/MHEGDisplay.c 2006-10-12 10:00:30 UTC (rev 148) > +++ redbutton-browser/trunk/MHEGDisplay.c 2006-11-05 10:30:39 UTC (rev 149) > @@ -756,13 +756,28 @@ > */ > for(i=0; i<width*height; i++) > { > - uint8_t r = rgba[(i * 4) + 0]; > - uint8_t g = rgba[(i * 4) + 1]; > - uint8_t b = rgba[(i * 4) + 2]; > - uint8_t a = rgba[(i * 4) + 3]; > -/* TODO */ > -/* if we still need to do r=g=b=0 when a=0, do it here */ > - uint32_t pix = (a << 24) | (r << 16) | (g << 8) | b; > + uint8_t a, r, g, b; > + uint32_t pix; > + /* > + * if the pixel is transparent, set the RGB components to 0 > + * otherwise, if we scale up the bitmap in fullscreen mode, > + * we may end up with a border around the image > + * this happens, for example, with the BBC's "Press Red" image > + * it has a transparent box around it, but the RGB values are not 0 in the transparent area > + * when we scale it up we get a pink border around it > + */ > + a = rgba[(i * 4) + 3]; > + if(a == 0) > + { > + pix = 0; > + } > + else > + { > + r = rgba[(i * 4) + 0]; > + g = rgba[(i * 4) + 1]; > + b = rgba[(i * 4) + 2]; > + pix = (a << 24) | (r << 16) | (g << 8) | b; > + } > *((uint32_t *) &rgba[i * 4]) = pix; > } > > @@ -890,6 +905,7 @@ > unsigned int i, npixs; > XImage *ximg; > XRenderPictFormat *pic_format; > + enum PixelFormat av_format; > GC gc; > > bitmap = safe_malloc(sizeof(MHEGBitmap)); > @@ -897,41 +913,44 @@ > > /* find a matching XRender pixel format */ > pic_format = XRenderFindStandardFormat(d->dpy, PictStandardARGB32); > + av_format = find_av_pix_fmt(32, > + pic_format->direct.redMask << pic_format->direct.red, > + pic_format->direct.greenMask << pic_format->direct.green, > + pic_format->direct.blueMask << pic_format->direct.blue); > > /* copy the RGBA values into a block we can use as XImage data */ > npixs = width * height; > /* 4 bytes per pixel */ > xdata = safe_malloc(npixs * 4); > - /* > - * copy the pixels, converting them to our XRender RGBA order as we go > - * even if the XRender pixel layout is the same as the ffmpeg one we still process each pixel > - * because we want to make sure transparent pixels have 0 for their RGB components > - * otherwise, if we scale up the bitmap in fullscreen mode and apply our bilinear filter, > - * we may end up with a border around the image > - * this happens, for example, with the BBC's "Press Red" image > - * it has a transparent box around it, but the RGB values are not 0 in the transparent area > - * when we scale it up we get a pink border around it > - */ > - for(i=0; i<npixs; i++) > + /* are the pixel layouts exactly the same */ > + if(av_format == PIX_FMT_RGBA32) > { > - rgba_pix = *((uint32_t *) &rgba[i * 4]); > - a = (rgba_pix >> 24) & 0xff; > - r = (rgba_pix >> 16) & 0xff; > - g = (rgba_pix >> 8) & 0xff; > - b = rgba_pix & 0xff; > - /* is it transparent */ > - if(a == 0) > + memcpy(xdata, rgba, npixs * 4); > + } > + else > + { > + /* swap the RGBA components as needed */ > + for(i=0; i<npixs; i++) > { > - xpix = 0; > + rgba_pix = *((uint32_t *) &rgba[i * 4]); > + a = (rgba_pix >> 24) & 0xff; > + r = (rgba_pix >> 16) & 0xff; > + g = (rgba_pix >> 8) & 0xff; > + b = rgba_pix & 0xff; > + /* is it transparent */ > + if(a == 0) > + { > + xpix = 0; > + } > + else > + { > + xpix = a << pic_format->direct.alpha; > + xpix |= r << pic_format->direct.red; > + xpix |= g << pic_format->direct.green; > + xpix |= b << pic_format->direct.blue; > + } > + *((uint32_t *) &xdata[i * 4]) = xpix; > } > - else > - { > - xpix = a << pic_format->direct.alpha; > - xpix |= r << pic_format->direct.red; > - xpix |= g << pic_format->direct.green; > - xpix |= b << pic_format->direct.blue; > - } > - *((uint32_t *) &xdata[i * 4]) = xpix; > } > > /* get X to draw the XImage onto a Pixmap */ > > Modified: redbutton-browser/trunk/utils.c > =================================================================== > --- redbutton-browser/trunk/utils.c 2006-10-12 10:00:30 UTC (rev 148) > +++ redbutton-browser/trunk/utils.c 2006-11-05 10:30:39 UTC (rev 149) > @@ -31,6 +31,48 @@ > #include "utils.h" > > /* > + * returns a PIX_FMT_xxx type that matches the given bits per pixel and RGB bit mask values > + * returns PIX_FMT_NONE if none match > + */ > + > +enum PixelFormat > +find_av_pix_fmt(int bpp, unsigned long rmask, unsigned long gmask, unsigned long bmask) > +{ > + enum PixelFormat fmt; > + > + fmt = PIX_FMT_NONE; > + switch(bpp) > + { > + case 32: > + if(rmask == 0xff0000 && gmask == 0xff00 && bmask == 0xff) > + fmt = PIX_FMT_RGBA32; > + break; > + > + case 24: > + if(rmask == 0xff0000 && gmask == 0xff00 && bmask == 0xff) > + fmt = PIX_FMT_RGB24; > + else if(rmask == 0xff && gmask == 0xff00 && bmask == 0xff0000) > + fmt = PIX_FMT_BGR24; > + break; > + > + case 16: > + if(rmask == 0xf800 && gmask == 0x07e0 && bmask == 0x001f) > + fmt = PIX_FMT_RGB565; > + else if(rmask == 0x7c00 && gmask == 0x03e0 && bmask == 0x001f) > + fmt = PIX_FMT_RGB555; > + break; > + > + default: > + break; > + } > + > + if(fmt == PIX_FMT_NONE) > + error("Unsupported pixel format (bpp=%d r=%lx g=%lx b=%lx)", bpp, rmask, gmask, bmask); > + > + return fmt; > +} > + > +/* > * returns 15 for 'f' etc > */ > > > Modified: redbutton-browser/trunk/utils.h > =================================================================== > --- redbutton-browser/trunk/utils.h 2006-10-12 10:00:30 UTC (rev 148) > +++ redbutton-browser/trunk/utils.h 2006-11-05 10:30:39 UTC (rev 149) > @@ -25,6 +25,7 @@ > > #include <stdlib.h> > #include <stdarg.h> > +#include <ffmpeg/avformat.h> > > #ifndef MIN > #define MIN(a, b) ((a) < (b) ? (a) : (b)) > @@ -33,6 +34,8 @@ > #define MAX(a, b) ((a) > (b) ? (a) : (b)) > #endif > > +enum PixelFormat find_av_pix_fmt(int, unsigned long, unsigned long, unsigned long); > + > unsigned int char2hex(unsigned char); > > int next_utf8(unsigned char *, int, int *); > > Modified: redbutton-browser/trunk/videoout_xshm.c > =================================================================== > --- redbutton-browser/trunk/videoout_xshm.c 2006-10-12 10:00:30 UTC (rev 148) > +++ redbutton-browser/trunk/videoout_xshm.c 2006-11-05 10:30:39 UTC (rev 149) > @@ -31,8 +31,6 @@ > static void vo_xshm_resize_frame(vo_xshm_ctx *, unsigned int, unsigned int); > static void vo_xshm_destroy_frame(vo_xshm_ctx *); > > -static enum PixelFormat find_av_pix_fmt(int, unsigned long, unsigned long, unsigned long); > - > void * > vo_xshm_init(void) > { > @@ -210,45 +208,3 @@ > return; > } > > -/* > - * returns a PIX_FMT_xxx type that matches the given bits per pixel and RGB bit mask values > - * returns PIX_FMT_NONE if none match > - */ > - > -static enum PixelFormat > -find_av_pix_fmt(int bpp, unsigned long rmask, unsigned long gmask, unsigned long bmask) > -{ > - enum PixelFormat fmt; > - > - fmt = PIX_FMT_NONE; > - switch(bpp) > - { > - case 32: > - if(rmask == 0xff0000 && gmask == 0xff00 && bmask == 0xff) > - fmt = PIX_FMT_RGBA32; > - break; > - > - case 24: > - if(rmask == 0xff0000 && gmask == 0xff00 && bmask == 0xff) > - fmt = PIX_FMT_RGB24; > - else if(rmask == 0xff && gmask == 0xff00 && bmask == 0xff0000) > - fmt = PIX_FMT_BGR24; > - break; > - > - case 16: > - if(rmask == 0xf800 && gmask == 0x07e0 && bmask == 0x001f) > - fmt = PIX_FMT_RGB565; > - else if(rmask == 0x7c00 && gmask == 0x03e0 && bmask == 0x001f) > - fmt = PIX_FMT_RGB555; > - break; > - > - default: > - break; > - } > - > - if(fmt == PIX_FMT_NONE) > - error("Unsupported pixel format (bpp=%d r=%lx g=%lx b=%lx)", bpp, rmask, gmask, bmask); > - > - return fmt; > -} > - > > > This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. > > ------------------------------------------------------------------------- > Using Tomcat but need to do more? Need to support web services, security? > Get stuff done quickly with pre-integrated technology to make your job easier > Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo > http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 > _______________________________________________ > Redbutton-devel mailing list > Red...@li... > https://lists.sourceforge.net/lists/listinfo/redbutton-devel > |
|
From: <ski...@us...> - 2006-12-15 17:11:56
|
Revision: 160
http://svn.sourceforge.net/redbutton/?rev=160&view=rev
Author: skilvington
Date: 2006-12-15 09:11:53 -0800 (Fri, 15 Dec 2006)
Log Message:
-----------
find out where we are supposed to get audio and video streams from
Modified Paths:
--------------
redbutton-browser/trunk/ContentBody.c
redbutton-browser/trunk/ContentBody.h
redbutton-browser/trunk/StreamClass.c
Modified: redbutton-browser/trunk/ContentBody.c
===================================================================
--- redbutton-browser/trunk/ContentBody.c 2006-12-14 14:09:32 UTC (rev 159)
+++ redbutton-browser/trunk/ContentBody.c 2006-12-15 17:11:53 UTC (rev 160)
@@ -48,3 +48,30 @@
return rc;
}
+/*
+ * returns a ptr to the Referenced Content OctetString
+ * retuns NULL if the content is included
+ */
+
+OctetString *
+ContentBody_getReference(ContentBody *c)
+{
+ OctetString *rc = NULL;
+
+ switch(c->choice)
+ {
+ case ContentBody_included_content:
+ break;
+
+ case ContentBody_referenced_content:
+ rc = &c->u.referenced_content.content_reference;
+ break;
+
+ default:
+ error("Unknown ContentBody type: %d", c->choice);
+ break;
+ }
+
+ return rc;
+}
+
Modified: redbutton-browser/trunk/ContentBody.h
===================================================================
--- redbutton-browser/trunk/ContentBody.h 2006-12-14 14:09:32 UTC (rev 159)
+++ redbutton-browser/trunk/ContentBody.h 2006-12-15 17:11:53 UTC (rev 160)
@@ -11,4 +11,6 @@
bool ContentBody_getContent(ContentBody *, RootClass *, OctetString *);
+OctetString *ContentBody_getReference(ContentBody *);
+
#endif /* __CONTENTBODY_H__ */
Modified: redbutton-browser/trunk/StreamClass.c
===================================================================
--- redbutton-browser/trunk/StreamClass.c 2006-12-14 14:09:32 UTC (rev 159)
+++ redbutton-browser/trunk/StreamClass.c 2006-12-15 17:11:53 UTC (rev 160)
@@ -6,6 +6,7 @@
#include "ISO13522-MHEG-5.h"
#include "StreamComponent.h"
#include "ExternalReference.h"
+#include "ContentBody.h"
#include "utils.h"
void
@@ -76,6 +77,7 @@
{
LIST_TYPE(StreamComponent) *comp;
RootClass *r;
+ OctetString *service;
verbose("StreamClass: %s; Activation", ExternalReference_name(&t->rootClass.inst.ref));
@@ -91,6 +93,14 @@
StreamClass_Preparation(t);
}
+ /* assume default is "rec://svc/cur", ie current channel */
+ if(t->have_original_content
+ && (service = ContentBody_getReference(&t->original_content)) != NULL
+ && OctetString_strcmp(service, "rec://svc/cur") != 0)
+ {
+printf("TODO: StreamClass: service='%.*s'\n", service->size, service->data);
+ }
+
/* start playing all active StreamComponents */
comp = t->multiplex;
while(comp)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2007-01-08 16:36:35
|
Revision: 167
http://svn.sourceforge.net/redbutton/?rev=167&view=rev
Author: skilvington
Date: 2007-01-08 08:36:27 -0800 (Mon, 08 Jan 2007)
Log Message:
-----------
in verbose mode, print the values of variables in Read/StorePersistent (I know why BBC News Multiscreen doesn't work\!)
Modified Paths:
--------------
redbutton-browser/trunk/ApplicationClass.c
redbutton-browser/trunk/VariableClass.c
redbutton-browser/trunk/VariableClass.h
Modified: redbutton-browser/trunk/ApplicationClass.c
===================================================================
--- redbutton-browser/trunk/ApplicationClass.c 2007-01-07 12:19:37 UTC (rev 166)
+++ redbutton-browser/trunk/ApplicationClass.c 2007-01-08 16:36:27 UTC (rev 167)
@@ -258,7 +258,7 @@
/* free any existing contents */
LIST_FREE_ITEMS(&p->data, OriginalValue, free_OriginalValue, safe_free);
- verbose("StorePersistent: '%.*s'", filename->size, filename->data);
+ verbose("StorePersistent: filename '%.*s'", filename->size, filename->data);
/* add the new values */
ref = params->in_variables;
@@ -268,6 +268,7 @@
{
if(var->rootClass.inst.rtti == RTTI_VariableClass)
{
+ verbose("StorePersistent: variable '%s'", VariableClass_stringValue(var));
val = safe_malloc(sizeof(LIST_TYPE(OriginalValue)));
OriginalValue_dup(&val->item, &var->inst.Value);
LIST_APPEND(&p->data, val);
@@ -315,7 +316,7 @@
/* find the file */
if((p = MHEGEngine_findPersistentData(filename, false)) != NULL)
{
- verbose("ReadPersistent: '%.*s'", filename->size, filename->data);
+ verbose("ReadPersistent: filename '%.*s'", filename->size, filename->data);
/* read the values into the variables */
ref = params->out_variables;
val = p->data;
@@ -328,6 +329,7 @@
{
/* free any existing data */
OriginalValue_copy(&var->inst.Value, &val->item);
+ verbose("ReadPersistent: variable '%s'", VariableClass_stringValue(var));
}
else
{
Modified: redbutton-browser/trunk/VariableClass.c
===================================================================
--- redbutton-browser/trunk/VariableClass.c 2007-01-07 12:19:37 UTC (rev 166)
+++ redbutton-browser/trunk/VariableClass.c 2007-01-08 16:36:27 UTC (rev 167)
@@ -234,3 +234,50 @@
return v->inst.Value.choice;
}
+/*
+ * returns a static string that will be overwritten by the next call to this routine
+ */
+
+static char *_value = NULL;
+
+char *
+VariableClass_stringValue(VariableClass *v)
+{
+ OctetString *oct;
+
+ switch(v->inst.Value.choice)
+ {
+ case OriginalValue_boolean:
+ _value = safe_realloc(_value, 16);
+ snprintf(_value, 16, "Boolean %s", v->inst.Value.u.boolean ? "true" : "false");
+ return _value;
+
+ case OriginalValue_integer:
+ _value = safe_realloc(_value, 64);
+ snprintf(_value, 64, "Integer %d", v->inst.Value.u.integer);
+ return _value;
+
+ case OriginalValue_octetstring:
+ oct = &v->inst.Value.u.octetstring;
+ _value = safe_realloc(_value, oct->size + 128);
+ snprintf(_value, oct->size + 128, "OctetString %u %.*s", oct->size, oct->size, oct->data);
+ return _value;
+
+ case OriginalValue_object_reference:
+ _value = safe_realloc(_value, PATH_MAX + 32);
+ snprintf(_value, PATH_MAX + 32, "ObjectReference %s", ObjectReference_name(&v->inst.Value.u.object_reference));
+ return _value;
+
+ case OriginalValue_content_reference:
+ oct = &v->inst.Value.u.content_reference;
+ _value = safe_realloc(_value, oct->size + 128);
+ snprintf(_value, oct->size + 128, "ContentReference %u %.*s", oct->size, oct->size, oct->data);
+ return _value;
+
+ default:
+ error("Unknown VariableClass %s; type: %d", ExternalReference_name(&v->rootClass.inst.ref), v->inst.Value.choice);
+ _value = safe_realloc(_value, 32);
+ snprintf(_value, 32, "Invalid VariableClass");
+ return _value;
+ }
+}
Modified: redbutton-browser/trunk/VariableClass.h
===================================================================
--- redbutton-browser/trunk/VariableClass.h 2007-01-07 12:19:37 UTC (rev 166)
+++ redbutton-browser/trunk/VariableClass.h 2007-01-08 16:36:27 UTC (rev 167)
@@ -19,5 +19,7 @@
unsigned int VariableClass_type(VariableClass *);
+char *VariableClass_stringValue(VariableClass *);
+
#endif /* __VARIABLECLASS_H__ */
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2007-01-10 21:25:55
|
Revision: 171
http://svn.sourceforge.net/redbutton/?rev=171&view=rev
Author: skilvington
Date: 2007-01-10 13:25:52 -0800 (Wed, 10 Jan 2007)
Log Message:
-----------
one step closer to being able to retune the backend
Modified Paths:
--------------
redbutton-browser/trunk/MHEGBackend.c
redbutton-browser/trunk/MHEGBackend.h
redbutton-browser/trunk/MHEGEngine.c
redbutton-browser/trunk/MHEGEngine.h
redbutton-browser/trunk/rb-browser.c
Modified: redbutton-browser/trunk/MHEGBackend.c
===================================================================
--- redbutton-browser/trunk/MHEGBackend.c 2007-01-08 16:57:43 UTC (rev 170)
+++ redbutton-browser/trunk/MHEGBackend.c 2007-01-10 21:25:52 UTC (rev 171)
@@ -11,6 +11,7 @@
#include <sys/socket.h>
#include "MHEGEngine.h"
+#include "si.h"
#include "utils.h"
/* local backend funcs */
@@ -18,6 +19,7 @@
bool local_loadFile(MHEGBackend *, OctetString *, OctetString *);
FILE *local_openFile(MHEGBackend *, OctetString *);
FILE *local_openStream(MHEGBackend *, bool, int *, int *, bool, int *, int *);
+void local_retune(MHEGBackend *, OctetString *);
static struct MHEGBackendFns local_backend_fns =
{
@@ -25,6 +27,7 @@
local_loadFile, /* loadFile */
local_openFile, /* openFile */
local_openStream, /* openStream */
+ local_retune, /* retune */
};
/* remote backend funcs */
@@ -32,6 +35,7 @@
bool remote_loadFile(MHEGBackend *, OctetString *, OctetString *);
FILE *remote_openFile(MHEGBackend *, OctetString *);
FILE *remote_openStream(MHEGBackend *, bool, int *, int *, bool, int *, int *);
+void remote_retune(MHEGBackend *, OctetString *);
static struct MHEGBackendFns remote_backend_fns =
{
@@ -39,6 +43,7 @@
remote_loadFile, /* loadFile */
remote_openFile, /* openFile */
remote_openStream, /* openStream */
+ remote_retune, /* retune */
};
/* internal functions */
@@ -346,6 +351,20 @@
}
/*
+ * retune the backend to the given service
+ * service should be in the form "dvb://<network_id>..<service_id>", eg "dvb://233a..4C80"
+ */
+
+void
+local_retune(MHEGBackend *t, OctetString *service)
+{
+/* TODO */
+fatal("TODO: Retune local backend to '%.*s' (service_id %u)", service->size, service->data, si_get_service_id(service));
+
+ return;
+}
+
+/*
* remote routines
*/
@@ -540,3 +559,17 @@
return sock;
}
+/*
+ * retune the backend to the given service
+ * service should be in the form "dvb://<network_id>..<service_id>", eg "dvb://233a..4C80"
+ */
+
+void
+remote_retune(MHEGBackend *t, OctetString *service)
+{
+/* TODO */
+fatal("TODO: Retune remote backend to '%.*s' (service_id %u)", service->size, service->data, si_get_service_id(service));
+
+ return;
+}
+
Modified: redbutton-browser/trunk/MHEGBackend.h
===================================================================
--- redbutton-browser/trunk/MHEGBackend.h 2007-01-08 16:57:43 UTC (rev 170)
+++ redbutton-browser/trunk/MHEGBackend.h 2007-01-10 21:25:52 UTC (rev 171)
@@ -28,6 +28,8 @@
FILE *(*openFile)(struct MHEGBackend *, OctetString *);
/* open an MPEG Transport Stream */
FILE *(*openStream)(struct MHEGBackend *, bool, int *, int *, bool, int *, int *);
+ /* tune to the given service */
+ void (*retune)(struct MHEGBackend *, OctetString *);
} *fns;
} MHEGBackend;
Modified: redbutton-browser/trunk/MHEGEngine.c
===================================================================
--- redbutton-browser/trunk/MHEGEngine.c 2007-01-08 16:57:43 UTC (rev 170)
+++ redbutton-browser/trunk/MHEGEngine.c 2007-01-10 21:25:52 UTC (rev 171)
@@ -183,85 +183,108 @@
}
int
-MHEGEngine_run(OctetString *derfile)
+MHEGEngine_run(void)
{
+ OctetString boot_obj;
ApplicationClass *app;
SceneClass *scene;
bool block;
+ unsigned int i;
+ bool found;
+ /* search order for the app to boot in the Service Gateway dir */
+ char *boot_order[] = { "~//a", "~//startup", NULL };
do
{
- verbose("Running '%.*s'", derfile->size, derfile->data);
- engine.quit_reason = QuitReason_DontQuit;
- /* load the app */
- if((app = MHEGApp_loadApplication(&engine.active_app, derfile)) == NULL)
- return EXIT_FAILURE;
- /* start it up */
- ApplicationClass_Preparation(app);
- ApplicationClass_Activation(app);
- /* main loop */
- while(engine.quit_reason == QuitReason_DontQuit)
+ /* search for the boot object */
+ found = false;
+ for(i=0; !found && boot_order[i] != NULL; i++)
{
- /* poll for files we are waiting for */
- MHEGEngine_pollMissingContent();
- /* process any async events */
- MHEGEngine_processMHEGEvents();
- /*
- * if we are polling for missing content,
- * or if we need to quit the current app
- * don't block waiting for the next GUI event
- */
- block = (engine.missing_content == NULL && engine.quit_reason == QuitReason_DontQuit);
- /* process any GUI events */
- if(MHEGDisplay_processEvents(&engine.display, block))
- engine.quit_reason = QuitReason_GUIQuit;
+ boot_obj.size = strlen(boot_order[i]);
+ boot_obj.data = boot_order[i];
+ found = MHEGEngine_checkContentRef(&boot_obj);
}
- /* do Destruction of Application and Scene */
- if((scene = MHEGEngine_getActiveScene()) != NULL)
+ if(!found)
{
- SceneClass_Deactivation(scene);
- SceneClass_Destruction(scene);
+ error("Unable to find boot object in service gateway");
+ return EXIT_FAILURE;
}
- ApplicationClass_Deactivation(app);
- ApplicationClass_Destruction(app);
- /* clean up */
- MHEGApp_fini(&engine.active_app);
- LIST_FREE(&engine.objects, RootClassPtr, safe_free);
- LIST_FREE(&engine.missing_content, MissingContent, free_MissingContentListItem);
- LIST_FREE(&engine.active_links, LinkClassPtr, safe_free);
- LIST_FREE(&engine.async_eventq, MHEGAsyncEvent, free_MHEGAsyncEventListItem);
- LIST_FREE(&engine.main_actionq, MHEGAction, free_MHEGActionListItem);
- LIST_FREE(&engine.temp_actionq, MHEGAction, free_MHEGActionListItem);
- /* do we need to run a new app */
- switch(engine.quit_reason)
+ do
{
- case QuitReason_Launch:
- verbose("Launch '%.*s'", engine.quit_data.size, engine.quit_data.data);
- derfile = &engine.quit_data;
- break;
-
- case QuitReason_Spawn:
+ /* boot it */
+ verbose("Booting '%.*s'", boot_obj.size, boot_obj.data);
+ engine.quit_reason = QuitReason_DontQuit;
+ /* load the app */
+ if((app = MHEGApp_loadApplication(&engine.active_app, &boot_obj)) == NULL)
+ return EXIT_FAILURE;
+ /* start it up */
+ ApplicationClass_Preparation(app);
+ ApplicationClass_Activation(app);
+ /* main loop */
+ while(engine.quit_reason == QuitReason_DontQuit)
+ {
+ /* poll for files we are waiting for */
+ MHEGEngine_pollMissingContent();
+ /* process any async events */
+ MHEGEngine_processMHEGEvents();
+ /*
+ * if we are polling for missing content,
+ * or if we need to quit the current app
+ * don't block waiting for the next GUI event
+ */
+ block = (engine.missing_content == NULL && engine.quit_reason == QuitReason_DontQuit);
+ /* process any GUI events */
+ if(MHEGDisplay_processEvents(&engine.display, block))
+ engine.quit_reason = QuitReason_GUIQuit;
+ }
+ /* do Destruction of Application and Scene */
+ if((scene = MHEGEngine_getActiveScene()) != NULL)
+ {
+ SceneClass_Deactivation(scene);
+ SceneClass_Destruction(scene);
+ }
+ ApplicationClass_Deactivation(app);
+ ApplicationClass_Destruction(app);
+ /* clean up */
+ MHEGApp_fini(&engine.active_app);
+ LIST_FREE(&engine.objects, RootClassPtr, safe_free);
+ LIST_FREE(&engine.missing_content, MissingContent, free_MissingContentListItem);
+ LIST_FREE(&engine.active_links, LinkClassPtr, safe_free);
+ LIST_FREE(&engine.async_eventq, MHEGAsyncEvent, free_MHEGAsyncEventListItem);
+ LIST_FREE(&engine.main_actionq, MHEGAction, free_MHEGActionListItem);
+ LIST_FREE(&engine.temp_actionq, MHEGAction, free_MHEGActionListItem);
+ /* do we need to run a new app */
+ switch(engine.quit_reason)
+ {
+ case QuitReason_Launch:
+ verbose("Launch '%.*s'", engine.quit_data.size, engine.quit_data.data);
+ boot_obj.size = engine.quit_data.size;
+ boot_obj.data = engine.quit_data.data;
+ break;
+
+ case QuitReason_Spawn:
+ verbose("Spawn '%.*s'", engine.quit_data.size, engine.quit_data.data);
/* TODO */
/* need to run on_restart and on_spawn_close_down Actions at some point */
printf("TODO: Spawn '%.*s'; doing Launch instead\n", engine.quit_data.size, engine.quit_data.data);
- derfile = &engine.quit_data;
- break;
-
- case QuitReason_Retune:
-/* TODO */
-fatal("TODO: Retune to '%.*s' (service_id %u)", engine.quit_data.size, engine.quit_data.data, si_get_service_id(&engine.quit_data));
- break;
-
- default:
- /* nothing to do */
- break;
+ boot_obj.size = engine.quit_data.size;
+ boot_obj.data = engine.quit_data.data;
+ break;
+
+ case QuitReason_Retune:
+ verbose("Retune to '%.*s'", engine.quit_data.size, engine.quit_data.data);
+ MHEGEngine_retune(&engine.quit_data);
+ break;
+
+ default:
+ /* nothing to do */
+ break;
+ }
}
+ while(engine.quit_reason == QuitReason_Launch || engine.quit_reason == QuitReason_Spawn);
}
- while(engine.quit_reason == QuitReason_Launch || engine.quit_reason == QuitReason_Spawn);
+ while(engine.quit_reason == QuitReason_Retune);
- /* clean up */
- free_OctetString(&engine.quit_data);
-
return EXIT_SUCCESS;
}
@@ -276,6 +299,8 @@
MHEGBackend_fini(&engine.backend);
+ free_OctetString(&engine.quit_data);
+
return;
}
@@ -1384,6 +1409,17 @@
}
/*
+ * retune the backend to the given service
+ * service should be in the form "dvb://<network_id>..<service_id>", eg "dvb://233a..4C80"
+ */
+
+void
+MHEGEngine_retune(OctetString *service)
+{
+ return (*(engine.backend.fns->retune))(&engine.backend, service);
+}
+
+/*
* returns the absolute group ID, ie it always starts with "~//"
* returns a ptr to static string that will be overwritten by the next call to this routine
* section 8.3.2 of the UK MHEG Profile says the filename prefixes are:
Modified: redbutton-browser/trunk/MHEGEngine.h
===================================================================
--- redbutton-browser/trunk/MHEGEngine.h 2007-01-08 16:57:43 UTC (rev 170)
+++ redbutton-browser/trunk/MHEGEngine.h 2007-01-10 21:25:52 UTC (rev 171)
@@ -184,8 +184,8 @@
/* prototypes */
void MHEGEngine_init(MHEGEngineOptions *);
-int MHEGEngine_run(OctetString *);
-void MHEGEngine_fini();
+int MHEGEngine_run(void);
+void MHEGEngine_fini(void);
MHEGDisplay *MHEGEngine_getDisplay(void);
MHEGVideoOutputMethod *MHEGEngine_getVideoOutputMethod(void);
@@ -237,6 +237,7 @@
bool MHEGEngine_loadFile(OctetString *, OctetString *);
FILE *MHEGEngine_openFile(OctetString *);
FILE *MHEGEngine_openStream(bool, int *, int *, bool, int *, int *);
+void MHEGEngine_retune(OctetString *);
char *MHEGEngine_absoluteFilename(OctetString *);
Modified: redbutton-browser/trunk/rb-browser.c
===================================================================
--- redbutton-browser/trunk/rb-browser.c 2007-01-08 16:57:43 UTC (rev 170)
+++ redbutton-browser/trunk/rb-browser.c 2007-01-10 21:25:52 UTC (rev 171)
@@ -33,11 +33,6 @@
int arg;
size_t last;
int rc;
- int i;
- bool found;
- OctetString boot_obj;
- /* search order for the app to boot in the Service Gateway dir */
- char *boot_order[] = { "~//a", "~//startup", NULL };
/* we assume &struct == &struct.first_item, not sure if C guarantees it */
ApplicationClass app;
@@ -106,27 +101,8 @@
MHEGEngine_init(&opts);
- /* search for the boot object */
- found = false;
- for(i=0; !found && boot_order[i] != NULL; i++)
- {
- boot_obj.size = strlen(boot_order[i]);
- boot_obj.data = boot_order[i];
- found = MHEGEngine_checkContentRef(&boot_obj);
- }
+ rc = MHEGEngine_run();
- if(found)
- {
- verbose("Booting '%.*s'", boot_obj.size, boot_obj.data);
- rc = MHEGEngine_run(&boot_obj);
- }
- else
- {
- error("Unable to find boot object in service gateway '%s'", opts.srg_loc);
- rc = EXIT_FAILURE;
- }
-
- /* clean up */
MHEGEngine_fini();
return rc;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2007-01-11 11:10:34
|
Revision: 172
http://svn.sourceforge.net/redbutton/?rev=172&view=rev
Author: skilvington
Date: 2007-01-11 03:10:32 -0800 (Thu, 11 Jan 2007)
Log Message:
-----------
allow local backends to retune
Modified Paths:
--------------
redbutton-browser/trunk/MHEGBackend.c
redbutton-browser/trunk/utils.c
redbutton-browser/trunk/utils.h
Modified: redbutton-browser/trunk/MHEGBackend.c
===================================================================
--- redbutton-browser/trunk/MHEGBackend.c 2007-01-10 21:25:52 UTC (rev 171)
+++ redbutton-browser/trunk/MHEGBackend.c 2007-01-11 11:10:32 UTC (rev 172)
@@ -73,6 +73,7 @@
{
/* backend is on a different host, srg_loc is the remote host[:port] */
b->fns = &remote_backend_fns;
+ b->base_dir = NULL;
if(parse_addr(srg_loc, &b->addr.sin_addr, &b->addr.sin_port) < 0)
fatal("Unable to resolve host %s", srg_loc);
verbose("Remote backend at %s:%u", inet_ntoa(b->addr.sin_addr), ntohs(b->addr.sin_port));
@@ -81,7 +82,7 @@
{
/* backend and frontend on same host, srg_loc is the base directory */
b->fns = &local_backend_fns;
- b->base_dir = srg_loc;
+ b->base_dir = safe_strdup(srg_loc);
verbose("Local backend; carousel file root '%s'", srg_loc);
}
@@ -96,6 +97,8 @@
&& remote_command(b, true, "quit\n") != NULL)
fclose(b->be_sock);
+ safe_free(b->base_dir);
+
return;
}
@@ -358,9 +361,35 @@
void
local_retune(MHEGBackend *t, OctetString *service)
{
-/* TODO */
-fatal("TODO: Retune local backend to '%.*s' (service_id %u)", service->size, service->data, si_get_service_id(service));
+ unsigned int service_id;
+ char service_str[64];
+ char *slash;
+ int prefix_len;
+ /* extract the service_id */
+ service_id = si_get_service_id(service);
+ snprintf(service_str, sizeof(service_str), "%u", service_id);
+
+ /*
+ * base_dir is: [path/to/services/]<service_id>
+ * so we just need to replace the last filename component with the new service_id
+ */
+ slash = strrchr(t->base_dir, '/');
+ if(slash == NULL)
+ {
+ /* no preceeding path */
+ t->base_dir = safe_realloc(t->base_dir, strlen(service_str) + 1);
+ strcpy(t->base_dir, service_str);
+ }
+ else
+ {
+ prefix_len = (slash - t->base_dir) + 1;
+ t->base_dir = safe_realloc(t->base_dir, prefix_len + strlen(service_str) + 1);
+ strcpy(t->base_dir + prefix_len, service_str);
+ }
+
+ verbose("Retune: new service gateway is '%s'", t->base_dir);
+
return;
}
Modified: redbutton-browser/trunk/utils.c
===================================================================
--- redbutton-browser/trunk/utils.c 2007-01-10 21:25:52 UTC (rev 171)
+++ redbutton-browser/trunk/utils.c 2007-01-11 11:10:32 UTC (rev 172)
@@ -206,6 +206,24 @@
return;
}
+/*
+ * safe_strdup(NULL) == NULL
+ */
+
+char *
+safe_strdup(const char *src)
+{
+ char *dst;
+
+ if(src == NULL)
+ return NULL;
+
+ dst = (char *) safe_malloc(strlen(src) + 1);
+ strcpy(dst, src);
+
+ return dst;
+}
+
void
error(char *message, ...)
{
Modified: redbutton-browser/trunk/utils.h
===================================================================
--- redbutton-browser/trunk/utils.h 2007-01-10 21:25:52 UTC (rev 171)
+++ redbutton-browser/trunk/utils.h 2007-01-11 11:10:32 UTC (rev 172)
@@ -45,6 +45,8 @@
void *safe_realloc(void *, size_t);
void safe_free(void *);
+char *safe_strdup(const char *);
+
void error(char *, ...);
void fatal(char *, ...);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2007-01-23 08:56:54
|
Revision: 191
http://svn.sourceforge.net/redbutton/?rev=191&view=rev
Author: skilvington
Date: 2007-01-23 00:56:53 -0800 (Tue, 23 Jan 2007)
Log Message:
-----------
cope with DSM: filename prefixes
Modified Paths:
--------------
redbutton-browser/trunk/MHEGEngine.c
redbutton-browser/trunk/TODO
Modified: redbutton-browser/trunk/MHEGEngine.c
===================================================================
--- redbutton-browser/trunk/MHEGEngine.c 2007-01-23 08:37:58 UTC (rev 190)
+++ redbutton-browser/trunk/MHEGEngine.c 2007-01-23 08:56:53 UTC (rev 191)
@@ -1449,26 +1449,43 @@
char *
MHEGEngine_absoluteFilename(OctetString *name)
{
-/**********************************************************************************/
+ unsigned int size;
+ unsigned char *data;
+
/* TODO */
-/* also need to cope with DSM: and CI: at the start */
-/**********************************************************************************/
+/* need to cope with CI: at the start */
+ if(name->size > 2 && strncmp(name->data, "CI:", 3) == 0)
+ {
+printf("TODO: absoluteFilename '%.*s'", name->size, name->data);
+ }
+ /* DSM: at the start is equivalent to ~ */
+ if(name->size > 3 && strncmp(name->data, "DSM:", 4) == 0)
+ {
+ size = name->size - 4;
+ data = &name->data[4];
+ }
+ else
+ {
+ size = name->size;
+ data = name->data;
+ }
+
/* does it already start with a ~// */
- if(name->size > 2 && strncmp(name->data, "~//", 3) == 0)
- snprintf(_absolute, sizeof(_absolute), "%.*s", name->size, name->data);
+ if(size > 2 && strncmp(data, "~//", 3) == 0)
+ snprintf(_absolute, sizeof(_absolute), "%.*s", size, data);
/* starting with // is the same as starting with ~// */
- else if(name->size > 1 && strncmp(name->data, "//", 2) == 0)
- snprintf(_absolute, sizeof(_absolute), "~%.*s", name->size, name->data);
+ else if(size > 1 && strncmp(data, "//", 2) == 0)
+ snprintf(_absolute, sizeof(_absolute), "~%.*s", size, data);
/* starting with ~/ means prepend the path to the current active app */
- else if(name->size > 1 && strncmp(name->data, "~/", 2) == 0)
- snprintf(_absolute, sizeof(_absolute), "%s%.*s", active_app_path(), name->size - 1, &name->data[1]);
+ else if(size > 1 && strncmp(data, "~/", 2) == 0)
+ snprintf(_absolute, sizeof(_absolute), "%s%.*s", active_app_path(), size - 1, &data[1]);
/* starting with / is the same as starting with ~/ */
- else if(name->size > 0 && name->data[0] == '/')
- snprintf(_absolute, sizeof(_absolute), "%s%.*s", active_app_path(), name->size, name->data);
+ else if(size > 0 && data[0] == '/')
+ snprintf(_absolute, sizeof(_absolute), "%s%.*s", active_app_path(), size, data);
/* no / at the start, UK Profile doesn't say what to do, so prepend the path to the current active app */
- else if(name->size > 0)
- snprintf(_absolute, sizeof(_absolute), "%s/%.*s", active_app_path(), name->size, name->data);
+ else if(size > 0)
+ snprintf(_absolute, sizeof(_absolute), "%s/%.*s", active_app_path(), size, data);
/* no name at all */
else
snprintf(_absolute, sizeof(_absolute), "%s/", active_app_path());
Modified: redbutton-browser/trunk/TODO
===================================================================
--- redbutton-browser/trunk/TODO 2007-01-23 08:37:58 UTC (rev 190)
+++ redbutton-browser/trunk/TODO 2007-01-23 08:56:53 UTC (rev 191)
@@ -35,9 +35,7 @@
(eg TokenGroupClass_CallActionSlot)
-cope with DSM: and CI: filename prefixes
-cope with .. in filenames (may not be needed, remote backend does it for us,
-for local backend filesystem does it for us)
+cope with CI: filename prefixes
see 8.3.2 in UK MHEG Profile
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2007-02-08 11:55:49
|
Revision: 205
http://svn.sourceforge.net/redbutton/?rev=205&view=rev
Author: skilvington
Date: 2007-02-08 03:55:44 -0800 (Thu, 08 Feb 2007)
Log Message:
-----------
prepare to allow streaming a/v from different service IDs
Modified Paths:
--------------
redbutton-browser/trunk/ElementaryAction.c
redbutton-browser/trunk/MHEGBackend.c
redbutton-browser/trunk/MHEGBackend.h
redbutton-browser/trunk/MHEGEngine.c
redbutton-browser/trunk/MHEGEngine.h
redbutton-browser/trunk/MHEGStreamPlayer.c
redbutton-browser/trunk/MHEGStreamPlayer.h
redbutton-browser/trunk/StreamClass.c
redbutton-browser/trunk/StreamClass.h
redbutton-browser/trunk/der_decode.c
redbutton-browser/trunk/der_decode.h
Modified: redbutton-browser/trunk/ElementaryAction.c
===================================================================
--- redbutton-browser/trunk/ElementaryAction.c 2007-01-29 17:00:12 UTC (rev 204)
+++ redbutton-browser/trunk/ElementaryAction.c 2007-02-08 11:55:44 UTC (rev 205)
@@ -1205,6 +1205,8 @@
TokenGroupClass_SetData((TokenGroupClass *) obj, &e->u.set_data, caller_gid);
else if(obj->inst.rtti == RTTI_ListGroupClass)
ListGroupClass_SetData((ListGroupClass *) obj, &e->u.set_data, caller_gid);
+ else if(obj->inst.rtti == RTTI_StreamClass)
+ StreamClass_SetData((StreamClass *) obj, &e->u.set_data, caller_gid);
else
error("SetData: unexpected target: %s", ExternalReference_name(&obj->inst.ref));
}
Modified: redbutton-browser/trunk/MHEGBackend.c
===================================================================
--- redbutton-browser/trunk/MHEGBackend.c 2007-01-29 17:00:12 UTC (rev 204)
+++ redbutton-browser/trunk/MHEGBackend.c 2007-02-08 11:55:44 UTC (rev 205)
@@ -18,7 +18,7 @@
bool local_checkContentRef(MHEGBackend *, ContentReference *);
bool local_loadFile(MHEGBackend *, OctetString *, OctetString *);
FILE *local_openFile(MHEGBackend *, OctetString *);
-FILE *local_openStream(MHEGBackend *, bool, int *, int *, bool, int *, int *);
+FILE *local_openStream(MHEGBackend *, int, bool, int *, int *, bool, int *, int *);
void local_retune(MHEGBackend *, OctetString *);
static struct MHEGBackendFns local_backend_fns =
@@ -34,7 +34,7 @@
bool remote_checkContentRef(MHEGBackend *, ContentReference *);
bool remote_loadFile(MHEGBackend *, OctetString *, OctetString *);
FILE *remote_openFile(MHEGBackend *, OctetString *);
-FILE *remote_openStream(MHEGBackend *, bool, int *, int *, bool, int *, int *);
+FILE *remote_openStream(MHEGBackend *, int, bool, int *, int *, bool, int *, int *);
void remote_retune(MHEGBackend *, OctetString *);
static struct MHEGBackendFns remote_backend_fns =
@@ -333,14 +333,15 @@
* return a read-only FILE handle for an MPEG Transport Stream
* the TS will contain an audio stream (if have_audio is true) and a video stream (if have_video is true)
* the *audio_tag and *video_tag numbers refer to Component/Association Tag values from the DVB PMT
- * if *audio_tag or *video_tag is -1, the default audio and/or video stream for the current Service ID is used
+ * if *audio_tag or *video_tag is -1, the default audio and/or video stream for the given Service ID is used
+ * if service_id is -1, it uses the Service ID we are downloading the carousel from
* updates *audio_tag and/or *video_tag to the actual PIDs in the Transport Stream
* updates *audio_type and/or *video_type to the stream type IDs
* returns NULL on error
*/
FILE *
-local_openStream(MHEGBackend *t, bool have_audio, int *audio_tag, int *audio_type, bool have_video, int *video_tag, int *video_type)
+local_openStream(MHEGBackend *t, int service_id, bool have_audio, int *audio_tag, int *audio_type, bool have_video, int *video_tag, int *video_type)
{
/*
* we need to convert the audio/video_tag into PIDs
@@ -350,7 +351,7 @@
* 3. just stream the TS from the backend
* we choose 3, to avoid duplicating code and having to pass "-d <device>" options etc
*/
- return remote_openStream(t, have_audio, audio_tag, audio_type, have_video, video_tag, video_type);
+ return remote_openStream(t, service_id, have_audio, audio_tag, audio_type, have_video, video_tag, video_type);
}
/*
@@ -522,14 +523,15 @@
* return a read-only FILE handle for an MPEG Transport Stream
* the TS will contain an audio stream (if have_audio is true) and a video stream (if have_video is true)
* the *audio_tag and *video_tag numbers refer to Component/Association Tag values from the DVB PMT
- * if *audio_tag or *video_tag is -1, the default audio and/or video stream for the current Service ID is used
+ * if *audio_tag or *video_tag is -1, the default audio and/or video stream for the given Service ID is used
+ * if service_id is -1, it uses the Service ID we are downloading the carousel from
* updates *audio_tag and/or *video_tag to the actual PIDs in the Transport Stream
* updates *audio_type and/or *video_type to the stream type IDs
* returns NULL on error
*/
FILE *
-remote_openStream(MHEGBackend *t, bool have_audio, int *audio_tag, int *audio_type, bool have_video, int *video_tag, int *video_type)
+remote_openStream(MHEGBackend *t, int service_id, bool have_audio, int *audio_tag, int *audio_type, bool have_video, int *video_tag, int *video_type)
{
char cmd[PATH_MAX];
FILE *sock;
@@ -538,6 +540,9 @@
unsigned int video_pid = 0;
bool err;
+/* TODO */
+if(service_id != -1) printf("TODO: openStream: service_id=%d\n", service_id);
+
/* no PIDs required */
if(!have_audio && !have_video)
return NULL;
Modified: redbutton-browser/trunk/MHEGBackend.h
===================================================================
--- redbutton-browser/trunk/MHEGBackend.h 2007-01-29 17:00:12 UTC (rev 204)
+++ redbutton-browser/trunk/MHEGBackend.h 2007-02-08 11:55:44 UTC (rev 205)
@@ -29,7 +29,7 @@
/* open a carousel file */
FILE *(*openFile)(struct MHEGBackend *, OctetString *);
/* open an MPEG Transport Stream */
- FILE *(*openStream)(struct MHEGBackend *, bool, int *, int *, bool, int *, int *);
+ FILE *(*openStream)(struct MHEGBackend *, int, bool, int *, int *, bool, int *, int *);
/* tune to the given service */
void (*retune)(struct MHEGBackend *, OctetString *);
} *fns;
Modified: redbutton-browser/trunk/MHEGEngine.c
===================================================================
--- redbutton-browser/trunk/MHEGEngine.c 2007-01-29 17:00:12 UTC (rev 204)
+++ redbutton-browser/trunk/MHEGEngine.c 2007-02-08 11:55:44 UTC (rev 205)
@@ -1416,9 +1416,10 @@
*/
FILE *
-MHEGEngine_openStream(bool have_audio, int *audio_tag, int *audio_type, bool have_video, int *video_tag, int *video_type)
+MHEGEngine_openStream(int service_id, bool have_audio, int *audio_tag, int *audio_type, bool have_video, int *video_tag, int *video_type)
{
return (*(engine.backend.fns->openStream))(&engine.backend,
+ service_id,
have_audio, audio_tag, audio_type,
have_video, video_tag, video_type);
}
Modified: redbutton-browser/trunk/MHEGEngine.h
===================================================================
--- redbutton-browser/trunk/MHEGEngine.h 2007-01-29 17:00:12 UTC (rev 204)
+++ redbutton-browser/trunk/MHEGEngine.h 2007-02-08 11:55:44 UTC (rev 205)
@@ -239,7 +239,7 @@
bool MHEGEngine_checkContentRef(ContentReference *);
bool MHEGEngine_loadFile(OctetString *, OctetString *);
FILE *MHEGEngine_openFile(OctetString *);
-FILE *MHEGEngine_openStream(bool, int *, int *, bool, int *, int *);
+FILE *MHEGEngine_openStream(int, bool, int *, int *, bool, int *, int *);
void MHEGEngine_retune(OctetString *);
char *MHEGEngine_absoluteFilename(OctetString *);
Modified: redbutton-browser/trunk/MHEGStreamPlayer.c
===================================================================
--- redbutton-browser/trunk/MHEGStreamPlayer.c 2007-01-29 17:00:12 UTC (rev 204)
+++ redbutton-browser/trunk/MHEGStreamPlayer.c 2007-02-08 11:55:44 UTC (rev 205)
@@ -91,6 +91,9 @@
p->video = NULL;
p->audio = NULL;
+ /* stream a/v components from the service we are currently tuned to */
+ p->service_id = -1;
+
p->audio_codec = NULL;
pthread_mutex_init(&p->base_lock, NULL);
@@ -119,7 +122,21 @@
return;
}
+/*
+ * service ID is used to resolve the stream component tags
+ * -1 => use the service we are currently tuned to,
+ * ie the service we are downloading the carousel from
+ */
+
void
+MHEGStreamPlayer_setServiceID(MHEGStreamPlayer *p, int id)
+{
+ p->service_id = id;
+
+ return;
+}
+
+void
MHEGStreamPlayer_setVideoStream(MHEGStreamPlayer *p, VideoClass *video)
{
if(p->have_video)
@@ -174,7 +191,8 @@
p->audio_pid = p->audio_tag;
p->video_pid = p->video_tag;
- if((p->ts = MHEGEngine_openStream(p->have_audio, &p->audio_pid, &p->audio_type,
+ if((p->ts = MHEGEngine_openStream(p->service_id,
+ p->have_audio, &p->audio_pid, &p->audio_type,
p->have_video, &p->video_pid, &p->video_type)) == NULL)
{
error("Unable to open MPEG stream");
Modified: redbutton-browser/trunk/MHEGStreamPlayer.h
===================================================================
--- redbutton-browser/trunk/MHEGStreamPlayer.h 2007-01-29 17:00:12 UTC (rev 204)
+++ redbutton-browser/trunk/MHEGStreamPlayer.h 2007-02-08 11:55:44 UTC (rev 205)
@@ -57,6 +57,7 @@
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 service_id; /* service containing the audio/video components (-1 => what we are currently tuned to) */
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) */
@@ -81,6 +82,7 @@
void MHEGStreamPlayer_init(MHEGStreamPlayer *);
void MHEGStreamPlayer_fini(MHEGStreamPlayer *);
+void MHEGStreamPlayer_setServiceID(MHEGStreamPlayer *, int);
void MHEGStreamPlayer_setVideoStream(MHEGStreamPlayer *, VideoClass *);
void MHEGStreamPlayer_setAudioStream(MHEGStreamPlayer *, AudioClass *);
Modified: redbutton-browser/trunk/StreamClass.c
===================================================================
--- redbutton-browser/trunk/StreamClass.c 2007-01-29 17:00:12 UTC (rev 204)
+++ redbutton-browser/trunk/StreamClass.c 2007-02-08 11:55:44 UTC (rev 205)
@@ -7,6 +7,7 @@
#include "StreamComponent.h"
#include "ExternalReference.h"
#include "ContentBody.h"
+#include "si.h"
#include "utils.h"
void
@@ -93,12 +94,29 @@
StreamClass_Preparation(t);
}
- /* assume default is "rec://svc/cur", ie current channel */
+ /* assume default is "rec://svc/def", ie current channel */
if(t->have_original_content
- && (service = ContentBody_getReference(&t->original_content)) != NULL
- && OctetString_strcmp(service, "rec://svc/cur") != 0)
+ && (service = ContentBody_getReference(&t->original_content)) != NULL)
{
+ /*
+ * service can be:
+ * "dvb://<original_network_id>.[<transport_stream_id>].<service_id>"
+ * "rec://svc/def" - use the service we are downloading the carousel from
+ * "rec://svc/cur" - use the current service
+ * this will be the same as "def" unless SetData has been called on the StreamClass
+ * "rec://svc/lcn/X" - use logical channel number X (eg 1 for BBC1, 3 for ITV1, etc)
+ */
+ if(OctetString_strncmp(service, "dvb:", 4) == 0)
+ {
+ MHEGStreamPlayer_setServiceID(&t->inst.player, si_get_service_id(service));
+ }
+ /* leave player's service ID as it is for "cur" and "def" */
+ else if(OctetString_strcmp(service, "rec://svc/cur") != 0
+ && OctetString_strcmp(service, "rec://svc/def") != 0)
+ {
+/* TODO */
printf("TODO: StreamClass: service='%.*s'\n", service->size, service->data);
+ }
}
/* start playing all active StreamComponents */
@@ -201,7 +219,22 @@
return;
}
+/*
+ * corrigendum says StreamClass can be the target of SetData
+ * this changes the multiplex (ie service ID)
+ */
+
void
+StreamClass_SetData(StreamClass *t, SetData *set, OctetString *caller_gid)
+{
+ verbose("StreamClass: %s; SetData", ExternalReference_name(&t->rootClass.inst.ref));
+
+/* TODO */
+printf("TODO: StreamClass_SetData not yet implemented\n");
+ return;
+}
+
+void
StreamClass_SetCounterTrigger(StreamClass *t, SetCounterTrigger *params, OctetString *caller_gid)
{
verbose("StreamClass: %s; SetCounterTrigger", ExternalReference_name(&t->rootClass.inst.ref));
Modified: redbutton-browser/trunk/StreamClass.h
===================================================================
--- redbutton-browser/trunk/StreamClass.h 2007-01-29 17:00:12 UTC (rev 204)
+++ redbutton-browser/trunk/StreamClass.h 2007-02-08 11:55:44 UTC (rev 205)
@@ -12,6 +12,7 @@
void StreamClass_Deactivation(StreamClass *);
void StreamClass_Destruction(StreamClass *);
+void StreamClass_SetData(StreamClass *, SetData *, OctetString *);
void StreamClass_SetCounterTrigger(StreamClass *, SetCounterTrigger *, OctetString *);
void StreamClass_SetSpeed(StreamClass *, SetSpeed *, OctetString *);
void StreamClass_SetCounterPosition(StreamClass *, SetCounterPosition *, OctetString *);
Modified: redbutton-browser/trunk/der_decode.c
===================================================================
--- redbutton-browser/trunk/der_decode.c 2007-01-29 17:00:12 UTC (rev 204)
+++ redbutton-browser/trunk/der_decode.c 2007-02-08 11:55:44 UTC (rev 205)
@@ -234,6 +234,19 @@
}
/*
+ * compare the first n characters of the OctetString with the given C string
+ */
+
+int
+OctetString_strncmp(OctetString *oct, char *str, size_t n)
+{
+ if(oct->size < n)
+ return oct->size - n;
+ else
+ return memcmp(oct->data, str, n);
+}
+
+/*
* assumes its okay to call der_realloc(dst->data, x)
* if dst is not initialised, you should use OctetString_dup instead
* src can be NULL, but dst must be valid
Modified: redbutton-browser/trunk/der_decode.h
===================================================================
--- redbutton-browser/trunk/der_decode.h 2007-01-29 17:00:12 UTC (rev 204)
+++ redbutton-browser/trunk/der_decode.h 2007-02-08 11:55:44 UTC (rev 205)
@@ -51,6 +51,7 @@
int OctetString_cmp(OctetString *, OctetString *);
int OctetString_strcmp(OctetString *, char *);
+int OctetString_strncmp(OctetString *, char *, size_t);
bool OctetString_copy(OctetString *, OctetString *);
void OctetString_dup(OctetString *, OctetString *);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2007-02-13 14:12:45
|
Revision: 213
http://svn.sourceforge.net/redbutton/?rev=213&view=rev
Author: skilvington
Date: 2007-02-13 06:12:31 -0800 (Tue, 13 Feb 2007)
Log Message:
-----------
let StreamComponents know which StreamClass they belong to
Modified Paths:
--------------
redbutton-browser/trunk/StreamClass.c
redbutton-browser/trunk/StreamComponent.c
redbutton-browser/trunk/StreamComponent.h
redbutton-browser/trunk/add_instance_vars.conf
Modified: redbutton-browser/trunk/StreamClass.c
===================================================================
--- redbutton-browser/trunk/StreamClass.c 2007-02-13 10:30:46 UTC (rev 212)
+++ redbutton-browser/trunk/StreamClass.c 2007-02-13 14:12:31 UTC (rev 213)
@@ -13,6 +13,8 @@
void
default_StreamClassInstanceVars(StreamClass *t, StreamClassInstanceVars *v)
{
+ LIST_TYPE(StreamComponent) *comp;
+
bzero(v, sizeof(StreamClassInstanceVars));
v->Speed.numerator = 1;
@@ -24,6 +26,14 @@
v->CounterTriggers = NULL;
+ /* let the StreamComponents know who they belong to */
+ comp = t->multiplex;
+ while(comp)
+ {
+ StreamComponent_registerStreamClass(&comp->item, t);
+ comp = comp->next;
+ }
+
MHEGStreamPlayer_init(&v->player);
return;
Modified: redbutton-browser/trunk/StreamComponent.c
===================================================================
--- redbutton-browser/trunk/StreamComponent.c 2007-02-13 10:30:46 UTC (rev 212)
+++ redbutton-browser/trunk/StreamComponent.c 2007-02-13 14:12:31 UTC (rev 213)
@@ -9,6 +9,32 @@
#include "RTGraphicsClass.h"
#include "utils.h"
+void
+StreamComponent_registerStreamClass(StreamComponent *s, StreamClass *owner)
+{
+
+ switch(s->choice)
+ {
+ case StreamComponent_audio:
+ s->u.audio.inst.owner = owner;
+ break;
+
+ case StreamComponent_video:
+ s->u.video.inst.owner = owner;
+ break;
+
+ case StreamComponent_rtgraphics:
+ s->u.rtgraphics.inst.owner = owner;
+ break;
+
+ default:
+ error("Unknown StreamComponent type: %d", s->choice);
+ break;
+ }
+
+ return;
+}
+
RootClass *
StreamComponent_rootClass(StreamComponent *s)
{
Modified: redbutton-browser/trunk/StreamComponent.h
===================================================================
--- redbutton-browser/trunk/StreamComponent.h 2007-02-13 10:30:46 UTC (rev 212)
+++ redbutton-browser/trunk/StreamComponent.h 2007-02-13 14:12:31 UTC (rev 213)
@@ -9,6 +9,8 @@
#include "ISO13522-MHEG-5.h"
+void StreamComponent_registerStreamClass(StreamComponent *, StreamClass *);
+
RootClass *StreamComponent_rootClass(StreamComponent *);
bool StreamComponent_isInitiallyActive(StreamComponent *);
Modified: redbutton-browser/trunk/add_instance_vars.conf
===================================================================
--- redbutton-browser/trunk/add_instance_vars.conf 2007-02-13 10:30:46 UTC (rev 212)
+++ redbutton-browser/trunk/add_instance_vars.conf 2007-02-13 14:12:31 UTC (rev 213)
@@ -177,6 +177,8 @@
/* VideoClass */
/* UK MHEG Profile adds this */
XYPosition VideoDecodeOffset;
+ /* we add a link to the StreamClass it is a part of */
+ struct StreamClass *owner;
/* we add a lock for the size/position */
pthread_mutex_t bbox_lock;
/* and the scaled size */
@@ -222,9 +224,20 @@
typedef struct
{
int Volume;
+ /* we add a link to the StreamClass it is a part of */
+ struct StreamClass *owner;
} AudioClassInstanceVars;
</AudioClass>
+<RTGraphicsClass>
+typedef struct
+{
+ /* not implemented */
+ /* we add a link to the StreamClass it is a part of */
+ struct StreamClass *owner;
+} RTGraphicsClassInstanceVars;
+</RTGraphicsClass>
+
<SliderClass>
typedef struct
{
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2007-02-14 17:17:58
|
Revision: 216
http://svn.sourceforge.net/redbutton/?rev=216&view=rev
Author: skilvington
Date: 2007-02-14 09:17:51 -0800 (Wed, 14 Feb 2007)
Log Message:
-----------
get StreamComponents to tell their StreamClass when they are [de]activated
Modified Paths:
--------------
redbutton-browser/trunk/AudioClass.c
redbutton-browser/trunk/StreamClass.c
redbutton-browser/trunk/StreamClass.h
redbutton-browser/trunk/VideoClass.c
Modified: redbutton-browser/trunk/AudioClass.c
===================================================================
--- redbutton-browser/trunk/AudioClass.c 2007-02-13 16:59:54 UTC (rev 215)
+++ redbutton-browser/trunk/AudioClass.c 2007-02-14 17:17:51 UTC (rev 216)
@@ -5,6 +5,7 @@
#include "MHEGEngine.h"
#include "AudioClass.h"
#include "RootClass.h"
+#include "StreamClass.h"
#include "ExternalReference.h"
void
@@ -14,6 +15,8 @@
v->Volume = t->original_volume;
+ v->owner = NULL;
+
return;
}
@@ -58,6 +61,15 @@
/* generate IsRunning event */
MHEGEngine_generateEvent(&t->rootClass.inst.ref, EventType_is_running, NULL);
+ /*
+ * tell our StreamClass to start playing us
+ * owner maybe NULL if our StreamClass is in the process of activating itself
+ * in which case, it will start us when needed
+ */
+ if(t->inst.owner != NULL)
+ StreamClass_activateAudioComponent(t->inst.owner, t);
+else printf("TODO: AudioClass_Activation: un-owned (tag=%d)\n", t->component_tag);
+
return;
}
@@ -66,8 +78,19 @@
{
verbose("AudioClass: %s; Deactivation", ExternalReference_name(&t->rootClass.inst.ref));
- RootClass_Deactivation(&t->rootClass);
+ /* is it already deactivated */
+ if(!RootClass_Deactivation(&t->rootClass))
+ return;
+ /*
+ * tell our StreamClass to stop playing us
+ * owner maybe NULL if our StreamClass is in the process of deactivating itself
+ * in which case, it will stop us when needed
+ */
+ if(t->inst.owner != NULL)
+ StreamClass_deactivateAudioComponent(t->inst.owner, t);
+else printf("TODO: AudioClass_Deactivation: un-owned (tag=%d)\n", t->component_tag);
+
return;
}
Modified: redbutton-browser/trunk/StreamClass.c
===================================================================
--- redbutton-browser/trunk/StreamClass.c 2007-02-13 16:59:54 UTC (rev 215)
+++ redbutton-browser/trunk/StreamClass.c 2007-02-14 17:17:51 UTC (rev 216)
@@ -13,8 +13,6 @@
void
default_StreamClassInstanceVars(StreamClass *t, StreamClassInstanceVars *v)
{
- LIST_TYPE(StreamComponent) *comp;
-
bzero(v, sizeof(StreamClassInstanceVars));
v->Speed.numerator = 1;
@@ -26,14 +24,6 @@
v->CounterTriggers = NULL;
- /* let the StreamComponents know who they belong to */
- comp = t->multiplex;
- while(comp)
- {
- StreamComponent_registerStreamClass(&comp->item, t);
- comp = comp->next;
- }
-
MHEGStreamPlayer_init(&v->player);
return;
@@ -155,6 +145,14 @@
t->rootClass.inst.RunningStatus = true;
MHEGEngine_generateEvent(&t->rootClass.inst.ref, EventType_is_running, NULL);
+ /* now we are fully activated, let our StreamComponents know who they belong to */
+ comp = t->multiplex;
+ while(comp)
+ {
+ StreamComponent_registerStreamClass(&comp->item, t);
+ comp = comp->next;
+ }
+
return;
}
@@ -170,6 +168,14 @@
if(!t->rootClass.inst.RunningStatus)
return;
+ /* disown all our StreamComponents */
+ comp = t->multiplex;
+ while(comp)
+ {
+ StreamComponent_registerStreamClass(&comp->item, NULL);
+ comp = comp->next;
+ }
+
/* stop playing all active StreamComponents */
MHEGStreamPlayer_stop(&t->inst.player);
comp = t->multiplex;
@@ -237,6 +243,53 @@
return;
}
+void
+StreamClass_activateVideoComponent(StreamClass *t, VideoClass *c)
+{
+/* TODO */
+printf("TODO: StreamClass_activateVideoComponent (tag=%d)\n", c->component_tag);
+// basically:
+// MHEGStreamPlayer_stop(t)
+// MHEGStreamPlayer_setVideoStream(t, c) - may get the "only using last video stream" warning
+// MHEGStreamPlayer_play(t)
+// MHEGEngine_generateAstncEvent(&t->rootClass.inst.ref, EventType_stream_playing, NULL)
+
+ return;
+}
+
+void
+StreamClass_activateAudioComponent(StreamClass *t, AudioClass *c)
+{
+/* TODO */
+printf("TODO: StreamClass_activateAudioComponent (tag=%d)\n", c->component_tag);
+
+ return;
+}
+
+void
+StreamClass_deactivateVideoComponent(StreamClass *t, VideoClass *c)
+{
+/* TODO */
+printf("TODO: StreamClass_deactivateVideoComponent (tag=%d)\n", c->component_tag);
+// basically:
+// MHEGStreamPlayer_stop(t)
+// MHEGStreamPlayer_setVideoStream(t, NULL)
+// MHEGStreamPlayer_play(t)
+// MHEGEngine_generateAstncEvent(&t->rootClass.inst.ref, EventType_stream_stopped, NULL)
+// => need to make MHEGStreamPlayer_setVideoStream(t, NULL) disable video
+
+ return;
+}
+
+void
+StreamClass_deactivateAudioComponent(StreamClass *t, AudioClass *c)
+{
+/* TODO */
+printf("TODO: StreamClass_deactivateAudioComponent (tag=%d)\n", c->component_tag);
+
+ return;
+}
+
/*
* corrigendum says StreamClass can be the target of SetData
* this changes the multiplex (ie service ID)
Modified: redbutton-browser/trunk/StreamClass.h
===================================================================
--- redbutton-browser/trunk/StreamClass.h 2007-02-13 16:59:54 UTC (rev 215)
+++ redbutton-browser/trunk/StreamClass.h 2007-02-14 17:17:51 UTC (rev 216)
@@ -12,6 +12,11 @@
void StreamClass_Deactivation(StreamClass *);
void StreamClass_Destruction(StreamClass *);
+void StreamClass_activateVideoComponent(StreamClass *, VideoClass *);
+void StreamClass_activateAudioComponent(StreamClass *, AudioClass *);
+void StreamClass_deactivateVideoComponent(StreamClass *, VideoClass *);
+void StreamClass_deactivateAudioComponent(StreamClass *, AudioClass *);
+
void StreamClass_SetData(StreamClass *, SetData *, OctetString *);
void StreamClass_SetCounterTrigger(StreamClass *, SetCounterTrigger *, OctetString *);
void StreamClass_SetSpeed(StreamClass *, SetSpeed *, OctetString *);
Modified: redbutton-browser/trunk/VideoClass.c
===================================================================
--- redbutton-browser/trunk/VideoClass.c 2007-02-13 16:59:54 UTC (rev 215)
+++ redbutton-browser/trunk/VideoClass.c 2007-02-14 17:17:51 UTC (rev 216)
@@ -5,6 +5,7 @@
#include "MHEGEngine.h"
#include "ISO13522-MHEG-5.h"
#include "RootClass.h"
+#include "StreamClass.h"
#include "ExternalReference.h"
#include "ObjectReference.h"
#include "GenericInteger.h"
@@ -30,6 +31,8 @@
v->VideoDecodeOffset.x_position = 0;
v->VideoDecodeOffset.y_position = 0;
+ v->owner = NULL;
+
pthread_mutex_init(&v->bbox_lock, NULL);
pthread_mutex_init(&v->scaled_lock, NULL);
v->scaled = false;
@@ -85,6 +88,15 @@
t->rootClass.inst.RunningStatus = true;
MHEGEngine_generateEvent(&t->rootClass.inst.ref, EventType_is_running, NULL);
+ /*
+ * tell our StreamClass to start playing us
+ * owner maybe NULL if our StreamClass is in the process of activating itself
+ * in which case, it will start us when needed
+ */
+ if(t->inst.owner != NULL)
+ StreamClass_activateVideoComponent(t->inst.owner, t);
+else printf("TODO: VideoClass_Activation: un-owned (tag=%d)\n", t->component_tag);
+
/* now its RunningStatus is true, get it drawn at its position in the application's DisplayStack */
MHEGEngine_redrawArea(&t->inst.Position, &t->inst.BoxSize);
@@ -100,6 +112,15 @@
if(!RootClass_Deactivation(&t->rootClass))
return;
+ /*
+ * tell our StreamClass to stop playing us
+ * owner maybe NULL if our StreamClass is in the process of deactivating itself
+ * in which case, it will stop us when needed
+ */
+ if(t->inst.owner != NULL)
+ StreamClass_deactivateVideoComponent(t->inst.owner, t);
+else printf("TODO: VideoClass_Deactivation: un-owned (tag=%d)\n", t->component_tag);
+
/* now its RunningStatus is false, redraw the area it covered */
MHEGEngine_redrawArea(&t->inst.Position, &t->inst.BoxSize);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2007-02-15 09:32:03
|
Revision: 217
http://svn.sourceforge.net/redbutton/?rev=217&view=rev
Author: skilvington
Date: 2007-02-15 01:31:49 -0800 (Thu, 15 Feb 2007)
Log Message:
-----------
make sure StreamComponents don't forget who their StreamClass is, if they are activated after the StreamClass is activated
Modified Paths:
--------------
redbutton-browser/trunk/AudioClass.c
redbutton-browser/trunk/VideoClass.c
Modified: redbutton-browser/trunk/AudioClass.c
===================================================================
--- redbutton-browser/trunk/AudioClass.c 2007-02-14 17:17:51 UTC (rev 216)
+++ redbutton-browser/trunk/AudioClass.c 2007-02-15 09:31:49 UTC (rev 217)
@@ -11,12 +11,18 @@
void
default_AudioClassInstanceVars(AudioClass *t, AudioClassInstanceVars *v)
{
- bzero(v, sizeof(AudioClassInstanceVars));
+ /*
+ * don't do:
+ * bzero(v, sizeof(AudioClassInstanceVars));
+ * or:
+ * v->owner = NULL;
+ * the whole AudioClass including these instance vars is zero'd when it is DER decoded
+ * we need to make sure v->owner is not set to NULL here
+ * in case our StreamClass is already active and has set our owner
+ */
v->Volume = t->original_volume;
- v->owner = NULL;
-
return;
}
@@ -68,7 +74,6 @@
*/
if(t->inst.owner != NULL)
StreamClass_activateAudioComponent(t->inst.owner, t);
-else printf("TODO: AudioClass_Activation: un-owned (tag=%d)\n", t->component_tag);
return;
}
@@ -89,7 +94,6 @@
*/
if(t->inst.owner != NULL)
StreamClass_deactivateAudioComponent(t->inst.owner, t);
-else printf("TODO: AudioClass_Deactivation: un-owned (tag=%d)\n", t->component_tag);
return;
}
Modified: redbutton-browser/trunk/VideoClass.c
===================================================================
--- redbutton-browser/trunk/VideoClass.c 2007-02-14 17:17:51 UTC (rev 216)
+++ redbutton-browser/trunk/VideoClass.c 2007-02-15 09:31:49 UTC (rev 217)
@@ -18,7 +18,15 @@
void
default_VideoClassInstanceVars(VideoClass *t, VideoClassInstanceVars *v)
{
- bzero(v, sizeof(VideoClassInstanceVars));
+ /*
+ * don't do:
+ * bzero(v, sizeof(VideoClassInstanceVars));
+ * or:
+ * v->owner = NULL;
+ * the whole VideoClass including these instance vars is zero'd when it is DER decoded
+ * we need to make sure v->owner is not set to NULL here
+ * in case our StreamClass is already active and has set our owner
+ */
/* VisibleClass */
memcpy(&v->BoxSize, &t->original_box_size, sizeof(OriginalBoxSize));
@@ -31,8 +39,6 @@
v->VideoDecodeOffset.x_position = 0;
v->VideoDecodeOffset.y_position = 0;
- v->owner = NULL;
-
pthread_mutex_init(&v->bbox_lock, NULL);
pthread_mutex_init(&v->scaled_lock, NULL);
v->scaled = false;
@@ -95,7 +101,6 @@
*/
if(t->inst.owner != NULL)
StreamClass_activateVideoComponent(t->inst.owner, t);
-else printf("TODO: VideoClass_Activation: un-owned (tag=%d)\n", t->component_tag);
/* now its RunningStatus is true, get it drawn at its position in the application's DisplayStack */
MHEGEngine_redrawArea(&t->inst.Position, &t->inst.BoxSize);
@@ -119,7 +124,6 @@
*/
if(t->inst.owner != NULL)
StreamClass_deactivateVideoComponent(t->inst.owner, t);
-else printf("TODO: VideoClass_Deactivation: un-owned (tag=%d)\n", t->component_tag);
/* now its RunningStatus is false, redraw the area it covered */
MHEGEngine_redrawArea(&t->inst.Position, &t->inst.BoxSize);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ski...@us...> - 2007-02-16 12:54:42
|
Revision: 218
http://svn.sourceforge.net/redbutton/?rev=218&view=rev
Author: skilvington
Date: 2007-02-16 04:54:40 -0800 (Fri, 16 Feb 2007)
Log Message:
-----------
allow us to temporarily stop playing streams without forgetting what their components are
Modified Paths:
--------------
redbutton-browser/trunk/MHEGStreamPlayer.c
redbutton-browser/trunk/StreamComponent.c
Modified: redbutton-browser/trunk/MHEGStreamPlayer.c
===================================================================
--- redbutton-browser/trunk/MHEGStreamPlayer.c 2007-02-15 09:31:49 UTC (rev 217)
+++ redbutton-browser/trunk/MHEGStreamPlayer.c 2007-02-16 12:54:40 UTC (rev 218)
@@ -139,6 +139,23 @@
void
MHEGStreamPlayer_setVideoStream(MHEGStreamPlayer *p, VideoClass *video)
{
+ /* assert */
+ if(p->playing)
+ fatal("MHEGStreamPlayer_setVideoStream: trying to set stream while playing");
+
+ if(video)
+ verbose("MHEGStreamPlayer_setVideoStream: tag=%d", video->component_tag);
+ else
+ verbose("MHEGStreamPlayer_setVideoStream: NULL");
+
+ /* video==NULL => forget any existing stream */
+ if(video == NULL)
+ {
+ p->have_video = false;
+ p->video = NULL;
+ return;
+ }
+
if(p->have_video)
error("MHEGStreamPlayer: more than one video stream; only using the last one (%d)", video->component_tag);
@@ -158,6 +175,24 @@
void
MHEGStreamPlayer_setAudioStream(MHEGStreamPlayer *p, AudioClass *audio)
{
+ /* assert */
+ if(p->playing)
+ fatal("MHEGStreamPlayer_setAudioStream: trying to set stream while playing");
+
+ if(audio)
+ verbose("MHEGStreamPlayer_setAudioStream: tag=%d", audio->component_tag);
+ else
+ verbose("MHEGStreamPlayer_setAudioStream: NULL");
+
+ /* audio==NULL => forget any existing stream */
+ if(audio == NULL)
+ {
+ p->have_audio = false;
+ p->audio = NULL;
+ p->audio_codec = NULL;
+ return;
+ }
+
if(p->have_audio)
error("MHEGStreamPlayer: more than one audio stream; only using the last one (%d)", audio->component_tag);
@@ -258,13 +293,6 @@
p->ts = NULL;
}
- /* forget any existing streams */
- p->have_video = false;
- p->have_audio = false;
- p->video = NULL;
- p->audio = NULL;
- p->audio_codec = NULL;
-
p->playing = false;
return;
Modified: redbutton-browser/trunk/StreamComponent.c
===================================================================
--- redbutton-browser/trunk/StreamComponent.c 2007-02-15 09:31:49 UTC (rev 217)
+++ redbutton-browser/trunk/StreamComponent.c 2007-02-16 12:54:40 UTC (rev 218)
@@ -155,9 +155,11 @@
switch(s->choice)
{
case StreamComponent_audio:
+ MHEGStreamPlayer_setAudioStream(player, NULL);
break;
case StreamComponent_video:
+ MHEGStreamPlayer_setVideoStream(player, NULL);
break;
case StreamComponent_rtgraphics:
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|