QMediaPlayer : media stays in UnknownMediaStatus - qt

I created a QMediaPlayer, passed video address to it and it won't play. I checked the mediaStatus and player state, they all stays 0 all the time. The basic idea is:
QMediaPlayer player = new QMediaPlayer();
cout << player.mediaStatus(); // should print 1: NoMedia but is 0: UnknownMediaStatus
player.setVideoOutput(some_constructed_video_widget);
cout << player.mediaStatus(); // should print 1: NoMedia but is 0: UnknownMediaStatus
player.setMedia(QUrl::fromLocalFile("path/to/test/video/test.mp4"));
cout << player.mediaStatus(); // should print 2: LoadingMedia but is 0: UnknownMediaStatus
player.play();
cout << player.mediaStatus(); // should print 3: LoadedMedia but is 0: UnknownMediaStatus
// and of course, no video gets played
The mediaStatus is simply a enum: MediaStatus { UnknownMediaStatus, NoMedia, LoadingMedia, LoadedMedia, ..., InvalidMedia }
The questions are:
What may be causing this problem and how to fix that?
What are all the cases that a QMediaPlayer::mediaStatus() will return an QMediaPlayer::UnknownMediaStatus (please be conclusive)?
Edit with more information: The following is the output I get for the following code. Anyone has any idea what the error message means and how to fix that?
code:
int main(int argc, char *argv[])
{
QMediaPlayer * temp = new QMediaPlayer(0, QMediaPlayer::VideoSurface);
std::cout << "Constructed: " << temp->mediaStatus() << std::endl;
temp->setMedia(QUrl::fromLocalFile("path/to/video/test.mp4"));
std::cout << "SetMedia: " << temp->mediaStatus() << std::endl;
temp->play();
std::cout << "Play: " << temp->mediaStatus() << std::endl;
-> debug breakpoint here
......
}
output:
defaultServiceProvider::requestService(): no service found for - "org.qt-project.qt.mediaplayer"
Constructed: 0
SetMedia: 0
Play: 0
I am using Mac 10.9 and Qt 5.3.0, but I do not think the mac/qt version matters for this problem.

Related

Can't delete a pointer in C++

I got this code from a book. When I ran on Visual Studio, it said to switch strcpy() to strcpy_s(), and after I did that, it seems the program terminated at the delete pointer. I tried to run on Dev-C++, and it works fine. Anyone knows why? Thank you.
#include "pch.h"
#include <iostream>
#include <cstring>
int main()
{
cout << "Enter a kind of animal: ";
cin >> animal; // ok if input < 20 chars
ps = animal; // set ps to point to string
cout << ps << "!\n"; // ok, same as using animal
cout << "Before using strcpy():\n";
cout << animal << " at " << (int *)animal << endl;
cout << ps << " at " << (int *)ps << endl;
ps = new char[strlen(animal) + 1]; // get new storage
strcpy_s(ps, sizeof(animal), animal); // copy string to new storage
cout << "After using strcpy():\n";
cout << animal << " at " << (int *)animal << endl;
cout << ps << " at " << (int *)ps << endl;
delete[] ps;
return 0;
}

Reading from character device with Qt

