2011-11-03 41 views
6

Tôi đang triển khai bộ giải mã âm thanh bằng ffmpeg. Trong khi đọc âm thanh và thậm chí tìm kiếm đã hoạt động, tôi không thể tìm ra cách xóa bộ đệm sau khi tìm kiếm vì vậy tôi không có hiện vật khi ứng dụng bắt đầu đọc âm thanh ngay sau khi tìm kiếm.FFMPEG Tìm kiếm mang đến các tạo phẩm âm thanh

avcodec_flush_buffers dường như không ảnh hưởng đến bộ đệm trong. Vấn đề này xảy ra với tất cả các bộ giải mã (mp3, aac, wma, ...) nhưng PCM/WAV (không sử dụng bộ đệm trong để giữ dữ liệu giải mã vì âm thanh không được nén).

Đoạn mã rất đơn giản:

av_seek_frame(audioFilePack->avContext, audioFilePack->stream, posInTimeFrame, AVSEEK_FLAG_ANY); 
avcodec_flush_buffers(audioFilePack->avContext->streams[audioFilePack->stream]->codec); 

Giải thích:

audioFilePack->avContext = FormatContext 
audioFilePack->stream = Stream Position (also used to read audio packets) 
audioFilePack->avContext->streams[audioFilePack->stream]->codec = CodecContext for the codec used 

Bất kỳ ý tưởng về những gì tôi nên làm như vậy tôi có thể tìm kiếm và không nhận được âm thanh còn lại? Cảm ơn!

+0

Xin vui lòng, không có ý tưởng? Tôi đang cố gắng khắc phục điều này trong gần 2 tuần mà không có bất kỳ ý tưởng về những gì có thể gây ra điều này ... nó nên hoạt động như thế nào? –

+0

Tin nhắn cũng được gửi tới danh sách gửi thư chính thức của người dùng ffmpeg. Trợ giúp vẫn cần thiết. –

+0

Bạn có thể mô tả các hiện vật một cách chi tiết hơn không? Họ có nhấp chuột và bật không? –

Trả lời

3

Tôi chưa bao giờ viết trình phát âm thanh có khả năng tìm kiếm, nhưng những gì tôi nghi ngờ đang diễn ra chính là điều này. Mỗi gói âm thanh giải mã thành một đoạn của sóng âm thanh gốc. Thông thường, những đoạn này liên tiếp đè bẹp lẫn nhau và kết quả là một sóng liên tục, mà nó nghe như âm thanh không có hiện vật. Khi bạn tìm kiếm, bạn buộc hai đoạn từ các phần khác nhau của tệp để loại bỏ lẫn nhau. Điều này thường giới thiệu một sự gián đoạn vào sóng âm thanh, mà tai cảm nhận như là một nhấp chuột hoặc pop, hoặc khi bạn gọi nó (tôi đoán) một tạo tác.

Dưới đây là ví dụ cụ thể hơn. Giả sử bạn đã phát 25 gói âm thanh đầu tiên trước khi bạn tìm kiếm. Giả sử gói 25 giải mã thành wave có mẫu cuối cùng là 12345. Trong khi gói 25 đang được trả về loa, bạn tìm gói 66. Giả sử mẫu đầu tiên của gói 66 là -23456. Do đó, luồng âm thanh kỹ thuật số nhảy từ 12345 đến -23456 trong quá trình tìm kiếm. Đây là một sự gián đoạn lớn, và sẽ được nghe như một cửa sổ pop.

Tôi nghĩ rằng một giải pháp là lấy thêm một gói trước khi bạn bắt đầu tìm kiếm (gói 26 trong ví dụ của tôi), giải mã nó vào bộ đệm ngoại tuyến, áp dụng fade-out và sau đó đặt nó vào hàng đợi phát lại. Sau khi bạn tìm đến vị trí mong muốn của bạn, hãy lấy gói đầu tiên (66 trong eaxmple của tôi), giải mã nó vào một bộ đệm ngoại tuyến khác, áp dụng một fade-in, và sau đó đặt nó vào hàng đợi phát lại. Điều này sẽ đảm bảo sóng âm thanh mượt mà và tìm kiếm không có tác phẩm.

Nếu bạn thông minh, bạn có thể làm mờ dần và mờ dần trong thời gian ngắn hoặc dài tùy thích. Tôi nghĩ chỉ một vài phần nghìn giây là đủ để ngăn ngừa hiện vật. Bạn thậm chí có thể áp dụng một cross-phai từ các gói cũ và mới. Cũng có thể đủ để chỉ lưu ý giá trị mẫu cuối cùng trong gói cuối cùng trước khi tìm kiếm, và dần dần chuyển nó xuống 0 trên một vài mẫu, thay vì kéo nó về 0 ngay lập tức. Điều này có thể dễ dàng hơn việc giải mã một gói phụ.

Đây là phỏng đoán của tôi về cách giải quyết vấn đề này. Đây rõ ràng là một vấn đề được giải quyết, vì vậy tôi khuyến khích bạn cũng xem xét các trình phát âm thanh nguồn mở và xem cách chúng triển khai tìm kiếm. Các chương trình như Audacity, Totem, Banshee, RhythmBox, Amarok, hoặc VLC, hoặc các framework như GStreamer có thể là những ví dụ tốt để học hỏi. Nếu bạn thấy họ sử dụng các kỹ thuật đáng chú ý, xin vui lòng báo cáo về chủ đề ở đây. Tôi nghĩ mọi người sẽ muốn biết họ là ai. Chúc may mắn!

3

Đó là lỗi trong ffmpeg. Các bộ đệm bên trong không bị xóa, và do đó khi bạn đi lấy một gói/khung sau khi xả, bạn sẽ nhận được dữ liệu tìm kiếm trước. Nó xuất hiện để được cố định từ 3-16-12, vì vậy bạn có thể kết hợp điều này sửa chữa chính mình, hoặc nâng cấp ffmpeg.

http://permalink.gmane.org/gmane.comp.video.libav.devel/23455

Như một bản cập nhật, các lỗi ở trên thực sự là một vấn đề, nhưng có một lỗi thứ hai với AAC đặc biệt.

Kể từ năm tháng trước, một người dùng khác đã tìm thấy lỗi này và đã được báo cáo là cố định. https://ffmpeg.org/trac/ffmpeg/ticket/420

Khắc phục là chức năng tuôn ra được thêm vào aacdec.c xóa bộ đệm trong của nó. Vấn đề là có hai bộ giải mã được định nghĩa trong aacdec.c, và chỉ có một bộ được cung cấp cho con trỏ hàm xả. Nếu bạn sử dụng bộ giải mã khác (phổ biến hơn), bộ giải mã vẫn sẽ không bị xóa hoàn toàn.

Nếu bạn đang ở một vị trí để xây dựng ffmpeg mình, việc sửa chữa là thêm .flush = tuôn ra, để dưới cùng của định nghĩa của AVCodec ff_aac_decoder (đó là ở dưới cùng của tập tin.)

Tôi sẽ để các anh chàng ffmpeg biết hy vọng nó có thể được đưa vào chi nhánh chính.

+0

Bumping để áp phích ban đầu hy vọng thấy điều này – JHawkZZ

+0

Cảm ơn bạn rất nhiều! Tôi sẽ biên dịch lại nó và từ bỏ cách thay thế của tôi ... đó là xấu xí nhưng hoạt động ... –

Các vấn đề liên quan