There is an android_camera.c file in the ffmpeg project. I want to call NDK camera through ffmpeg, take out YUV data, and write it to the file. Currently, the code has been blocking the function wait_for_image_format.
android_camera.c
#include <stdio.h>
#include <math.h>
#include <libavutil/opt.h>
#include <libavcodec/avcodec.h>
#include <libavutil/channel_layout.h>
#include <libavutil/common.h>
#include <libavutil/imgutils.h>
#include <libavutil/mathematics.h>
#include <libavutil/samplefmt.h>
#include <libavformat/avformat.h>
#include <libavdevice/avdevice.h>
#include <libavutil/dict.h>
int main(int argc, char **argv) {
int ret;
AVFormatContext *fmtCtx = NULL;
AVPacket pkt1, *pcaket = &pkt1;
/*1、注册*/
avcodec_register_all();
avdevice_register_all();
/*2、连接视频源*/
AVInputFormat *inputFmt = av_find_input_format("android_camera");
if (NULL != inputFmt) {
printf("input device name:%s\n",inputFmt->name);
} else {
printf("Null point!\n");
}
#if 1
AVDictionary *avdict = NULL;
AVDictionaryEntry *t = av_dict_get(avdict, "video_size", NULL, AV_DICT_IGNORE_SUFFIX);
printf("ok1\n");
av_dict_set(&avdict, "video_size", "hd720", 0);
av_dict_set_int(&avdict, "camera_index",1, 0);
av_dict_set_int(&avdict, "input_queue_size",2, 0);
printf("ok2\n");
/*3、打开视频采集设备*/
//ret = avformat_open_input(&fmtCtx, "video=/dev/video1", inputFmt, avdict);
//ret = avformat_open_input(&fmtCtx, "android_camera", inputFmt, avdict);
fmtCtx = avformat_alloc_context();
if (NULL == fmtCtx) {
printf("Open input device seccess!\n");
}
printf("ok3\n");
//if (avformat_find_stream_info(fmtCtx, NULL) < 0) {
// printf("Could not find stream information\n");
//}
//printf("ok4\n");
ret = avformat_open_input(&fmtCtx, NULL, inputFmt, &avdict);
printf("ok4\n");
av_dict_free(&avdict);
#else
fmtCtx = avformat_alloc_context();
if(!fmtCtx)
{
printf("avformat_alloc_contest error\n");
exit(1);
}
#endif
printf("ok5\n");
//ret = av_demuxer_open(fmtCtx);
if(ret<0)
{
printf("av_demuxer_open error\n");
}
printf("ok6\n");
/*4、读取一帧数据,编码依据摄像头类型而定,我使用的摄像头输出的是yuv422格式*/
fmtCtx->flags &= (~0x4);
av_read_frame(fmtCtx, pcaket);
printf("ok7\n");
//printf("packet size:%d\n",(pcaket->size));
/*5、写入帧数据到文件*/
FILE *fp = NULL;
fp = fopen("out.yuv", "a+");
if (NULL != fp) {
//将数据写入文件
fwrite(pcaket->data, 1, pcaket->size, fp);
}
//关闭文件
fclose(fp);
/*6、释放读取的帧数据*/
av_free_packet(pcaket);
/*7、关闭视频输入源*/
avformat_close_input(&fmtCtx);
return 0;
}
Related
What if the EEPROM used is greater than 32K, such as at24c32, and the register address is 16bit? It seems that smbus only supports 8bit registers?
I can read 0xff, but the written content will return - 5, which fails.
I want to know whether the kernel only supports 8-bit registers, but not 16 bit registers?
This is my code:
#include <fcntl.h>
#include <stdio.h>
#include <linux/i2c-dev.h>
#include <errno.h>
#include <stddef.h>
#include <sys/ioctl.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <linux/types.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <stdint.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <ctype.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <errno.h>
#include <signal.h>
#define AT24C32_ADDR 0x53
__s32 i2c_smbus_access(int file, char read_write, __u8 command,
int size, union i2c_smbus_data* data)
{
struct i2c_smbus_ioctl_data args;
__s32 err;
args.read_write = read_write;
args.command = command;
args.size = size;
args.data = data;
err = ioctl(file, I2C_SMBUS, &args);
if (err == -1)
err = -errno;
return err;
}
__s32 i2c_smbus_write_byte_data(int file, __u8 command, __u8 value)
{
union i2c_smbus_data data;
data.byte = value;
return i2c_smbus_access(file, I2C_SMBUS_WRITE, command,
I2C_SMBUS_BYTE_DATA, &data);
}
__s32 i2c_smbus_read_byte_data(int file, __u8 command)
{
union i2c_smbus_data data;
int err;
err = i2c_smbus_access(file, I2C_SMBUS_READ, command,
I2C_SMBUS_BYTE_DATA, &data);
if (err < 0)
return err;
return 0x0FF & data.byte;
}
static int32_t i2c_smbus_write_word_data(int file, uint8_t cmd, uint16_t value)
{
union i2c_smbus_data data;
data.word = value;
return i2c_smbus_access(file, I2C_SMBUS_WRITE, cmd,
I2C_SMBUS_WORD_DATA, &data);
}
static int32_t i2c_smbus_read_word_data(int fd, uint8_t cmd)
{
union i2c_smbus_data data;
int err;
err = i2c_smbus_access(fd, I2C_SMBUS_READ, cmd,
I2C_SMBUS_WORD_DATA, &data);
if (err < 0)
return err;
return data.word;
}
int set_slave_addr(int file, int address, int force)
{
/* With force, let the user read from/write to the registers
even when a driver is also running */
if (ioctl(file, force ? I2C_SLAVE_FORCE : I2C_SLAVE, address) < 0) {
fprintf(stderr,
"Error: Could not set address to 0x%02x: %s\n",
address, strerror(errno));
return -errno;
}
return 0;
}
I am trying to replace the Windows Bluetooth pairing. I found some code that was suppose to do this, and I mostly mimiced that code. Although, when I run the code which is below I always get a 258 error code.
Below is the code that does the actual pairing.
#include <stdio.h>
#include <tchar.h>
#include <stdlib.h>
#include <initguid.h>
#include <winsock2.h>
#include <ws2bth.h>
#include <BluetoothAPIs.h>
bool BluetoothAuthCallback(LPVOID pvParam, PBLUETOOTH_AUTHENTICATION_CALLBACK_PARAMS pAuthCallbackParams)
{
DWORD dwRet;
fprintf(stderr, "BluetoothAuthCallback 0x%x\n", pAuthCallbackParams->deviceInfo.Address.ullLong);
dwRet = BluetoothSendAuthenticationResponse(NULL, &(pAuthCallbackParams->deviceInfo), L"1234");
if(dwRet != ERROR_SUCCESS)
{
fprintf(stderr, "BluetoothSendAuthenticationResponse ret %d\n", dwRet);
ExitProcess(2);
return 1;
}
fprintf(stderr, "BluetoothAuthCallback finish\n");
ExitProcess(0);
return 1;
}
int _tmain(int argc, _TCHAR* argv[])
{
SOCKADDR_BTH sa = { 0 };
int sa_len = sizeof(sa);
DWORD dwRet;
BLUETOOTH_DEVICE_INFO btdi = {0};
HBLUETOOTH_AUTHENTICATION_REGISTRATION hRegHandle = 0;
// initialize windows sockets
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD( 2, 0 );
if( WSAStartup( wVersionRequested, &wsaData ) != 0 ) {
ExitProcess(2);
}
// parse the specified Bluetooth address
if( argc < 2 ) {
fprintf(stderr, "usage: rfcomm-client <addr>\n"
"\n addr must be in the form (XX:XX:XX:XX:XX:XX)");
ExitProcess(2);
}
if( SOCKET_ERROR == WSAStringToAddress( argv[1], AF_BTH,
NULL, (LPSOCKADDR) &sa, &sa_len ) ) {
ExitProcess(2);
}
btdi.dwSize = sizeof(BLUETOOTH_DEVICE_INFO);
btdi.Address.ullLong = sa.btAddr;
btdi.ulClassofDevice = 0;
btdi.fConnected = false;
btdi.fRemembered = false;
btdi.fAuthenticated = false;
dwRet = BluetoothRegisterForAuthenticationEx(&btdi, &hRegHandle, (PFN_AUTHENTICATION_CALLBACK_EX)&BluetoothAuthCallback, NULL);
if(dwRet != ERROR_SUCCESS)
{
fprintf(stderr, "BluetoothRegisterForAuthenticationEx ret %d\n", dwRet);
ExitProcess(2);
}
dwRet = BluetoothAuthenticateDeviceEx(NULL, NULL, &btdi, NULL,MITMProtectionNotRequired);
if(dwRet != ERROR_SUCCESS)
{
fprintf(stderr, "BluetoothAuthenticateDevice ret %d\n", dwRet);
ExitProcess(2);
}
Sleep(1000);
fprintf(stderr, "pairing finish\n");
ExitProcess(0);
return 0;
}
Below this is how I find the address to pass into the pairing application.
// BluetoothAddressFinder.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <initguid.h>
#include <winsock2.h>
#include <ws2bth.h>
#include <BluetoothAPIs.h>
int _tmain(int argc, _TCHAR* argv[])
{
BLUETOOTH_RADIO_INFO m_bt_info = {sizeof(BLUETOOTH_RADIO_INFO),0,};
BLUETOOTH_FIND_RADIO_PARAMS m_bt_find_radio = {sizeof(BLUETOOTH_FIND_RADIO_PARAMS)};
BLUETOOTH_DEVICE_INFO m_device_info = {sizeof(BLUETOOTH_DEVICE_INFO),0,};
BLUETOOTH_DEVICE_SEARCH_PARAMS m_search_params = {
sizeof(BLUETOOTH_DEVICE_SEARCH_PARAMS),
1, 0,
1,1,1,15,NULL
};
HANDLE m_radio = NULL;
HBLUETOOTH_RADIO_FIND m_bt = NULL;
HBLUETOOTH_DEVICE_FIND m_bt_dev = NULL;
int m_radio_id;
DWORD mbtinfo_ret;
int tempNumberOfDevices = 0;
m_bt = BluetoothFindFirstRadio(&m_bt_find_radio, &m_radio);
m_radio_id = 0;
do {
// Then get the radio device info....
mbtinfo_ret = BluetoothGetRadioInfo(m_radio, &m_bt_info);
// If there was an issue with the current radio check the next radio
if(mbtinfo_ret != ERROR_SUCCESS)
continue;
m_search_params.hRadio = m_radio;
ZeroMemory(&m_device_info, sizeof(BLUETOOTH_DEVICE_INFO));
m_device_info.dwSize = sizeof(BLUETOOTH_DEVICE_INFO);
// Next for every radio, get the device
m_bt_dev = BluetoothFindFirstDevice(&m_search_params, &m_device_info);
// Get the device info
do {
tempNumberOfDevices+=1;
fprintf(stdout, "Device name: %S Device Address: %d:%d:%d:%d:%d:%d \n" ,m_device_info.szName,m_device_info.Address.rgBytes[5],m_device_info.Address.rgBytes[4], m_device_info.Address.rgBytes[3], m_device_info.Address.rgBytes[2], m_device_info.Address.rgBytes[1], m_device_info.Address.rgBytes[0] );
} while(BluetoothFindNextDevice(m_bt_dev, &m_device_info));
} while(BluetoothFindNextRadio(&m_bt_find_radio, &m_radio));
}
I changed in my code avcodec_decode_audio3 to avcodec_decode_audio4 and added the frame handling. But now I cannot decode AAC frames anymore.
Why does avcodec_decode_audio4 return -22 (invalid argument)?
Following the answer below, does this have something to do with the parameters in AVContext that need to be set?
I had to use avcodec_decode_audio4 because I updated my ffmpeg and then got the following error:
[NULL # 0xb14f020] Custom get_buffer() for use withavcodec_decode_audio3() detected.
Overriding with avcodec_default_get_buffer
[NULL # 0xb14f020] Please port your application to avcodec_decode_audio4()
According to Buffer error in avcodec_decode_audio4() this is a regression, is there any other solution for this than going back to ffmpeg < 0.8 ?
The decoder using avcodec_decode_audio4:
AVCodec *codec;
AVCodecContext *avCtx;
AVFrame * decoded_frame = NULL;
uint8_t *outbuf = static_cast<uint8_t *>(malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE));
AVPacket avPacket;
main(){
av_register_all();
codec = avcodec_find_decoder(CODEC_ID_AAC);
//set parameters
avCtx = avcodec_alloc_context3(codec);
avCtx->channels = 1;
avCtx->sample_rate = 44100;
avCtx->bit_rate=16;
if (avcodec_open2(avCtx, codec, NULL) < 0) printf("Could not open codec\n");
av_init_packet(&avPacket);
//Main decoder loop
while(1)
my_frame_decoder();
return 0;
}
void my_frame_decoder() {
//get data
...
avPacket.size = numBytes;
avPacket.data = inputBytes;
int len;
while (avPacket.size > 0) {
int got_frame = 0;
if (!decoded_frame) {
if (!(decoded_frame = avcodec_alloc_frame())) {
printf("out of memory");
return;
}
} else {
avcodec_get_frame_defaults(decoded_frame);
}
//-------------------->> returns always -22
len = avcodec_decode_audio4(avCtx, decoded_frame, &got_frame, &avPacket);
//do something with the decoded frame
...
avPacket.size -= len;
avPacket.data += len;
}
return;
}
After hours of searching, i found out that the dec_ctx of the avcodec_decode_audio4 must be opened by a dec_codec initialised by av_find_best_stream()
1° av_find_best_stream(in_fmt_ctx, AVMEDIA_TYPE_AUDIO, -1, -1,
&dec_codec, 0);<br>
2° dec_ctx = m_in_aud_strm->codec;<br>
3° av_opt_set_int(dec_ctx, "refcounted_frames", 1, 0);<br>
4° avcodec_open2(dec_ctx, dec_codec, NULL)<br>
.
.
.
5° avcodec_decode_audio4(dec_ctx, pFrame, &got_frame, &pkt);
I think the problem is the parameters set in your codec's context. Please refer to https://www.ffmpeg.org/doxygen/trunk/structAVCodecContext.html for setting the parameters, which has changed from avcodec_decode_audio3 to avcodec_decode_audio4.
No solution but a workaround is to go back to older builds. After testing various builds that work with avcodec_decode_audio3, I thought it might be useful for others to know that ffmpeg-0.10.14.tar.bz2 from https://ffmpeg.org/releases/ works.
<!-- language: c++ -->
#include <windows.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include <fcntl.h>
#include <ctype.h>
#include <math.h>
#include <wctype.h>
#include <wchar.h>
#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <locale.h>
#include <signal.h>
#include <limits.h>
#include <float.h>
#include <iso646.h>
#undef NDEBUG
#include <assert.h>
// Use avcodec_send_packet() and avcodec_receive_frame().
//sample code
while (av_read_frame (FormatContext, packet_ptr) >= 0)
{
/* some code */
if (packet_ptr->stream_index == audiostream)
{
assert(NULL == decoded_frame);
decoded_frame = av_frame_alloc();
ret = avcodec_send_packet(pCodecCtx, packet_ptr);
if (ret < 0 && ret != AVERROR(EAGAIN) && ret != AVERROR_EOF)
{
av_packet_unref (packet_ptr);
if (decoded_frame)
{
av_frame_unref(decoded_frame);
decoded_frame = NULL;
}
continue;
}
else
{
if (0 <= ret)
packet_ptr->size = 0;
ret = avcodec_receive_frame(pCodecCtx, decoded_frame);
if (ret >= 0)
got_frame = 1;
else
{
got_frame = 0;
if (decoded_frame)
{
av_frame_unref(decoded_frame);
decoded_frame = NULL;
}
av_packet_unref (packet_ptr);
continue;
}
}
if(AV_SAMPLE_FMT_FLTP == pCodecCtx->sample_fmt)//AAC sample format for Libav released 10-October-2020 (ffmpeg 4.3.1)
{
//now get the PCM data ready to play or save
int nb_samples = decoded_frame->nb_samples;
int channels = pCodecCtx->channels;
if(channels > 2) //for this small sample only 2 channels...
{
channels = 2;//it will convert multichannel media files to 2 channels, remember this...more code need to be modified
}
int outputBufferLen = nb_samples * channels * 2;
int size_out //the size of the PCM data as sizeof(char)
=outputBufferLen;
char * buf = malloc(size_out);
short *outputBuffer=(short *)buf;
int in_samples = decoded_frame->nb_samples;
int i=0;
float * inputChannel0 = (float *)decoded_frame->extended_data[0];
// Mono
if (pCodecCtx->channels==1)
{
for (i=0; i<in_samples; i++)
{
float sample = *inputChannel0++;
if (sample<-1.0f) sample=-1.0f;
else if (sample>1.0f) sample=1.0f;
outputBuffer[i] = (int16_t) (sample * 32767.0f);//largest positive int16_t
}
}
// Stereo
else
{
float * inputChannel1 = (float *)decoded_frame->extended_data[1];
for (i=0; i < in_samples; i++)
{
float sample = *inputChannel0++;
if (sample<-1.0f) sample=-1.0f;
else if (sample>1.0f) sample=1.0f;
float sample2 = *inputChannel1++;
if (sample2<-1.0f) sample2=-1.0f;
else if (sample2>1.0f) sample2=1.0f;
outputBuffer[i*2] = (int16_t) ((sample) * 32767.0f);
outputBuffer[i*2+1] = (int16_t) ((sample2) * 32767.0f);
}
}
//use buf and size_out here then free the buf
free(buf);
}
}
av_packet_unref (packet_ptr);
if (decoded_frame)
{
av_frame_unref(decoded_frame);
decoded_frame = NULL;
}
}
Hope it helps...
I'm new using OpenAl library. I'm following the OpenAl programming guide but i can't find.
I have this code extracted from page 10 of the OpenAl programming guide but still have no sound. I use OSX Snow Leopard, i know OSX doesn't have ALUT defined.
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <OpenAL/al.h>
#include <OpenAL/alc.h>
using namespace std;
#define NUM_BUFFERS 3
#define BUFFER_SIZE 4096
int main(int argc, char **argv)
{
ALCdevice *dev;
ALCcontext *ctx;
struct stat statbuf;
Aluint buffer[NUM_BUFFERS];
Aluint source[NUM_SOURCES];
ALsizei size, freq;
ALenum format;
ALvoid *data;
// Initialization
dev = alcOpenDevice(NULL); // select the "preferred dev"
if (dev)
{
ctx = alcCreateContext(dev,NULL);
alcMakeContextCurrent(ctx);
}
// Check for EAX 2.0 support
// g_bEAX = alIsExtensionPresent("EAX2.0");
// Generate Buffers
alGetError(); // clear error code
alGenBuffers(NUM_BUFFERS, buffer);
if ((error = alGetError()) != AL_NO_ERROR)
{
DisplayALError("alGenBuffers :", error);
return 1;
}
// Load test.wav
loadWAVFile("sample.wav", &format, &data, &size, &freq, &loop);
if ((error = alGetError()) != AL_NO_ERROR)
{
DisplayALError("LoadWAVFile sample.wav : ", error);
alDeleteBuffers(NUM_BUFFERS, buffer);
return 1;
}
// Copy test.wav data into AL Buffer 0
alBufferData(buffer[0], format, data, size, freq);
if ((error = alGetError()) != AL_NO_ERROR)
{
DisplayALError("alBufferData buffer 0 : ", error);
alDeleteBuffers(NUM_BUFFERS, buffer);
return 1;
}
// Unload test.wav
unloadWAV(format, data, size, freq);
if ((error = alGetError()) != AL_NO_ERROR)
{
DisplayALError("UnloadWAV : ", error);
alDeleteBuffers(NUM_BUFFERS, buffer);
return 1;
}
// Generate Sources
alGenSources(1, source);
if ((error = alGetError()) != AL_NO_ERROR)
{
DisplayALError("alGenSources 1 : ", error);
return 1;
}
// Attach buffer 0 to source
alSourcei(source[0], AL_BUFFER, buffer[0]);
if ((error = alGetError()) != AL_NO_ERROR)
{
DisplayALError("alSourcei AL_BUFFER 0 : ", error);
}
// Exit
ctx = alcGetCurrentContext();
dev = alcGetContextsDevice(ctx);
alcMakeContextCurrent(NULL);
alcDestroyContext(ctx);
alcCloseDevice(dev);
return 0;
}
What things I missed to make this code work ???
What i'm doing wrong ???
Any advice could help, thanks.
You are not calling alSourcePlay(source[0]) to start the playback.
I'm testing out multicast with the two programs below. The client run well on linux and in wine on two of my machines, but it won't work properly on my windows machine (in Virtualbox).
Strangely, if I start up vlc in windows and open the udp stream, the client program receives the packets - and when I stop vlc, the client goes silent again.
What am I doing wrong?
Here is the the server program:
/*
* server.c - multicast server program.
*/
#include <sys/types.h>
#ifdef WINDOWS
#include <winsock.h>
#include <windows.h>
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#endif
#include <time.h>
#include <string.h>
#include <stdio.h>
#define HELLO_PORT 5004
#define HELLO_GROUP "224.0.0.1"
int main(int argc, char *argv[])
{
struct sockaddr_in addr;
int fd, cnt, numbytes;
struct ip_mreq mreq;
char message[100];
#ifdef WINDOWS
WSADATA wsaData; /* Windows socket DLL structure */
if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) {
fprintf(stderr, "WSAStartup() failed");
return 1;
}
#endif
/* create what looks like an ordinary UDP socket */
if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
fprintf(stderr, "failed to create socket.\n");
return 1;
}
/* set up destination address */
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr(HELLO_GROUP);
addr.sin_port = htons(HELLO_PORT);
/* now just sendto() our destination! */
cnt = 0;
while (1) {
numbytes = sprintf(message, "%d", cnt);
if (sendto(fd, message, numbytes, 0, (struct sockaddr*)&addr,
sizeof(addr)) < 0) {
fprintf(stderr, "sendto failed.\n");
return 1;
}
#ifdef WINDOWS
Sleep(1000);
#else
sleep(1);
#endif
cnt++;
}
return 0;
}
and here's the client program:
/*
* client.c -- client program for udp multicast data.
*/
#include <sys/types.h>
#ifdef WINDOWS
#include <winsock.h>
#else
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#endif
#include <time.h>
#include <string.h>
#include <stdio.h>
#define HELLO_GROUP "224.0.0.1"
#define HELLO_PORT 5004
#define MSGBUFSIZE 256
int main(int argc, char *argv[])
{
struct sockaddr_in addr;
int fd, nbytes,addrlen;
struct ip_mreq mreq;
char msgbuf[MSGBUFSIZE];
u_int yes = 1;
#ifdef WINDOWS
WSADATA wsaData; /* Windows socket DLL structure */
if (WSAStartup(MAKEWORD(2, 0), &wsaData) != 0) {
fprintf(stderr, "WSAStartup() failed");
return 1;
}
#endif
/* create what looks like an ordinary UDP socket */
fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd == -1) {
fprintf(stderr, "failed to create socket.\n");
return 1;
}
/* allow multiple sockets to use the same PORT number */
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&yes, sizeof(yes)) != 0) {
fprintf(stderr, "failed to reuse port number.\n");
return 1;
}
/* set up destination address */
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = INADDR_ANY;
addr.sin_port = htons(HELLO_PORT);
/* bind to receive address */
if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) != 0) {
fprintf(stderr, "failed to bind socket.\n");
return 1;
}
/* use setsockopt() to request that the kernel join a multicast group */
mreq.imr_multiaddr.s_addr = inet_addr(HELLO_GROUP);
mreq.imr_interface.s_addr = INADDR_ANY;
if (setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const char*)&mreq, sizeof(mreq)) != 0) {
fprintf(stderr, "failed to join the multicast group.\n");
return 1;
}
/* now just enter a read-print loop */
while (1) {
addrlen = sizeof(addr);
nbytes = recvfrom(fd, msgbuf, MSGBUFSIZE, 0,
(struct sockaddr*)&addr, &addrlen);
if (nbytes < 0) {
fprintf(stderr, "recfrom failed, %d\n", nbytes);
return 1;
}
msgbuf[nbytes] = '\0';
puts(msgbuf);
}
return 0;
}
Thanks,
Oskar
Ok, so apparently the firewall blocked the packets. Turning it off fixes the issue.