2013-03-17 35 views
5

Theo các ngoại lệ của ffmpeg: decoding_encoding.c và filtering_video.c, tôi xử lý một tệp video do iPhone chụp. Tệp video: .mov, kích thước video; 480x272, Codec video: H.264/AVC, 30 khung hình/giây, tốc độ bit: 605 kbps.Tại sao frame-> pts tăng 20, thay vì 1?

Lần đầu tiên tôi trích xuất từng khung là YUV. Tôi chuyển đổi YUV thành RGB24 và xử lý RGB24, sau đó ghi RGB24 vào tệp .ppm. Nó cho thấy tệp .ppm là chính xác.

Sau đó, tôi lập kế hoạch mã hóa RGB24 đã xử lý thành tệp video. Vì MPEG không hỗ trợ định dạng hình ảnh RGB24, tôi đã sử dụng AV_CODEC_ID_HUFFYUV. Nhưng tệp video đầu ra (hiển thị 18,5 MB) không phát. Trình phát phim trên Ubuntu xác nhận lỗi: Không thể xác định loại luồng. Tôi cũng đã thử nó trên VCL. Nó chỉ đơn giản là không hoạt động, mà không có bất kỳ thông tin lỗi nào.

câu hỏi thứ hai của tôi là: Đối với mỗi fram chiết xuất từ ​​các tập tin video đầu vào, tôi nhận được điểm của nó như sau theo filtering_video.c:

frame->pts = av_frame_get_best_effort_timestamp(frame);

tôi in ra điểm của mỗi khung hình, và thấy rằng nó tăng thêm 20, như sau:

pFrameRGB_count: 0, frame->pts: 0 
pFrameRGB_count: 1, frame->pts: 20 
pFrameRGB_count: 2, frame->pts: 40 
pFrameRGB_count: 3, frame->pts: 60 

Khung ở đâu là khung được trích xuất từ ​​video đầu vào và pFrameRGB_count là số được tính cho khung đã xử lý ở dạng RGB24.

Tại sao chúng sai?

Trả lời

5

Video H.264 sử dụng 90 kHz clock để mã hóa timestamps. Vì video của bạn là 30 fps, đồng bằng PTS giữa 2 khung liên tiếp phải là 3000 thay vì 20.

Một giá trị của 20 chỉ ra một hoặc cả hai trong những cách sau:

  • đồng hồ mã hóa của bạn (tức là tỷ lệ lấy mẫu) được cấu hình không chính xác (đến 600 Hz) cho tỷ lệ khung hình nhất định tốc độ 30 fps

  • Khung hình/giây của bạn được định cấu hình không chính xác (đến 4500fps).

Công thức chung để tính toán đồng bằng PTS là:

PTS delta = (1/fps) * Encoder sampling rate 
0

tôi gỡ lỗi để có được bối cảnh codec của các file video đầu vào, dec_ctx-> time_base.den = 1200; Tôi biết fps, 30, bằng cách nhấp chuột phải vào tệp video đầu vào để kiểm tra thuộc tính của nó (Ubuntu 12.04) Vì vậy, có vẻ như thời lượng khung phải là 1200/30 = 40 đơn vị cơ sở. Nhưng nó là 20 bằng cách sử dụng frame-> pts = av_frame_get_best_effort_timestamp (frame);

gói đọc của video đầu vào có thời gian = 20.

tôi thấy dec_ctx-> ticks_per_frame = 2. Tôi đoán ticks_per_frame làm cho 40 đến 20. Có thể có một số công thức bên trong, như: độ dài khung trong đơn vị cơ sở = thời lượng khung x ticks_per_frame (nhưng có vẻ như nó khác với những gì được nói trong tài liệu ffmpeg, chẳng hạn như time_base bằng 1/tỷ lệ khung hình.)

0

Tôi nghĩ rằng tôi tìm thấy câu trả lời. Do thiếu tài liệu chi tiết về ffmpeg, người dùng có thể bị lừa dối. tôi thấy rằng, để có được điểm đúng, người ta luôn luôn nên sử dụng: video_st-> time_base KHÔNG video_st-> codec-> time_base

(a) thời gian tuyệt đối của một khung:

packet-> dts * (1/video_st-> time_base.den)

(b) thời gian tuyệt đối giữa khung và khung tiếp theo của nó:

frame-> repeat_pict * (1/video_st-> time_base.den)

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