Media (Intel® Video Processing Library, Intel Media SDK)
Access community support with transcoding, decoding, and encoding in applications using media tools like Intel® oneAPI Video Processing Library and Intel® Media SDK
Announcements
The Intel Media SDK project is no longer active. For continued support and access to new features, Intel Media SDK users are encouraged to read the transition guide on upgrading from Intel® Media SDK to Intel® Video Processing Library (VPL), and to move to VPL as soon as possible.
For more information, see the VPL website.

MPEG-2 encoding questions

Kevin_Michalski
Beginner
932 Views
I am using the Media SDK (v3.0.554.34012 Beta4) to encode and am running into a few problems. I hope someone here can help me.

When working with interlaced input (480i and 1080i), the input pictures to the encoder will be deinterlaced frame pictures (i.e. 720x480). I would like the encoder to encode full frames but mark them as interlaced rather than progressive. In essence, I am expecting the Progressive Sequence and progressive frame flags (in the MPEG-2 sequence header and picture header) to be unset and the Top Field First flag to be set/unset as appropriate. However, when I set PicStruct to MFX_PICSTRUCT_FIELD_TFF (or BFF), the encoder seems to be encoding the fields as separate pictures. FYI, I am using the sample_encode app with the arguments as follows:

sample_encode mpeg2 -hw -tff -f 29.97 -i "D:\\Mpeg Files\\420_1.yuv" -o "D:\\Mpeg Files\\420_1.enc.mpg" -h 480 -w 720

I could always encode as Progressive and restamp the appropriate bits in the output stream as a post process, but I wanted to make sure there wasn't a way to accomplish this using the SDK.

My other issue might be a bug. In the scenario described above, the GOP header in the output stream only contains correct time codes when encoding interlaced. When PicStruct is MFX_PICSTRUCT_PROGRESSIVE, the GOP header time code appears as 00:00:00:00 in every GOP. Have you seen this behavior?

Thanks again for your help.

Kevin
0 Kudos
9 Replies
IDZ_A_Intel
Employee
932 Views
Hi Kevin,
Thanks for your feedback.

I'm not sure I fully understand what you are trying to achieve. By using the "-tff" flag with the encode sample you will be encoding an interlaces TFF stream. To test this I used unmodified sample_encode with the same parameters as you used and verified that the stream is of type interlaced TFF and the theProgressive Sequence and progressive frame header flags are set to 0.
Can you please clarify a bit more.

Regarding the observed missing timer code in MPEG2 progressive content. I did reproduce this and it may be a bug. We will look into this further. Thanks for reporting this.

Regards,
Petter
0 Kudos
Kevin_Michalski
Beginner
932 Views
Petter,

Thanks for the info. To clarify, using sample_encode as you describe does produce interlaced fields as output. My situation is as follows: I am using interlaced video as a source (for SD, 480i@29.97). However, the capture card I am using deinterlaces the video, so the input to the encoder is a sequence of full 720x480 frames at 29.97 fps. I would like to encode these whole (deinterlaced) frames. When using the -tff or -bff options, the encoder breaks the input frames back up into fields and encodes them separately. Thus, the output MPEG-2 stream contains 59.94 half-frames (fields) per second rather than 29.97 full frames.

The only reason I don't encode in progressive mode is that I need the afore-mentioned flags to signify "interlaced" rather than "progressive", as instruction to decoders that the displayed video should be interlaced. We have a fairly large collection of MPEG files from various sources that we use for testing and other purposes, and this seems to be a fairly standard configuration. Let me know if this clears things up.

Did you find out anything in regards to the possible time code bug?

Thanks again,

Kevin
0 Kudos
Nina_K_Intel
Employee
932 Views

Hi Kevin,

I'm not sure that I understood your case correctly, but please try mfxExtCodingOption.FramePicture = MFX_CODINGOPTION_ON for encoder initialization along with setting mfxVideoParam.mfx.frameInfo.PicStruct = MFX_PICSTRUCT_FIELD_TFF (or BFF). This way encoder will use the whole frame for coding but stream will be properly marked as interlaced.