I'm not very good at character devices, so I need your help. A have a char device(let's call it /dev/my_light) which is a light sensor. I have to read the data from this file and transform it to the brightness value and then pass it to the brightness manager that changes the brightness of my screen. The problem is that when I read the value for some period of time I get old values from the file.I assume there is a buffer(again not sure how character devices exactly work). Whereas when I use cat /dev/my_light I see new data! Is it possible to get rid off the buffer and read new values that were written to the file just right now. Here is my code in Qt:
void MySensor::updateMySensor()
{
Packet packet;
packet.startByte = 0;
packet.mantissa = 0;
packet.exp = 0;
d->device = ::open(d->path.toStdString().c_str(), O_RDONLY);
if (d->device == -1)
{
qDebug() << Q_FUNC_INFO << "can't open the sensor";
return;
}
ssize_t size = ::read(d->device, &packet, sizeof(packet));
close(d->device);
if (size == -1)
{
qDebug() << errno;
return;
}
packet.exp &= 0x0F;
float illumination = pow(2, packet.exp) * packet.mantissa * 0.045;
if(d->singleShot) emit lightSensorIsRunning(true);
emit illuminationRead(illumination);
}
The mySensor function is called every second. I tried to call it each 200 msec but it didn't help. The value of illumination stays old for about 7 seconds(!) whereas the value that I get from cat is new just immediately.
Thank you in advance!
I can't test with your specific device, however, I'm using the keyboard as a read only device.
The program attempts to connect to keyboard and read all keys pressed inside and outside the window. It's a broad solution you'll have to adapt to meet your demands.
Note that I'm opening the file with O_RDONLY | O_NONBLOCK which means open in read only mode and no wait for the event be triggered(some notifier needed to know when data is ready!) respectively.
You'll need super user privilege to run this example!
#include <QtCore>
#include <fcntl.h>
#include <linux/input.h>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
const char *device_name = "/dev/input/by-path/platform-i8042-serio-0-event-kbd";
int descriptor = open(device_name, O_RDONLY | O_NONBLOCK);
if (descriptor < 0)
{
qDebug() << "Error" << strerror(errno);
return a.exec();
}
QFile device;
if (!device.open(descriptor, QFile::ReadOnly))
{
qDebug() << "Error" << qPrintable(device.errorString());
return a.exec();
}
QSocketNotifier notifier(device.handle(), QSocketNotifier::Read);
QObject::connect(&notifier, &QSocketNotifier::activated, &notifier, [&](int socket){
Q_UNUSED(socket)
struct input_event ev;
QByteArray data = device.readAll();
qDebug() << "Event caught:"
<< "\n\nDATA SIZE" << data.size()
<< "\nSTRUCT COUNT" << data.size() / int(sizeof(input_event))
<< "\nSTRUCT SIZE" << sizeof(input_event);
qDebug() << ""; //New line
while (data.size() >= int(sizeof(input_event)))
{
memcpy(&ev, data.data(), sizeof(input_event));
data.remove(0, int(sizeof(input_event)));
qDebug() << "TYPE" << ev.type << "CODE" << ev.code << "VALUE" << ev.value << "TIME" << ev.time.tv_sec;
}
qDebug() << ""; //New line
});
return a.exec();
}

QAbstractVideoSurface generating A Null Image

