vlc pays video created with libavcodec at wrong frame rate - h.264

As a test i'd like to create a video that has a framerate of 1 fps. When I create it like this vlc still plays it at 25 fps. does anybody have an idea?
AVFormatContext* formatContext;
avformat_alloc_output_context2(&formatContext, NULL, NULL, "test.h264");
AVOutputFormat* outputFormat = formatContext->oformat;
AVStream* videoStream = av_new_stream(formatContext, 0);
AVCodecContext* ctx = videoStream->codec;
ctx->codec_type = AVMEDIA_TYPE_VIDEO;
ctx->codec_id = CODEC_ID_H264;
ctx->bit_rate = 500*1000;
ctx->bit_rate_tolerance = 0;
ctx->width = w;
ctx->height = h;
ctx->pix_fmt = AV_PIX_FMT_YUV420P;
ctx->time_base.den = 1;//25;
ctx->time_base.num = 1;

this is an old question but I hope it help others with the same problem
AVStream has an explicit time_base which is set by muxer according to container.
as stated in AVStream.time_base comment :
The muxer MAY use the user-provided value of
AVCodecContext.time_base as a hint.
you need to use av_rescale_q() to set your RAW FRAME pts to a correct value :
/* AVFrame* */ raw_frame->pts = av_rescale_q(my_pts, ctx->time_base, videoStream->time_base);
.
.
.
/* AVPacket pkt; */
avcodec_encode_video2(ctx, pkt, &got_packet);
.
.
.
av_write_frame(formatContext, &pkt);

Related

Reading YUY2 data from an IMFSample that appears to have improper data on Windows 10

