0

LANG: C / ENV: Linux

私はストリーミングエンジンを開発しています。今のところ、ストリームを開始、停止、一時停止できますが、シークは私に多くの頭痛の種を与えている操作です。以前にここで質問し、コード内のいくつかの問題を修正しました答えます。

lseek()関数を使用して、オープン ストリーミング ファイル記述子を最初の引数として渡します。また、次のコードのように、送信に UDP を使用しています。

transport_fd = open(tsfile, O_RDONLY);
int offset = 1024;
off_t offsetIndicator;
if ((offsetIndicator=lseek(transport_fd, offset, SEEK_CUR))<0) printf("Error seeking\n");

ストリーミング中にシークしようとすると、ストリーミングが停止し、画像がハングします。

注意すべきことはありますか?たとえば、変更を有効にするためにファイルをシークした後にsleep()またはnanosleep()を試行するなどです。

そのようなエンジンのベスト プラクティスに関する例、論文、関連記事は見つかりませんでした。

編集:

テスト後、ファイルは引き続きストリーミングされたようですが、ネットワーク上の受信デバイスがストリーム接続をキャッチしなくなり、シーク時間を差し引いて終了までの時間を計算すると、ストリームは正常に終了したようです。

コードスニペット:

while (!completed) 
{
    while (/* Comparing conditions */ && !completed)
    { 
        if (seekLck == 1) // seekLck is a semaphore to test seek signal from father process initiated by 0
        {
            int offset = 1024;
            off_t offsetIndicator;
            if ((offsetIndicator=lseek(transport_fd, offset, SEEK_CUR))<0) 
                printf("Error seeking\n");
            nanosleep(&nano_sleep_packet, 0); //Try to sleep to see if it is still hanging, didn't work 
            seekLck = 0;
        }   
        len = read(transport_fd, send_buf, packet_size);
        if(len < 0) {
            fprintf(stderr, "File read error \n");
            completed = 1;
        } 
        else if (len == 0)
        {
            fprintf(stderr, "Sent done\n");
            completed = 1;
        }
        else
        {
            sent = sendto(sockfdstr, send_buf, len, 0, (struct sockaddr *)&addr, sizeof(struct sockaddr_in));
            if(sent <= 0)
            {
                perror("send(): error ");
                completed = 1;
            }
        }
    }
    nanosleep(&nano_sleep_packet, 0);
}
close(transport_fd);
close(sockfdstr);
free(send_buf);
printf("cleaning up\n");
return 0;
}
4

1 に答える 1

0

主な質問は、「 lseek()が正常に動作しているのに、なぜファイルがストリーミング ( Played )されないのですか?」というものでした...

実際にはサーバー側には何も問題はありませんでしたが、クライアントはフレーム カウントを失った後、ストリーミングを続行できませんでした (ストリーミング ffmpeg フレーム、クライアントはビデオ スクランブラーからストリームを取得しています)。

この状況で私にとってうまくいったのは、ソケットパラメーターを取得し、ストリーム位置を保持しながらシークする必要があるプロセスを(クリーンな方法で)強制終了し、その後、同じソケットパラメーターでシーク位置からまったく新しいストリームを開始することですそのため、古いものを置き換えます。

これが、特にそれらに関するドキュメントがあまりないという人に役立つことを願っています。

于 2014-11-20T12:24:23.970 に答える