I'm reimplemented the present method from a QAbstractVideo Surface in order to capture frames from an IP camera.
This is my reimplemented methods (the required ones):
QList<QVideoFrame::PixelFormat> CameraFrameGrabber::supportedPixelFormats(QAbstractVideoBuffer::HandleType handleType) const
{
Q_UNUSED(handleType);
return QList<QVideoFrame::PixelFormat>()
<< QVideoFrame::Format_ARGB32
<< QVideoFrame::Format_ARGB32_Premultiplied
<< QVideoFrame::Format_RGB32
<< QVideoFrame::Format_RGB24
<< QVideoFrame::Format_RGB565
<< QVideoFrame::Format_RGB555
<< QVideoFrame::Format_ARGB8565_Premultiplied
<< QVideoFrame::Format_BGRA32
<< QVideoFrame::Format_BGRA32_Premultiplied
<< QVideoFrame::Format_BGR32
<< QVideoFrame::Format_BGR24
<< QVideoFrame::Format_BGR565
<< QVideoFrame::Format_BGR555
<< QVideoFrame::Format_BGRA5658_Premultiplied
<< QVideoFrame::Format_AYUV444
<< QVideoFrame::Format_AYUV444_Premultiplied
<< QVideoFrame::Format_YUV444
<< QVideoFrame::Format_YUV420P
<< QVideoFrame::Format_YV12
<< QVideoFrame::Format_UYVY
<< QVideoFrame::Format_YUYV
<< QVideoFrame::Format_NV12
<< QVideoFrame::Format_NV21
<< QVideoFrame::Format_IMC1
<< QVideoFrame::Format_IMC2
<< QVideoFrame::Format_IMC3
<< QVideoFrame::Format_IMC4
<< QVideoFrame::Format_Y8
<< QVideoFrame::Format_Y16
<< QVideoFrame::Format_Jpeg
<< QVideoFrame::Format_CameraRaw
<< QVideoFrame::Format_AdobeDng;
}
bool CameraFrameGrabber::present(const QVideoFrame &frame)
{
//qWarning() << "A frame";
if (frame.isValid()) {
//qWarning() << "Valid Frame";
QVideoFrame cloneFrame(frame);
cloneFrame.map(QAbstractVideoBuffer::ReadOnly);
const QImage image(cloneFrame.bits(),
cloneFrame.width(),
cloneFrame.height(),
QVideoFrame::imageFormatFromPixelFormat(cloneFrame .pixelFormat()));
qWarning() << "Is created image NULL?" << image.isNull();
if (!image.isNull())
emit nextFrameAsImage(image);
cloneFrame.unmap();
return true;
}
return false;
}
And this is is how I used it:
grabber = new CameraFrameGrabber(this);
connect(grabber,&CameraFrameGrabber::nextFrameAsImage,this,&QCmaraTest::on_newFrame);
QMediaPlayer *a = new QMediaPlayer(this);
QString url = "http://Admin:1234#10.255.255.67:8008";
a->setMedia(QUrl(url));
a->setVideoOutput(grabber);
a->play();
The problem is that the image that is created is null. As far as I can tell, this can only be because the frame is valid but does not contain data.
Any ideas what the problem could be?
Important Detail: If I set the stream to a QVideoWidget and simply show that, it works just fine.
So I found out what the problem was.
This:
QVideoFrame::imageFormatFromPixelFormat(cloneFrame .pixelFormat())
Was returning invalid format because the IP cam gave the format as a YUV format which QImage can't handle. The solution was to force the format and the only one I found that did not make the program crash was: QImage::Format_Grayscale8.
With that, it worked.

OpenCL Vector add program