I am developing an application that using IMFSourceReader to read data from video files. I am using DXVA for improved performance. I am having trouble with one specific full-HD H.264 encoded AVI file. Based on my investigation this far, I believe that the IMFSample contains incorrect data. My workflow is below:
Create a source reader with a D3D manager to enable hardware acceleration.
Set the current media type to YUY2 as DXVA does not
decode to any RGB colorspace.
Call ReadSample to get an IMFSample. Works fine.
Use the VideoProcessorBlt to perform YUY2 to BGRA32
conversion. For this specific file it errors out with an
E_INVALIDARGS error code. Decided to do the conversion myself.
Used IMFSample::ConvertToContiguousBuffer to receive an IMFMediaBuffer. When locking this buffer, the pitch is reported as 1280 bytes. This I believe is incorrect, because for a full HD video, the pitch should be (1920 + 960 + 960 = 3840 bytes).
I dumped the raw memory and extracted the Y, U and V components based on my understanding of the YUY2 layout. You can find it below. So, the data is there but I do not believe it is laid out as YUY2. Need some help in interpreting the data.
My code for reading is below:
// Direct3D surface that stores the result of the YUV2RGB conversion
CComPtr<IDirect3DSurface9> _pTargetSurface;
IDirectXVideoAccelerationService* vidAccelService;
initVidAccelerator(&vidAccelService); // Omitting the code for this.
// Create a new surface for doing the color conversion, set it up to store X8R8G8B8 data.
hr = vidAccelService->CreateSurface( static_cast<UINT>( 1920 ),
static_cast<UINT>( 1080 ),
0, // no back buffers
D3DFMT_X8R8G8B8, // data format
D3DPOOL_DEFAULT, // default memory pool
0, // reserved
DXVA2_VideoProcessorRenderTarget, // to use with the Blit operation
&_pTargetSurface, // surface used to store frame
NULL);
GUID processorGUID;
DXVA2_VideoDesc videoDescriptor;
D3DFORMAT processorFmt;
UINT numSubStreams;
IDirectXVideoProcessor* _vpd;
initVideoProcessor(&vpd); // Omitting the code for this
// We get the videoProcessor parameters on creation, and fill up the videoProcessBltParams accordingly.
_vpd->GetCreationParameters(&processorGUID, &videoDescriptor, &processorFmt, &numSubStreams);
RECT targetRECT; // { 0, 0, width, height } as left, top, right, bottom
targetRECT.left = 0;
targetRECT.right = videoDescriptor.SampleWidth;
targetRECT.top = 0;
targetRECT.bottom = videoDescriptor.SampleHeight;
SIZE targetSIZE; // { width, height }
targetSIZE.cx = videoDescriptor.SampleWidth;
targetSIZE.cy = videoDescriptor.SampleHeight;
// Parameters that are required to use the video processor to perform
// YUV2RGB and other video processing operations
DXVA2_VideoProcessBltParams _frameBltParams;
_frameBltParams.TargetRect = targetRECT;
_frameBltParams.ConstrictionSize = targetSIZE;
_frameBltParams.StreamingFlags = 0; // reserved.
_frameBltParams.BackgroundColor.Y = 0x0000;
_frameBltParams.BackgroundColor.Cb = 0x0000;
_frameBltParams.BackgroundColor.Cr = 0x0000;
_frameBltParams.BackgroundColor.Alpha = 0xFFFF;
// copy attributes from videoDescriptor obtained above.
_frameBltParams.DestFormat.VideoChromaSubsampling = videoDescriptor.SampleFormat.VideoChromaSubsampling;
_frameBltParams.DestFormat.NominalRange = videoDescriptor.SampleFormat.NominalRange;
_frameBltParams.DestFormat.VideoTransferMatrix = videoDescriptor.SampleFormat.VideoTransferMatrix;
_frameBltParams.DestFormat.VideoLighting = videoDescriptor.SampleFormat.VideoLighting;
_frameBltParams.DestFormat.VideoPrimaries = videoDescriptor.SampleFormat.VideoPrimaries;
_frameBltParams.DestFormat.VideoTransferFunction = videoDescriptor.SampleFormat.VideoTransferFunction;
_frameBltParams.DestFormat.SampleFormat = DXVA2_SampleProgressiveFrame;
// The default values are used for all these parameters.
DXVA2_ValueRange pRangePABrightness;
_vpd->GetProcAmpRange(DXVA2_ProcAmp_Brightness, &pRangePABrightness);
DXVA2_ValueRange pRangePAContrast;
_vpd->GetProcAmpRange(DXVA2_ProcAmp_Contrast, &pRangePAContrast);
DXVA2_ValueRange pRangePAHue;
_vpd->GetProcAmpRange(DXVA2_ProcAmp_Hue, &pRangePAHue);
DXVA2_ValueRange pRangePASaturation;
_vpd->GetProcAmpRange(DXVA2_ProcAmp_Saturation, &pRangePASaturation);
_frameBltParams.ProcAmpValues = { pRangePABrightness.DefaultValue, pRangePAContrast.DefaultValue,
pRangePAHue.DefaultValue, pRangePASaturation.DefaultValue };
_frameBltParams.Alpha = DXVA2_Fixed32OpaqueAlpha();
_frameBltParams.DestData = DXVA2_SampleData_TFF;
// Input video sample for the Blt operation
DXVA2_VideoSample _frameVideoSample;
_frameVideoSample.SampleFormat.VideoChromaSubsampling = videoDescriptor.SampleFormat.VideoChromaSubsampling;
_frameVideoSample.SampleFormat.NominalRange = videoDescriptor.SampleFormat.NominalRange;
_frameVideoSample.SampleFormat.VideoTransferMatrix = videoDescriptor.SampleFormat.VideoTransferMatrix;
_frameVideoSample.SampleFormat.VideoLighting = videoDescriptor.SampleFormat.VideoLighting;
_frameVideoSample.SampleFormat.VideoPrimaries = videoDescriptor.SampleFormat.VideoPrimaries;
_frameVideoSample.SampleFormat.VideoTransferFunction = videoDescriptor.SampleFormat.VideoTransferFunction;
_frameVideoSample.SrcRect = targetRECT;
_frameVideoSample.DstRect = targetRECT;
_frameVideoSample.PlanarAlpha = DXVA2_Fixed32OpaqueAlpha();
_frameVideoSample.SampleData = DXVA2_SampleData_TFF;
CComPtr<IMFSample> sample; // Assume that this was read in from a call to ReadSample
CComPtr<IMFMediaBuffer> buffer;
HRESULT hr = sample->GetBufferByIndex(0, &buffer);
CComPtr<IDirect3DSurface9> pSrcSurface;
// From the MediaBuffer, we get the Source Surface using MFGetService
hr = MFGetService( buffer, MR_BUFFER_SERVICE, __uuidof(IDirect3DSurface9), (void**)&pSrcSurface );
// Update the videoProcessBltParams with frame specific values.
LONGLONG sampleStartTime;
sample->GetSampleTime(&sampleStartTime);
_frameBltParams.TargetFrame = sampleStartTime;
LONGLONG sampleDuration;
sample->GetSampleDuration(&sampleDuration);
_frameVideoSample.Start = sampleStartTime;
_frameVideoSample.End = sampleStartTime + sampleDuration;
_frameVideoSample.SrcSurface = pSrcSurface;
// Run videoProcessBlt using the parameters setup (this is used for color conversion)
// The returned code is E_INVALIDARGS
hr = _vpd->VideoProcessBlt( _pTargetSurface, // target surface
&_frameBltParams, // parameters
&_frameVideoSample, // video sample structure
1, // one sample
NULL); // reserved
After a call to ReadSample of IMFSourceReader or inside OnReadSample callback function of the IMFSourceReaderCallback implementation, you might receive the MF_SOURCE_READERF_CURRENTMEDIATYPECHANGED flag. It means that the current media type has changed for one or more streams. To get the current media type call the IMFSourceReader::GetCurrentMediaType method.
In your case you need to query (again) the IMFMediaType's MF_MT_FRAME_SIZE attribute for the video stream, in order to obtain the new correct video resolution. You should use the new video resolution to set the "width" and "height" values of the VideoProcessorBlt parameters' source and destination rectangles.

