gstreamer omx 解碼器代碼分析


最近分析了幾個和omx播放相關的問題,從播放器的角度,對omx流程有了進一步的了解。

相關處理主要在:gst-omx-1.9.1/omx/gstomxvideodec.c
1  gst_omx_video_dec_handle_frame
gstreamer調用此函數,給omx decoder發送待解碼的packets。

主要處理流程如下:

2226   if (!self->started) {                                        // 第一次進入
2232     gst_pad_start_task (GST_VIDEO_DECODER_SRC_PAD (self),
2233         (GstTaskFunction) gst_omx_video_dec_loop, decoder, NULL);    // 啟動解碼線程
2234   }

2258   port = self->dec_in_port;                                   // 獲取端口;因為這個端口是給omx解碼器送數據的,所以獲取的是in port。
2266     acq_ret = gst_omx_port_acquire_buffer (port, &buf);            // 從端口中申請一個空閑buffer。
// enter: gst_omx_port_acquire_buffer
1353   _buf = g_queue_pop_head (&port->pending_buffers);             // 從端口的鏈表中獲取bufferr
// leave: gst_omx_port_acquire_buffer

2383     buf->omx_buf->nFilledLen =
2384         MIN (size - offset, buf->omx_buf->nAllocLen - buf->omx_buf->nOffset);     // 計算實際傳送的數據長度
2385     gst_buffer_extract (frame->input_buffer, offset,
2386         buf->omx_buf->pBuffer + buf->omx_buf->nOffset,
2387         buf->omx_buf->nFilledLen);                                        // 把Frame中的數據拷貝到omx port buffer。

2420     err = gst_omx_port_release_buffer (port, buf);                           // 把填充過數據的omx port buffer還給omx port。
// enter:gst_omx_port_release_buffer
1427   if (port->port_def.eDir == OMX_DirInput) {
1428     err = OMX_EmptyThisBuffer (comp->handle, buf->omx_buf);                  // omx 解碼器的接口函數:發送待解碼數據。解碼器處理完,
                                                                                         // 會調用dec->callbacks.EmptyBufferDone通知omx插件。
1429   } else {
1430     err = OMX_FillThisBuffer (comp->handle, buf->omx_buf);
1431   }
// leave:gst_omx_port_release_buffer

至此, gst_omx_video_dec_handle_frame發送packets完成。

2 gst_omx_video_dec_loop
把omx decoder解碼后的幀,發送給gstreamer播放器。

主要處理流程如下:

1263   port = self->dec_out_port;                        // 獲取端口;因為這個端口是用來獲取omx解碼后的數據的,所以獲取的是out port。
1266   acq_return = gst_omx_port_acquire_buffer (port, &buf);        // 從端口中申請一個空閑buffer。
// enter: gst_omx_port_acquire_buffer
1353   _buf = g_queue_pop_head (&port->pending_buffers);     // 從端口的鏈表中獲取bufferr
// leave: gst_omx_port_acquire_buffer

1499       if ((flow_ret =
1500               gst_video_decoder_allocate_output_frame (GST_VIDEO_DECODER
1501                   (self), frame)) == GST_FLOW_OK) {                        // 從gstreamer播放器申請buffer,用來存儲解碼后的數據

1506         if (!gst_omx_video_dec_fill_buffer (self, buf, frame->output_buffer)) {            // 把omx buffer的數據拷貝到gstreamer播放器的buffer
1513         }
1520         flow_ret =
1521             gst_video_decoder_finish_frame (GST_VIDEO_DECODER (self), frame);        // 把帶有解碼后數據的frame,傳送給后續插件
1525       }

1535   if (buf) {
1537     err = gst_omx_port_release_buffer (port, buf);                        // 把omx out port的buffer還回去
// enter:gst_omx_port_release_buffer
1427   if (port->port_def.eDir == OMX_DirInput) {
1428     err = OMX_EmptyThisBuffer (comp->handle, buf->omx_buf);        
1429   } else {
1430     err = OMX_FillThisBuffer (comp->handle, buf->omx_buf);                // omx 解碼器的接口函數:把空buffer還給omx,以便存放新的解碼后的數據。
                                              // 解碼器解碼完,調用dec->callbacks.FillBufferDone通知omx插件
1431 } // leave:gst_omx_port_release_buffer 1540 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM