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 }

 

posted @ 2017-12-06 10:40  plumnut  阅读(2581)  评论(0编辑  收藏  举报