How to set general purpose timer to counter mode on STM32F411E?

I need a timer to increment with rising edge on the GPIO pin. I can't find any code example doing just that.
I have a digital Hall sensor which sense a magnet approaching the sensor and I want to count how many times the magnet came around the sensor. The sensor gives positive pulse when magnet goes around. I want to use this pulse to increment counter value.
I know how to set the timer into basic up-counting mode (with internal clock).
TIM_TimeBaseInitTypeDef TIM_BaseStruct;
/* Configure TIMER4*/
TIM_BaseStruct.TIM_Prescaler = 40000;
TIM_BaseStruct.TIM_CounterMode = TIM_CounterMode_Up;
TIM_BaseStruct.TIM_Period = 500;
TIM_BaseStruct.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_BaseStruct.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM4, &TIM_BaseStruct);
TIM_Cmd(TIM4, ENABLE);
And this works, but I need to switch the clock to external signal. How do I do that?
EDIT
After rewriting code from Guillaume Michel's answer with the use of functions defined in library I'm using (I do not use HAL library), I came up with a code
TIM_TimeBaseInitTypeDef timer4;
timer4.TIM_Prescaler=0;
timer4.TIM_CounterMode=TIM_CounterMode_Up;
timer4.TIM_Period=5;
timer4.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseInit(TIM4,&timer4);
TIM_ETRClockMode2Config(TIM4,TIM_ExtTRGPSC_DIV2,TIM_ExtTRGPolarity_NonInverted, 0);
TIM_SelectSlaveMode(TIM4,TIM_SlaveMode_Reset);
TIM_SelectMasterSlaveMode(TIM4, TIM_MasterSlaveMode_Disable);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_PinAFConfig(GPIOD,GPIO_Pin_13,GPIO_AF_TIM4);
GPIO_Init(GPIOD, &GPIO_InitStructure);
This is compilable, yet non-working code. I set the timer period to 5 and I set interrupt to toggle LED every time timer counts all the way up, but LED never lights on no matter how many times i run magnet around sensor. Is there some visible mistake? What can I do to make it work?
You could try to connect the hall sensor output on a GPIO of you STM32F411 and set this GPIO as clock of the timer. This could look like:
TIM_HandleTypeDef htim4;
TIM_ClockConfigTypeDef sClockSourceConfig;
TIM_MasterConfigTypeDef sMasterConfig;
htim4.Instance = TIM4;
htim4.Init.Prescaler = 0;
htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
htim4.Init.Period = 65535;
htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
HAL_TIM_Base_Init(&htim4);
sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_ETRMODE2;
sClockSourceConfig.ClockPolarity = TIM_CLOCKPOLARITY_NONINVERTED;
sClockSourceConfig.ClockPrescaler = TIM_CLOCKPRESCALER_DIV1;
sClockSourceConfig.ClockFilter = 0;
HAL_TIM_ConfigClockSource(&htim4, &sClockSourceConfig);
sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig);
The GPIO is set up like this:
//Set PE0 as TIM4_ETR
__HAL_RCC_GPIOE_CLK_ENABLE();
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF2_TIM4;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);

