Page 1 of 1

SmartQ V5

Posted: 22 Feb 2010 18:31
by jech
Hi,

I would like to ask you only out of curiosity if you know about the modified version of VLC that can be found in SmartQ V5 and V7. This MID runs a modified version of Ubuntu and the default media player is VLC. The version is 1.1 and it contains HW acceleration for video decoding.

I'm curious if you know about this version and if SmartQ published the modifications they made to allow HW decoding acceleration. Thank you.

Re: SmartQ V5

Posted: 24 Feb 2010 17:45
by Rémi Denis-Courmont
We are aware of that, but since there are based in China, there is not much we can do.

Re: SmartQ V5

Posted: 24 Feb 2010 23:12
by jech
So they haven't published the modified sources, if I understood you right. That's really disappointing.

Re: SmartQ V5

Posted: 24 Feb 2010 23:45
by Jean-Baptiste Kempf
Indeed :'(

Re: SmartQ V5

Posted: 13 Jun 2010 15:17
by Santiago
Seems that this is VLC patch for SmartQ from chinese developers.
Found there: http://smartqmid.ru/index.php?showtopic=1113

Code: Select all

--- modules/codec/avcodec/video.c | 51 +++++++++++++++++++++++---- modules/video_output/wrapper.c | 72 ++++++++++++++++++++++++++++++++++++++ src/input/decoder.c | 26 +++++++++++++- src/video_output/video_output.c | 20 ++++++++++ src/video_output/vout_pictures.c | 6 +++ 5 files changed, 167 insertions(+), 8 deletions(-) diff --git a/modules/codec/avcodec/video.c b/modules/codec/avcodec/video.c index 72e4151..d0fe383 100644 --- a/modules/codec/avcodec/video.c +++ b/modules/codec/avcodec/video.c @@ -299,7 +299,8 @@ int InitVideoDec( decoder_t *p_dec, AVCodecContext *p_context, /* Apparently direct rendering doesn't work with YUV422P */ p_sys->p_context->pix_fmt != PIX_FMT_YUV422P && /* H264 uses too many reference frames */ - p_sys->i_codec_id != CODEC_ID_H264 && + (p_sys->p_codec->capabilities & 0x0100) && // XXX: + //p_sys->i_codec_id != CODEC_ID_H264 && // XXX: /* No idea why ... but this fixes flickering on some TSCC streams */ p_sys->i_codec_id != CODEC_ID_TSCC && !p_sys->p_context->debug_mv ) @@ -540,11 +541,11 @@ picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block ) int i_used, b_gotpicture; picture_t *p_pic; -#if 0 - AVPacket pkt; //av_init_packet(&pkt); +#if 1 + AVPacket pkt; //av_init_packet(&pkt); - pkt.flags = AV_PKT_FLAG_KEY; // XXX: - pkt.pts = p_sys->input_pts; pkt.dts = p_sys->input_dts; + pkt.flags = AV_PKT_FLAG_KEY; // XXX: + pkt.pts = p_sys->input_pts; pkt.dts = p_sys->input_dts; pkt.data = (p_block->i_buffer <= 0 && p_sys->b_flush) ? NULL : p_block->p_buffer; @@ -566,9 +567,17 @@ picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block ) b_null_size = false; if( p_sys->b_hurry_up ) p_sys->p_context->skip_frame = p_sys->i_skip_frame; + if (0 && b_gotpicture && // XXX: + (p_pic = (picture_t*)p_sys->p_ff_pic->opaque)) + decoder_DeletePicture(p_dec, p_pic); +#if 1 + i_used = avcodec_decode_video2(p_sys->p_context, + p_sys->p_ff_pic, &b_gotpicture, &pkt); +#else// XXX: i_used = avcodec_decode_video( p_sys->p_context, p_sys->p_ff_pic, &b_gotpicture, p_block->p_buffer, p_block->i_buffer ); +#endif } if( p_sys->b_flush ) @@ -598,6 +607,11 @@ picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block ) if( !b_gotpicture ) { if( i_used == 0 ) break; + picture_t *p_pic = (picture_t*)p_sys->p_ff_pic->opaque; + if (0 && p_pic && (p_sys->p_codec->capabilities & 0x0100)) { + msg_Warn(p_dec, "fake displayed to fix pictures leak"); + p_pic->i_status = DISPLAYED_PICTURE; // XXX: + } //else ffmpeg_NextPts(p_dec); continue; } @@ -612,6 +626,16 @@ picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block ) if( i_display_date > 0 && i_display_date <= mdate() ) { + if (!p_sys->p_ff_pic->data[3]) { // XXX: FIXME + p_pic = (picture_t *)p_sys->p_ff_pic->opaque; + if (!b_drawpicture && p_pic) + decoder_DeletePicture(p_dec, p_pic); + msg_Warn(p_dec, "ignoring picture"); + + ffmpeg_NextPts( p_dec ); + continue; + } + p_sys->i_late_frames++; if( p_sys->i_late_frames == 1 ) p_sys->i_late_frames_start = mdate(); @@ -650,6 +674,11 @@ picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block ) else { p_pic = (picture_t *)p_sys->p_ff_pic->opaque; + + if (p_pic->p->p_pixels != *p_sys->p_ff_pic->data + /*&& p_sys->p_ff_pic->data[3]*/) + for (int i = 0; i < 4; ++i) // XXX: + p_pic->p[i].p_pixels = p_sys->p_ff_pic->data[i]; } /* Sanity check (seems to be needed for some streams) */ @@ -691,6 +720,8 @@ picture_t *DecodeVideo( decoder_t *p_dec, block_t **pp_block ) p_pic->b_progressive = !p_sys->p_ff_pic->interlaced_frame; p_pic->b_top_field_first = p_sys->p_ff_pic->top_field_first; + if (!p_sys->p_ff_pic->qscale_table) return p_pic; + p_pic->i_qstride = p_sys->p_ff_pic->qstride; int i_mb_h = ( p_pic->format.i_height + 15 ) / 16; p_pic->p_q = malloc( p_pic->i_qstride * i_mb_h ); @@ -863,6 +894,12 @@ static void ffmpeg_CopyPicture( decoder_t *p_dec, uint8_t *p_dst, *p_src; int i_src_stride, i_dst_stride; + if (p_pic->i_planes == 3 && p_ff_pic->data[3]) { + for (i_plane = 0; i_plane < 4; ++i_plane) // XXX: + p_pic->p[i_plane].p_pixels = p_ff_pic->data[i_plane]; + return; + } + for( i_plane = 0; i_plane < p_pic->i_planes; i_plane++ ) { p_src = p_ff_pic->data[i_plane]; @@ -950,9 +987,9 @@ static int ffmpeg_GetFrameBuf( struct AVCodecContext *p_context, avcodec_align_dimensions( p_sys->p_context, &i_width, &i_height ); if( GetVlcChroma( &p_dec->fmt_out.video, p_context->pix_fmt ) != VLC_SUCCESS || - p_sys->p_context->width % 16 || p_sys->p_context->height % 16 || + p_sys->p_context->width % 16 || p_sys->p_context->height % 2 || // XXX: /* We only pad picture up to 16 */ - PAD(p_sys->p_context->width,16) < i_width || PAD(p_sys->p_context->height,16) < i_height || + PAD(p_sys->p_context->width,16) < i_width || //PAD(p_sys->p_context->height,16) < i_height || // XXX: p_context->pix_fmt == PIX_FMT_PAL8 ) return avcodec_default_get_buffer( p_context, p_ff_pic ); diff --git a/modules/video_output/wrapper.c b/modules/video_output/wrapper.c index b379201..6f2906e 100644 --- a/modules/video_output/wrapper.c +++ b/modules/video_output/wrapper.c @@ -36,6 +36,15 @@ #include "../video_filter/filter_common.h" #include <assert.h> +#ifdef TCC_M2MSCALER_PADDR // 0x4f400000 // XXX: +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/mman.h> +#include <fcntl.h> + +#include <string.h> +#endif /* comment by mhfan */ + /***************************************************************************** * Module descriptor *************************************************************************** **/ @@ -60,6 +69,10 @@ struct vout_sys_t { char *title; vout_display_t *vd; bool use_dr; + +#ifdef TCC_M2MSCALER_PADDR + int fd; uint8_t *vaddr; +#endif /* comment by mhfan */ }; struct picture_sys_t { @@ -97,6 +110,24 @@ static int Open(vlc_object_t *object) if (!sys) return VLC_ENOMEM; +#ifdef TCC_M2MSCALER_PADDR +#define TCC_M2MSCALER_MSIZE 0x400000 + + if ((sys->fd = open("/dev/mem", O_RDWR | O_NDELAY)) < 0) { + msg_Err(vout, "Fail to open `/dev/mem': %s", strerror(errno)); + sys->vaddr = MAP_FAILED; + } else { + if ((sys->vaddr = mmap(0, TCC_M2MSCALER_MSIZE, PROT_READ | PROT_WRITE, + MAP_SHARED, sys->fd, TCC_M2MSCALER_PADDR)) == MAP_FAILED) { + msg_Err(vout, "Fail to mmap %p + %x: %s", + (void*)TCC_M2MSCALER_PADDR, TCC_M2MSCALER_MSIZE, + strerror(errno)); + close(sys->fd); sys->fd = -1; + } else msg_Info(vout, "mmaped physical memory: %p + %x", + (void*)TCC_M2MSCALER_PADDR, TCC_M2MSCALER_MSIZE); + } +#endif /* comment by mhfan */ + sys->title = var_CreateGetNonEmptyString(vout, "video-title"); /* */ @@ -151,6 +182,16 @@ static void Close(vlc_object_t *object) vout_thread_t *vout = (vout_thread_t *)object; vout_sys_t *sys = vout->p_sys; +#ifdef TCC_M2MSCALER_PADDR + if (-1 < sys->fd) { + close(sys->fd); sys->fd = -1; + if (sys->vaddr != MAP_FAILED) { + munmap((void*)sys->vaddr, TCC_M2MSCALER_MSIZE); + sys->vaddr = MAP_FAILED; + } + } +#endif /* comment by mhfan */ + #ifdef WIN32 var_DelCallback(vout, "direct3d-desktop", Forward, NULL); var_DelCallback(vout, "video-wallpaper", Forward, NULL); @@ -416,6 +457,37 @@ static void Display(vout_thread_t *vout, picture_t *picture) if (sys->use_dr) picture_Hold(direct); + if (picture->i_planes == 3 && picture->p[3].p_pixels) { + unsigned* addr = (void*)direct->p->p_pixels; + addr[0] = (unsigned) picture->p[3].p_pixels; + + addr[1] = addr[0] + (unsigned) (picture->p[1].p_pixels - + picture->p[0].p_pixels); + addr[2] = addr[1] + (unsigned) (picture->p[2].p_pixels - + picture->p[1].p_pixels); + + //memcpy(addr, picture->p[0].p_pixels + 4, 36); // XXX: + } else { +#ifdef TCC_M2MSCALER_PADDR + if (sys->vaddr != MAP_FAILED) { + unsigned size, *addr = (void*)direct->p->p_pixels; + + addr[0] = TCC_M2MSCALER_PADDR; + addr[3] = (unsigned)sys->vaddr; //addr[3] &= ~0x0f; + + size = picture->p->i_pitch * picture->p->i_lines; + vlc_memcpy(addr[3], picture->p->p_pixels, size); + for (int i = 1; i < picture->i_planes; ++i) { + addr[3 + i] = addr[3 + i - 1] + size; + addr[i] = addr[i - 1] + size; + + size = picture->p[i].i_pitch * picture->p[i].i_lines; + vlc_memcpy(addr[3 + i], picture->p[i].p_pixels, size); + } + } +#endif /* comment by mhfan */ + } + vout_display_Display(vd, direct); if (sys->use_dr) { diff --git a/src/input/decoder.c b/src/input/decoder.c index 13e6658..e1c455d 100644 --- a/src/input/decoder.c +++ b/src/input/decoder.c @@ -31,6 +31,9 @@ #endif #include <assert.h> +#include <unistd.h> +#include <sys/sysinfo.h> + #include <vlc_common.h> #include <vlc_block.h> @@ -292,6 +295,24 @@ decoder_t *input_DecoderNew( input_thread_t *p_input, p_dec->p_owner->p_clock = p_clock; assert( p_dec->fmt_out.i_cat != UNKNOWN_ES ); + if (fmt->i_cat == VIDEO_ES && 719 < fmt->video.i_height) { + size_t mems; struct sysinfo sysi; + if (!sysinfo(&sysi)) mems = sysi.totalram * sysi.mem_unit; else + mems = sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE); + + // XXX: p_dec-> fmt_in/fmt_out . + if (( 719 < fmt->video.i_height && (188 << 20) < mems) || + (1079 < fmt->video.i_height && (138 << 20) < mems)) + dialog_FatalWait(p_input, _("Memory mis-required warning"), + _("VLC may fail to play this `%ux%u/%4.4s' video," + " due to limited memory space (%u MB)." + " If it failed, please re-try after reboot" + " and reserve more memory: select" + " `1080P51' in the boot menu."), + fmt->video.i_width, fmt->video.i_height, + (char*)&fmt->i_codec, mems >> 20); + } + if( p_dec->fmt_out.i_cat == AUDIO_ES ) i_priority = VLC_THREAD_PRIORITY_AUDIO; else @@ -320,6 +341,9 @@ void input_DecoderDelete( decoder_t *p_dec ) { decoder_owner_sys_t *p_owner = p_dec->p_owner; + if (p_owner->p_vout) + vout_Flush(p_owner->p_vout, VLC_TS_INVALID - 1); // XXX: + vlc_object_kill( p_dec ); /* Make sure we aren't paused/buffering/waiting anymore */ @@ -2069,7 +2093,7 @@ static void DeleteDecoder( decoder_t * p_dec ) vout_ChangePause( p_owner->p_vout, false, mdate() ); /* */ - input_resource_RequestVout( p_owner->p_input->p->p_resource, p_owner->p_vout, NULL, true ); + input_resource_RequestVout( p_owner->p_input->p->p_resource, p_owner->p_vout, NULL, false ); // XXX: input_SendEventVout( p_owner->p_input ); } diff --git a/src/video_output/video_output.c b/src/video_output/video_output.c index 943970a..153df1d 100644 --- a/src/video_output/video_output.c +++ b/src/video_output/video_output.c @@ -641,6 +641,12 @@ void vout_Flush( vout_thread_t *p_vout, mtime_t i_date ) { vlc_mutex_lock( &p_vout->picture_lock ); p_vout->p->i_picture_displayed_date = 0; + + if (p_vout->p->p_picture_displayed && i_date < 2) { + p_vout->p->p_picture_displayed->date = i_date; // XXX: + msg_Warn(p_vout, "drop last displayed picture too: %d", (int)i_date); + } + for( int i = 0; i < p_vout->render.i_pictures; i++ ) { picture_t *p_pic = p_vout->render.pp_picture[i]; @@ -1038,6 +1044,12 @@ static void* RunThread( void *p_this ) } if( !p_picture ) { + if (p_last && p_last->date < 2) { + vout_UsePictureLocked(p_vout, p_last); + msg_Warn(p_vout, "last displayed picture dropped: %d", + (int)p_last->date); + p_vout->p->p_picture_displayed = p_last = NULL; + } else // XXX: p_picture = p_last; if( !p_vout->p->b_picture_empty ) @@ -1216,6 +1228,14 @@ static void* RunThread( void *p_this ) */ if( p_filtered_picture != NULL && p_directbuffer != NULL ) { + if (p_picture->i_planes == 3 && p_picture->p[3].p_pixels) { + if (p_directbuffer->p->p_pixels != p_picture->p->p_pixels) + for (int i = 0; i < p_picture->i_planes; ++i) + p_directbuffer->p[i].p_pixels = + p_picture->p[i].p_pixels; + p_directbuffer->p[3].p_pixels = p_picture->p[3].p_pixels; + } + /* Display the direct buffer returned by vout_RenderPicture */ if( p_vout->pf_display ) p_vout->pf_display( p_vout, p_directbuffer ); diff --git a/src/video_output/vout_pictures.c b/src/video_output/vout_pictures.c index 7cd06c5..4878cef 100644 --- a/src/video_output/vout_pictures.c +++ b/src/video_output/vout_pictures.c @@ -1028,6 +1028,12 @@ void picture_CopyPixels( picture_t *p_dst, const picture_t *p_src ) { int i; + if (p_src->i_planes == 3 && p_src->p[3].p_pixels) { + for (i = 0; i < 4; ++i) // XXX: + p_dst->p[i].p_pixels = p_src->p[i].p_pixels; + return; + } + for( i = 0; i < p_src->i_planes; i++ ) plane_CopyPixels( p_dst->p+i, p_src->p+i ); } -- 1.7.1

Re: SmartQ V5

Posted: 15 Jun 2010 04:00
by Rémi Denis-Courmont
That looks like a quick undocumented set of hacks from an unknown origin (Chinese on a Russian language website - why do I find this odd?).
This definitely is NOT the source code for the extra VLC plugins that SmartQ ships, such as the HDMI output.

Re: SmartQ V5

Posted: 15 Jun 2010 09:26
by Jean-Baptiste Kempf
Clearly, those are various fixes and work-arounds for their own drivers...