Функция Libvlc libvlc_new_callbacks

Здравствуйте, я пытаюсь реализовать эту функцию libvlc версии 3.0, libvlc_new_callbacks для чтения из массива буферов. Документация

У меня есть функция, которая использует libusb для получения USB-передачи с устройства.

static void procedimiento_de_llamada_leer_transferencia_usb(struct libusb_transfer *transferencia_usb_2)
{
    if(transferencia_usb_2->status == LIBUSB_TRANSFER_COMPLETED)             
    {
        std::cout<<"Transferencia completa"<<std::endl;                    
    }
    else std::cout<<"Error: "<<transferencia_usb_2->status<<std::endl;      

    contador_evitar_basura++;                                                 
    if (contador_evitar_basura > 4)                 
    {
        apuntador_al_buffer_recepcion_BTS=transferencia_usb_2->buffer;
        variable_archivo_TS.write( (char *)transferencia_usb_2->buffer, tamanio_buffer); 
    }

    int respuesta_transferencia_llamada = libusb_submit_transfer(transferencia_usb_2);  

    if(respuesta_transferencia_llamada != 0) std::cout<<"Error transferencia: "<<respuesta_transferencia_llamada<<std::endl; 
}

На самом деле переданные байты попадают в файл, а затем открываются с помощью libvlc в качестве медиафайла, чтобы воспроизвести его, с помощью этой инструкции строки я записываю полученные байты в файл

variable_archivo_TS.write( (char *)transferencia_usb_2->buffer, tamanio_buffer);

Я вижу видео в своей программе, но файл постоянно растет, если долго смотреть видео, файл может достигать размеров 10 Gb. Я пытаюсь отправить буфер, полученный libusb, в плеер, не сохраняя его в файл, я создаю глобальную переменную, которая указывает на буфер

unsigned char *apuntador_al_buffer_recepcion_BTS;

apuntador_al_buffer_recepcion_BTS=transferencia_usb_2->buffer;

Затем я пытаюсь реализовать функцию libvlc_new_call_backs:

Я передаю указатель apuntador_al_buffer_recepcion_BTS в функцию и устанавливаю обратные вызовы на открытие и чтение, объявляю поиск и закрытие как NULL, возможно, это неправильный подход, но я думаю прочитать весь буфер сразу, поэтому я не нужна функция поиска

void procedimiento_media_callbacks()
{
    static libvlc_media_t *media = libvlc_media_new_callbacks(
                         instancia_vlc,     // 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());    
    libvlc_media_player_set_media(reproductor, media);          

}

Я думаю, что просто использую функцию open_callback, чтобы указать данные на непрозрачный (буфер) и установить sizep на размер буфера,

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)
{
    return 245760;
}

Но я не могу заставить его работать, я не смог найти код, который использует эту функцию.


person Edgar Gomez    schedule 25.04.2017    source источник


Ответы (1)


Часть кода, как я заставляю это работать

//! Variable para indicar la posicion del buffer a copiar a la media del reproductor.
/*!
     Posiciones={0,245760,491520,737280,983040,1228800,1474560,1720320,1966080,2211840,2457600,2703360,2949120,3194880,3440640,3686400,3932160,4177920,4423680,4669440}.
*/
static int posicion_media_buffer=0;

//! Función de llamada de la función libvlc_media_new_callbacks para apuntar a la posición de los datos y guardar el tamaño del buffer a leer.
/*!
    \param *opaque apuntador al buffer rotativo.
    \param **datap espacio de alamacenamiento para un apuntador de datos.
    \param *sizep apuntador al tamaño del buffer de datos.
    \return 0 operación exitosa.
*/
int abrir_media(void *opaque, void **datap, long unsigned int *sizep)
{
    *sizep = tamanio_buffer;                                                //Asigna el tamaño de los datos
    *datap = opaque;                                                        //Coloca como data con el apuntador al buffer rotativo
    return 0;                                                               //Devuelve cero
}

//! Función de llamada de la función libvlc_media_new_callbacks para leer los datos.
/*!
    \param *opaque apuntador al buffer rotativo.
    \param *buf apuntador al buffer de lectura.
    \param len longuitud de los datos a leer.
    \return devuelve la cantidad de datos leidos.
*/
long int leer_media(void *opaque, unsigned char *buf,long unsigned int len)
{
    len=tamanio_buffer_MPEG_TS;                                                 //Longuitud de datos a leer igual al tamanio_buffer_MPEG_TS
    std::memcpy(buf,((unsigned char*)opaque+posicion_media_buffer), len);       //copiar los dtoas del buffer rotativo al buffer de lectura
    procedimiento_retardo_milisegundos(2);                                      //Retardo par evitar uso excesivo del CPU
    posicion_media_buffer+=tamanio_buffer_MPEG_TS;                              //Aumentar posición_media_buffer con los datos ya leidos

    if(posicion_media_buffer>4669440||funcion_leer_estado_hotplug()!=1)         //Si posicion_media_buffer mayor a 4669440 ó dispositivo desconectado
        posicion_media_buffer=0;                                                //posicion_media_buffer igual a cero

    return tamanio_buffer_MPEG_TS;                                              //Devuelve la cantidad de datos leidos
}

//! Funcion de llamada de la función libvlc_media_new_callbacks para colocar la nueva posición en el buffer de datos.
/*!
    \param *opaque apuntador al buffer rotativo.
    \param offset posicion de nuevos datos leidos.
    \return 0 operación exitosa.
*/
int posicionar_media(void *opaque, uint64_t offset)
{
    offset=0;   //offset igual a cero
    return 0;   //retorna cero
}

//! Procedimiento procedimiento_media_callbacks.
/*!
    Procedimeinto para obtener la data media y luego mandarlar a reproducir con el reproductor.
*/
void procedimiento_media_callbacks(void)
{
    media = libvlc_media_new_callbacks(     //media igual a los datos BTS que llegan la pueert USB su llenado es asincrónico
                         instancia_vlc,     //Instancia vlc
                           abrir_media,     //función de llamada abrir_media()
                            leer_media,     //función de llamada leer_media()
                      posicionar_media,     //función de llamada posicionar_media()
                                  NULL,     //NULL cerrar media
     apuntador_al_buffer_recepcion_BTS);    //Apuntador al buffer roatativo

    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
}
person Edgar Gomez    schedule 25.04.2017
comment
спасибо за пример, я тоже пытаюсь заставить это работать, в настоящее время безуспешно, но ваш пример очень полезен для продвижения вперед - person amigo421; 05.07.2017