Get physical screen(display) resolution. Windows Store App

I need current display resolution. How can i get this? I know about Window.Current.Bounds, but application can worked in windows mode.
what do you mean VisibleBounds is not working on Deskptop?
I tried in my win10 UWP program, it works fine. I can get my desktop resotion like below:
var bounds = ApplicationView.GetForCurrentView().VisibleBounds;
var scaleFactor = DisplayInformation.GetForCurrentView().RawPixelsPerViewPixel;
var size = new Size(bounds.Width * scaleFactor, bounds.Height * scaleFactor);
Besides, if you are using DX in store app, you can create an IDXGIFactory object and use it to enumerate the available adapters. Then call IDXGIOutput::GetDisplayModeList to retrieve an array of DXGI_MODE_DESC structures and the number of elements in the array. Each DXGI_MODE_DESC structure represents a valid display mode for the output. e.g.:
UINT numModes = 0;
DXGI_MODE_DESC* displayModes = NULL;
DXGI_FORMAT format = DXGI_FORMAT_R32G32B32A32_FLOAT;
// Get the number of elements
hr = pOutput->GetDisplayModeList( format, 0, &numModes, NULL);
displayModes = new DXGI_MODE_DESC[numModes];
// Get the list
hr = pOutput->GetDisplayModeList( format, 0, &numModes, displayModes);
Please let me know if you need further information.

Taking a screenshot of a page in InDesign Extension Builder

For my current assignment I need to make an extension for Adobe InDesign using Adobe Creative Suit Extension Builder and Flash Builder. I guess this is more of a question for ones that know Extension Builder and InDesign API.
The point of this extension is to load some data and send some data to a server. I need to make a screenshot of a page, then send it in jpg to a server. But, there are no (or at least i couldnt find any) ways to create a bitmap(to cast it on a object seems impossible, because this Objects are just Objects, and not DisplayObjects).
I managed to silently export pages as jpegs, now I'm thinking about loading them and sending but that will require building an AIR app to handle it all, so this will be a bit bulky.
So to sum up the question, how to take a screencapture of all elements on a page in InDesign using CS Ext.Builder?
what is the problem with export to JPG ? You can choose to export the page or the objects themselves.
Here is a snippet I wrote in a recent project. Hope it helps.
public static function getFilePath():String {
var app:com.adobe.indesign.Application = InDesign.app;
var sel:* = app.selection, oldResolution:Number, oldColorSpace:JpegColorSpaceEnum, groupItems:Array = [], i:int = 0, n:int = sel.length;
if (!sel || !n )
{
Alert.show("Pas de selection !", "title", Alert.OK, Sprite(mx.core.Application.application));
return "";
}
for ( i = 0 ; i < n ; i ++ )
{
groupItems [ groupItems.length ] = sel[i];
}
sel = ( sel.length > 1 )? app.activeDocument.groups.add ( sel ) : sel[0] ;
var tempFolder:File = File.createTempDirectory();
AppModel.getInstance().jpgFolder = tempFolder;
var jpgFile:File = new File ();
jpgFile.nativePath = tempFolder.nativePath + "/temp.jpg";
oldResolution = app.jpegExportPreferences.exportResolution;
app.jpegExportPreferences.exportResolution = 72;
oldColorSpace = app.jpegExportPreferences.jpegColorSpace;
app.jpegExportPreferences.jpegColorSpace = JpegColorSpaceEnum.GRAY;
sel.exportFile ( ExportFormat.jpg, jpgFile );
app.jpegExportPreferences.jpegColorSpace = oldColorSpace;
app.jpegExportPreferences.exportResolution = oldResolution;
if ( sel is Group )
{
sel.ungroup();
app.select ( groupItems );
}
return jpgFile.nativePath;
}

