позволяет передавать двоичные данные между процессами - PullRequest
0 голосов
/ 14 марта 2011

У меня проблема с передачей двоичных данных между процессами. Моя программа открывает канал для ffmpeg с помощью popen () и пытается перехватить вывод и затем передать его как HTTP-сервер.

Я делаю что-то вроде этого

ffmpeg -i "input_video.avi" -ab 56 -ar 44100 -b 1500000 -r 25 -s 800x600 -f flv - 

(имя выходного файла "-" переводит вывод в стандартный вывод)

После открытия я использую fread () для чтения канала.

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

Я подозреваю, что канал открыт, чтобы быть "недвоичным" дескриптором, поскольку я открыл его с помощью popen ("", "r"), так как "r" в fopen для открытия текстового файла.

Но я не могу открыть его с помощью "rb", как я делаю для fopen (), так как "rb" не допускается popen ().

Как я могу решить эту проблему?

UPDATE:

#define FFMPEG_COMMAND "ffmpeg -i %s -ab 56 -ar 44100 -b 1500000 -r 25 -s 800x600 -f flv -"

Код Открывающая труба

Opening_pipe(filename)
{
    STREAMING_HANDLE *vfp = NULL;
    char command[512] = {  0 };


    vfp = (STREAMING_HANDLE *)malloc(sizeof(STREAMING_HANDLE));
    if(NULL != vfp)
    {
        sprintf(command, FFMPEG_COMMAND, filename);
        vfp->ffmpeg_pipe = popen( command, 
                                  "r" );

        if( NULL == vfp->ffmpeg_pipe )
        {
            free(vfp);
            vfp = NULL;
        }
    }    
    printf("Virt_dir_fopen : vfp => 0x%X\n", vfp);
    return vfp;
}

код для чтения с трубы

Reading_data_from_pipe(fileHnd, buff, buflen)
{
    STREAMING_HANDLE *vfp = (STREAMING_HANDLE *)fileHnd;
    int ret_code;
    printf("Virt_dir_fread : Asking for %d bytes \n", buflen);
    ret_code =  fread(buf, 1, buflen, vfp->ffmpeg_pipe );
    printf("Virt_dir_fread : Returning %d bytes \n", ret_code);

    return ret_code;
}

Код для закрытия трубы (для полноты :))

Closing_pipe(fileHnd)
{
    STREAMING_HANDLE *vfp = (STREAMING_HANDLE *)fileHnd;
    pclose(vfp->ffmpeg_pipe);
    free(vfp);
    return 0;
}

Update-2:

Сравнил файлы

1) Файл-1 => Получается путем передачи данных из ffmpeg

2) Файл-2 => Получен непосредственно из ffmpeg с использованием той же конфигурации

Есть различия, которые я вижу, 1) File_Duration_field в File-1 равен 0, но File-2 имеет некоторое значение. 2) File_size_field в File-1 равен 0, но File-2 имеет некоторое значение 3) Файл-1 имеет в конце дополнительные 18 байтов, которых нет в файле-2. Похоже, отсутствует подробное описание file_size и file_duration.

Это выглядит естественно, не так ли? так как ffmpeg не знает точный размер файла file_size, он мог бы поместить его в ноль в заголовке файла-1 (но все еще задается вопросом, почему он должен указывать 0 для продолжительности в файле-1).

Моя цель состоит в том, чтобы перекодировать мои видеофайлы в flv и передавать их одновременно, чтобы мне не пришлось ждать конвертации или преобразовывать все заранее. Но сделать это выглядит невозможно. Есть ли способ для меня, чтобы сделать это ???

Любая помощь / предложение будет очень полезно и ценится.

С уважением,

Microkernel

Ответы [ 2 ]

3 голосов
/ 14 марта 2011

Я предполагаю, что вы используете Linux или какой-то другой Unix. В этом случае нет различия между открытием чего-либо в двоичном или текстовом режиме. Вам не нужен флаг "b" вообще. Ваша проблема лежит в другом месте.

Из справочной страницы fopen :

Строка режима также может содержать букву '' b '' либо как последний символ, либо как символ между символами в любой из двухсимвольных строк, описанных выше. Это строго для совместимости с C89 и не имеет никакого эффекта; '' b '' игнорируется во всех системах, соответствующих POSIX, включая Linux. (Другие системы могут обрабатывать текстовые и двоичные файлы по-разному, и добавление '' b '' может быть хорошей идеей, если вы выполняете ввод-вывод в двоичный файл и ожидаете, что ваша программа может быть перенесена в не-Unix-среды.)

1 голос
/ 14 марта 2011

Вывод может быть необработанными данными без контейнера.Таким образом, приложение не может узнать, как интерпретировать двоичные данные в файле.

Вы также можете попробовать использовать параметр ffmpeg pipe , чтобы проверить, имеет ли оновлияние на вывод.

Обратите внимание, что некоторые форматы (обычно MOV) требуют, чтобы протокол вывода был доступен для поиска, поэтому они не будут работать с протоколом вывода канала.

...