Page 1 of 1

How to use ibvlc_media_new_callbacks

Posted: 15 Mar 2017 16:09
by aurquiel
Hello

I was searching around the internet but there are not good examples about using libvlc_media_new_callbacks from stream from an array of data

I am developing a software to play packets form an USB Device on Linux. I actually get to play the data but saving in a file that constantly grows up, that's the problem the file could consume the hard drive if you are reproducing it for a long time, for 48 min of Video i got a file of 10GB, the packets are TS (transport stream packets) so in a single frequency i have 6 programs ID, I just saying in that file of 10GB i have 6 different channels.

Lets see the callback function of the code USB receiving, in that callback function i get the buffer with the data. (I am using Libusb, this function is doing by a thread just receive data, the play is doing in the main thread application)

Code: Select all

//Global variables std::ofstream variable_archivo_TS ("data.ts"); //File to write the BTS frame const int tamanio_buffer=1024; //Size of the buffer 240Kb 245760 unsigned char MPEG2_TS[tamanio_buffer]; //Buffer to receive int contador_evitar_basura=0; static void funcion_de_llamda_leer_transferencia_usb(struct libusb_transfer *transferencia_usb_2) { int res; if(transferencia_usb_2->status ==LIBUSB_TRANSFER_COMPLETED) { std::cout<<"Transferencia completa"<<std::endl; //Mostar la siguiente advertencia } else { std::cout<<"Error: "<<transferencia_usb_2->status<<std::endl; //Mostar la siguiente advertencia } contador_evitar_basura++; //Incrementar contador_evitar_basura //If glbal_counter > 2 write to a file, this to avoid the trash in the first transmissions if (contador_evitar_basura>2) variable_archivo_TS.write( (char *)transferencia_usb_2->buffer, tamanio_buffer); res = libusb_submit_transfer(transferencia_usb_2); //Realizar unanueva transferencia if(res !=0) { std::cout<<"submitting. error code: "<<res<<std::endl; //Mostar la siguiente advertencia } }
//This line of the code is where a write to the file.

Code: Select all

if (contador_evitar_basura>2) variable_archivo_TS.write( (char *)transferencia_usb_2->buffer, tamanio_buffer);
In the frontend to play it i wait 1.5 seconds to fill the file, serach the directory and path to the file, add the media and play the file

Code: Select all

SemcoSleep(1500); //Esperar 1,5 segundo para llenar un poco el archivo .TS //Obteniendo el directorio donde se encuentra el archivo a reproducir Comienzo char directorio_actual_de_trabajo[200000]; //TamaƱo del buffer donde guardar el directorio getcwd(directorio_actual_de_trabajo, sizeof(directorio_actual_de_trabajo)); //Rellena el buffer con el directorio actual de trabajo std::string direccion_archivo_vlc=directorio_actual_de_trabajo; //Se guarda en un string direccion_archivo_vlc="file://"+direccion_archivo_vlc+"/data.ts"; //Se modifica el string para hacerlo compatible con la direccion tomada por libvlc //Obteniendo el directorio donde se encuentra el archivo a reproducir Fin libvlc_media_t *media; //Se crea la variable media media = libvlc_media_new_location(instancia_vlc, &direccion_archivo_vlc[0u]); //fill media libvlc_media_add_option(media,funcion_leer_id()); //Se coloca el Id del canal deseado a reproducir libvlc_media_player_set_media(reproductor, media); //Se coloca el medio media en el reporductor libvlc_media_player_play(reproductor); //Reproducir
The question is i could use this function

LIBVLC_API libvlc_media_t* libvlc_media_new_callbacks ( libvlc_instance_t * instance,
libvlc_media_open_cb open_cb,
libvlc_media_read_cb read_cb,
libvlc_media_seek_cb seek_cb,
libvlc_media_close_cb close_cb,
void * opaque
)

In the callback read pass the buffer of 1024bytes incoming through the usb transfer rather than write it to a file


But i can find any code how to implement it. I just find this https://forum.videolan.org/viewtopic.php?t=127796

The source code of my project is here https://github.com/aurquiel/TDA_Linux

Re: How to use ibvlc_media_new_callbacks

Posted: 15 Mar 2017 21:44
by chouquette
libvlc_media_new_callbacks is meant to stream a media from memory, not from a file. You'd need to remove the intermediate temporary file for this to work I think.

That being said, couldn't you simply open your media using the v4l2 module? You're reading from a device, not memory per-se, and I don't see the need for libvlc_media_new_callbacks here.

Re: How to use ibvlc_media_new_callbacks

Posted: 18 Apr 2017 15:03
by aurquiel
libvlc_media_new_callbacks is meant to stream a media from memory, not from a file. You'd need to remove the intermediate temporary file for this to work I think.

That being said, couldn't you simply open your media using the v4l2 module? You're reading from a device, not memory per-se, and I don't see the need for libvlc_media_new_callbacks here.
I can't use v4I2 because i am developing the software at linux using libusb, i am controlling the device from the user space, that's why i want to use the media_new_callbacks function, for v4I2 i must write a driver for the device, the project works well far now so i don't see the necessity to trow all the development around libusb to write a driver .

I have a question, should i use media_new_callbacks in a new thread with a while loop after call it, or just run it at the main thread of my program and then pass the media to the player to play it?

Re: How to use ibvlc_media_new_callbacks

Posted: 25 Apr 2017 18:48
by aurquiel
By the way i share the solution for other users, they could improve it

At this way you will read from a buffer that comes from libusb with transport stream video

Code: Select all

int open_callback(void *opaque, void **datap, long unsigned int *sizep) { *sizep = 245760; *datap = opaque; return 0; } long int read_callback(void *opaque, unsigned char *buf,long unsigned int len) { procedimiento_retardo_milisegundos(60); //Delay waiting new data std::memcpy(buf,apuntador_al_buffer_recepcion_BTS, 245760); //Copy from archive return 245760; } void procedimiento_media_callbacks() { static libvlc_media_t *media = libvlc_media_new_callbacks( instancia_vlc, //Instancia vlc open_callback, //open media read_callback, //read media NULL, //NULL seak NULL, //NULL close apuntador_al_buffer_recepcion_BTS); //NULL libvlc_media_player_set_media(reproductor, media); libvlc_media_add_option(media, funcion_leer_id()); //Se coloca el Id del canal deseado a reproducir libvlc_media_player_set_media(reproductor, media); //Se coloca el medio media en el reporductor }
I don't put it in another thread

procedimiento_retardo_milisegundos(60); this is a delay of 60 ms