I'm absolutely new to OpenCL programming. I have a working installation of OpenCL library and drivers. But the program I'm trying to run is not producing expected output (Output is all zeros). It is just a simple vector_add program.
Thanks in advance for suggestions.
int main(int argc, char** argv)
{
cout << "Hello OpenCL" << endl;
vector<Platform> all_platforms;
int err = Platform::get(&all_platforms);
cout << "Getting Platform ... Error code " << err << endl;
if (all_platforms.size()==0)
(cout << "No platforms" << endl, exit(0));
cout << "Platform info : " << all_platforms[0].getInfo<CL_PLATFORM_NAME>() << endl;
Platform default_platform = all_platforms[0];
cout << "Defaulting to it ..." << endl;
vector<Device> all_devices;
err = default_platform.getDevices(CL_DEVICE_TYPE_GPU, &all_devices);
cout << "Getting devices ... Error code : " << err << endl;
if (all_devices.size()==0)
(cout << "No devices" << endl, exit(0));
Device default_device = all_devices[0];
cout << all_devices.size() << " devices & " << "Device info : " << all_devices[0].getInfo<CL_DEVICE_NAME>() << endl;
cout << "Defaulting to it ..." << endl;
Context context(default_device);
Program::Sources sources;
std::string kernel_code=
" void kernel simple_add(global const int* A, global const int* B, global int* C){"
" unsigned int i = get_global_id(0); "
" C[i]=A[i]+B[i]; "
" } ";
sources.push_back(make_pair(kernel_code.c_str(), kernel_code.length()+1));
Program program(context, sources);
if (program.build(all_devices)==CL_SUCCESS)
cout << "Built Successfully" << endl;
Buffer buffer_A(context,CL_MEM_READ_WRITE,sizeof(int)*10);
Buffer buffer_B(context,CL_MEM_READ_WRITE,sizeof(int)*10);
Buffer buffer_C(context,CL_MEM_READ_WRITE,sizeof(int)*10);
int A[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int B[] = {0, 1, 2, 0, 1, 2, 0, 1, 2, 0};
CommandQueue queue(context,default_device);
queue.enqueueWriteBuffer(buffer_A,CL_TRUE,0,sizeof(int)*10,A); // load data from host to device
queue.enqueueWriteBuffer(buffer_B,CL_TRUE,0,sizeof(int)*10,B);
Kernel kernel(program, "vector_add");
kernel.setArg(0, buffer_A);
kernel.setArg(1, buffer_B);
kernel.setArg(2, buffer_C);
queue.enqueueNDRangeKernel(kernel,cl::NullRange,cl::NDRange(10),cl::NullRange);
queue.finish();
int *C = new int[10];
queue.enqueueReadBuffer(buffer_C, CL_TRUE, 0, 10 * sizeof(int), C);
for (int i=0;i<10;i++)
std::cout << A[i] << " + " << B[i] << " = " << C[i] << std::endl;
return 0;
}
As pointed out in the comments, you should always check the error codes when using OpenCL API functions. This can be achieved by enabling exception handling in the C++ wrapper:
#define __CL_ENABLE_EXCEPTIONS // with cl.hpp
//#define CL_HPP_ENABLE_EXCEPTIONS // with cl2.hpp
#include <CL/cl.hpp>
int main(int argc, char *argv[])
{
try
{
// OpenCL code here
}
catch (cl::Error& err)
{
cout << err.what() << " failed with error code " << err.err() << endl;
}
}
If you do this, you will receive useful information about a couple of issues with your code.
The clCreateKernel function returns CL_INVALID_NAME. In your kernel, you define the kernel function with the name simple_add, but then you try and create a kernel object using the name vector_add.
If you have an OpenCL platform with multiple devices, you may also receive an error when building your kernel program. This is because you are creating an OpenCL context with a single device, but then trying to build the program for a list of devices:
Context context(default_device);
// ...
if (program.build(all_devices)==CL_SUCCESS)
cout << "Built Successfully" << endl;
The simplest fix is just to remove the argument from the build function, since by default it will build the program for all devices in the context (which is almost always what you actually want):
if (program.build()==CL_SUCCESS)
cout << "Built Successfully" << endl;

QtCreator 2.4.1 console input

I'm somewhat new to C++ and QT.
Trying to run a very simple program in QtCreator, which uses console input on WinXP:
#include <QString>
#include <QTextStream>
int main() {
QTextStream streamOut(stdout);
QTextStream streamIn(stdin);
QString s1("This "), s2("is a "), s3("string.");
QString s4 = s1 + s2 + s3;
streamOut << s4 << endl;
streamOut << "The length of that string is " << s4.length() << endl;
streamOut << "Enter a sentence with whitespaces: " << endl;
s4 = streamIn.readLine();
streamOut << "Here is your sentence: \n" << s4 << endl;
streamOut << "The length of your sentence is: " << s4.length() << endl;
return 0;
}
Problem is that native QTCreator's application output, for it's name, doesn't support typing in things. Here is application output:
Starting C:\QProject\test-build-desktop-Qt_4_8_0_for_Desktop_-MinGW_Qt_SDK___>z>>\debug\test.exe...
This is a string.
The length of that string is 17
Enter a sentence with whitespaces:
Qml debugging is enabled. Only use this in a safe environment!
I've tried checking "Run in terminal" in Projects>Desktop>Run as some answers to similar questions here suggested and the terminal shows up, but it doesn't seem to interact with the program anyhow. Terminal's output:
Press RETURN to close this window...
I would say that checking Run in terminal is correct and needed.
What is surprising is that you don't get any compile error, as there is a mistake at line 8 :
cout << "Enter a sentence: "<<;
The last << is wrong.
Correcting your code, I get this :
#include <QString>
#include <QTextStream>
QTextStream cout(stdout);
QTextStream cin(stdin);
int main() {
QString s2;
cout << "Enter a sentence: ";
s2 = cin.readLine();
cout << "Here is your sentence:" << s2 << endl;
cout << "The length of your sentence is: " << s2.length() << endl;
return 0;
}
which works fine on my computer (WinXP, QtCreator 2.2.0).
Are you sure your Qt project is correct and that you are compiling the right file ?

Resources