2012-06-18 16 views
6

Tôi đang cố gắng đọc và ghi đồng thời tệp H.264 mov được viết bởi AVAssetWriter. Tôi quản lý để trích xuất các đơn vị NAL cá nhân, đóng gói chúng vào AVPackets của ffmpeg và ghi chúng vào một định dạng video khác bằng cách sử dụng ffmpeg. Nó hoạt động và tập tin kết quả phát tốt ngoại trừ tốc độ phát lại không đúng. Làm cách nào để tính giá trị PTS/DTS chính xác từ dữ liệu H.264 thô? Hoặc có thể có một số cách khác để có được chúng?Nhận PTS từ nguyên mẫu H264 mdat được tạo bởi iOS AVAssetWriter

Đây là những gì tôi đã cố gắng:

  1. Giới hạn chụp min/tốc độ khung hình tối đa tới 30 và cho rằng các tập tin đầu ra sẽ là 30 fps. Trên thực tế, khung hình/giây của nó luôn nhỏ hơn giá trị tôi đặt. Và cũng có thể, tôi nghĩ rằng fps không phải là không đổi từ gói tin đến gói.

  2. Hãy nhớ dấu thời gian trình bày của từng mẫu văn bản và giả định rằng các mẫu ánh xạ một-một cho NALUs và áp dụng dấu thời gian đã lưu vào gói đầu ra. Điều này không hoạt động.

  3. Đặt PTS thành 0 hoặc AV_NOPTS_VALUE. Không hoạt động.

Từ googling về nó Tôi hiểu rằng dữ liệu H.264 thô thường không chứa bất kỳ thông tin thời gian nào. Nó đôi khi có thể có một số thông tin thời gian bên trong SEI, nhưng các tập tin mà tôi sử dụng không có nó. Mặt khác, có một số ứng dụng làm chính xác những gì tôi đang cố gắng làm, vì vậy tôi cho rằng nó có thể bằng cách nào đó.

+2

Tôi cũng đang cố đọc đồng thời H.264 từ tệp mov được viết bởi AVAssetWriter và không thể làm điều đó bằng cách sử dụng đường ống/đọc tệp thông thường. Làm thế nào bạn quản lý để đọc nó trong khi nó đang được viết? Cảm ơn! –

+3

Sử dụng đọc tập tin thường xuyên nhưng thay vì dừng lại trên EOF đọc lại. Sớm hay muộn hoạt động đọc của bạn sẽ thành công. – kolyuchiy

+2

@kolyuchiy - các nguồn công văn tận dụng tốt hơn hệ thống. Thiết lập nguồn đọc trên bộ mô tả FILE. Một khối sẽ được gọi khi có dữ liệu được đọc. Nếu EOF xảy ra chỉ rõ ràng lỗi trên FILE của bạn. –

Trả lời

5

Bạn sẽ phải tự tạo hoặc truy cập thông tin thời gian chứa của Atom trong vùng chứa MP4/MOV để tạo thông tin PTS/DTS. FFmpeg's mov.c trong libavformat có thể hữu ích.

Mỗi mẫu/khung bạn viết bằng AVAssetWriter sẽ ánh xạ từ một đến một với VCL NAL. Nếu tất cả các bạn đang làm là chuyển đổi sau đó có FFmpeg làm tất cả các nâng nặng. Nó sẽ duy trì đúng thời gian thông tin khi đi từ một định dạng container khác.

Luồng bit được tạo bởi AVAssetWriter không chứa dữ liệu SEI. Nó chỉ chứa các khung SPS/PPS/I/P. SPS cũng không chứa thông số VUI hoặc HRD.

- Edit -

Ngoài ra, hãy nhớ rằng nếu bạn đang lưu thông tin PTS từ đó căn cứ thời gian của CMSampleBufferRef có thể khác so với những container mục tiêu. Ví dụ: cơ sở thời gian AVFoundation là nano giây và tệp FLV là mili giây.

+1

Cảm ơn! Trên thực tế CMSampleBuffers thực sự chứa PTS chính xác ánh xạ tới các gói đầu ra. Tôi đã quá lười biếng để đi tất cả các con đường theo hướng đó. Điều này giải quyết được vấn đề của tôi. – kolyuchiy