New Background Image on each page reload

How can I display a new background image on each page refresh on a website (using Wordpress if this helps anything)? I would also like to take into account different screen resolutions, and proper handling for this. Any help would be greatly appreciated.
Have you seen this page in the wordpress codex?
It explains how to rotate the header image. It shouldn't be too hard adapt it for your needs.
Just have your own script that randomly returns pictures each time it is accessed. I have one that I wrote in C at the URL below that returns a different pic each time.
http://www.scale18.com/cgi-bin/gpic
You can generate it in realtime with GD library
To detect screen resolution, you can use client-side javascript
screen.height
screen.width
To display a different image, you could probably use a script to generate a random number and display the image that ties to it...?
You could store the "current" imaage in the session and just check each time you generate a new random number, that it's not going to display the last....
This is what I use with Wordpress to randomly rotate the header images on my site.
Someone else wrote the code and I can't remember who. Put the php code below into a file named rotate.php, and then put rotate.php into the directory of images that are to be rotated (i.e. "headerimages"), and rotate.php will draw from them. Call rotate.php from your CSS style sheet in whatever DIV is used for your headerimage.
I don't understand what you mean by being able to handle different screen resolutions. End user screen resolutions?
<?php
/*
Call this way: <img src="http://example.com/rotate.php">
Set $folder to the full path to the location of your images.
For example: $folder = '/user/me/example.com/images/';
If the rotate.php file will be in the same folder as your
images then you should leave it set to $folder = '.';
*/
$folder = '.';
$extList = array();
$extList['gif'] = 'image/gif';
$extList['jpg'] = 'image/jpeg';
$extList['jpeg'] = 'image/jpeg';
$extList['png'] = 'image/png';
$img = null;
if (substr($folder,-1) != '/') {
$folder = $folder.'/';
}
if (isset($_GET['img'])) {
$imageInfo = pathinfo($_GET['img']);
if (
isset( $extList[ strtolower( $imageInfo['extension'] ) ] ) &&
file_exists( $folder.$imageInfo['basename'] )
) {
$img = $folder.$imageInfo['basename'];
}
} else {
$fileList = array();
$handle = opendir($folder);
while ( false !== ( $file = readdir($handle) ) ) {
$file_info = pathinfo($file);
if (
isset( $extList[ strtolower( $file_info['extension'] ) ] )
) {
$fileList[] = $file;
}
}
closedir($handle);
if (count($fileList) > 0) {
$imageNumber = time() % count($fileList);
$img = $folder.$fileList[$imageNumber];
}
}
if ($img!=null) {
$imageInfo = pathinfo($img);
$contentType = 'Content-type: '.$extList[ $imageInfo['extension'] ];
header ($contentType);
readfile($img);
} else {
if ( function_exists('imagecreate') ) {
header ("Content-type: image/png");
$im = #imagecreate (100, 100)
or die ("Cannot initialize new GD image stream");
$background_color = imagecolorallocate ($im, 255, 255, 255);
$text_color = imagecolorallocate ($im, 0,0,0);
imagestring ($im, 2, 5, 5, "IMAGE ERROR", $text_color);
imagepng ($im);
imagedestroy($im);
}
}
?>
JavaScript is probably your best bet for this one.