If you meant that the input for encoder is essentially progressive (your capture card does actual deinterlacing) and you need to encode it as progressive, only telling decoder to tell renderer to display as interlaced.. then check out the combined display attributes e.g. MFX_PICSTRUCT_PROGRESSIVE| MFX_PICSTRUCT_FIELD_TFF(see mediasdk_man.pdf pp 119-120)

Regarding time code problem - it was confirmed to be a library bug, please expect a fix in Media SDK 3.0 Beta5 which should be available very soon.

Regards,
Nina
0 Kudos
Kevin_Michalski
Beginner
932 Views
Thanks Nina; turning on the FramePicture setting did the trick.

I am using your MPEG-2 encoder filter code as a basis for a directshow encoder. I have tried making the same change in this code. I added the line

m_CodingOption.FramePicture = MFX_CODINGOPTION_ON;

to the CBaseEncoder() constructor and set PicStruct to MFX_PICSTRUCT_FIELD_TFF. However, when I try to run a graph, no frames are output from the decoder. If I change PicStruct back to MFX_PICSTRUCT_PROGRESSIVE, this does not happen. Note that the sample_encode project works fine with these settings. Do you know of any reason this should not work in the DirectShow filter?
0 Kudos
Nina_K_Intel
Employee
932 Views
Hi Kevin,

Good to hear your problem is solved. As for DS MPEG2 Encoder filter, you should modify mfxVideoParam at filter level, not at CBaseEncoder level. Parameters are configured on filter level (read from registry in filter constructor so make sure you add your code later) and then passed to CBaseEncoder.Init in StartStreaming.

Hope this helps.

-Nina
0 Kudos
Kevin_Michalski
Beginner
932 Views
Nina,

Thanks for the feedback. I've tweaked the DS filter code to the point where no settings are being read from the registry or overwritten from those set in BaseEncoder, and I've hard-coded some others to match the values in the sample_encode project. I've traced the code to the point where MFXVideoENCODE_Init() is being called. In the debugger, I've verified that all values in the mfxVideoParam structure being passed (aside from pointer addresses) are equal in both projects. However, the DS filter still fails to output anything when FramePicture = MFX_CODINGOPTION_ON and PicStruct = MFX_PICSTRUCT_FIELD_TFF.

Any other ideas as to what is happening?
0 Kudos
Nina_K_Intel
Employee
932 Views
Kevin,

Can you try to debug the Receive method and further to see if there's any problem with EncodeFrameAsync and SyncOperation calls? Any errors returned? Filter failing to output means an error is thrown or the graph hangs or something else? What does your graph look like?

-Nina
0 Kudos
Kevin_Michalski
Beginner
932 Views
Nina,

I think I've figured out the issue. The GetRequiredFramesNum() function is called before the mfxExtCodingOption structure is attached. I noticed that QueryIO returns twice the number of necessary frames if I call it later. Since GetAllocatorRequirements() was returning too few buffers, the upstream filter was hanging on GetBuffer() and the encoder stopped receiving input. The change I made was to double the values of nMinFrames and nRecommendedFrames returned by GetRequiresFramesNum() and everything seems to work.

Do you know what, if any, danger there might be in possibly requesting too many buffers (the * 2 is just a quick fix). Thanks again for your help.
0 Kudos
Nina_K_Intel
Employee
932 Views
Hi Kevin,

Glad to hear you found the reason, great debugging skills :-). I don't see any danger in requesting that many buffers - it's only the question of memory resources. As a quick workaround it's fine. But if you are looking into making this code a product I would suggest to provide proper mfxVideoParam structure to QueryIOSurf called in GetAllocatorRequirements. The fact that current QueryIOSurf implementation requests 2x buffers with params with this particular extCodingOption configuration may change in future versions or may be different for some of the platform specific implementations of MSDK. So it may appear that doubling the output of QueryIOSurf is simply not enough.

Regards,
Nina
0 Kudos
Reply