Quantcast
Channel: Media Foundation Development for Windows Desktop forum
Viewing all articles
Browse latest Browse all 1079

IMFTransform::ProcessOutput method always returning MF_E_TRANSFORM_NEED_MORE_INPUT

$
0
0

MftH264Decoder::DecoderOutputState MftH264Decoder::GetOutput() {

CComPtr<IMFSample> output_sample;
if (!use_dxva_) {
// If DXVA is enabled, the decoder will allocate the sample for us.
output_sample.Attach(CreateEmptySampleWithBuffer(out_buffer_size_));
if (output_sample == NULL) {
cout<< "GetSample: failed to create empty output sample";
return kNoMemory;
}
}
MFT_OUTPUT_DATA_BUFFER output_data_buffer;
HRESULT hr;
DWORD status;
for (;;) {
output_data_buffer.dwStreamID = 0;
output_data_buffer.pSample = output_sample;
output_data_buffer.dwStatus = 0;
output_data_buffer.pEvents = NULL;
hr = decoder_->ProcessOutput(0,            // No flags
1,            // # of out streams to pull from
&output_data_buffer,
&status);
IMFCollection* events = output_data_buffer.pEvents;
if (events != NULL) {
cout<< "Got events from ProcessOuput, but discarding";
events->Release();
}
if (FAILED(hr)) {
cout<< "ProcessOutput failed with status " << std::hex << hr
<< ", meaning..." << ProcessOutputStatusToCString(hr);
if (hr == MF_E_TRANSFORM_STREAM_CHANGE) {
if (!SetDecoderOutputMediaType(output_format_)) {
cout<< "Failed to reset output type";
return kResetOutputStreamFailed;
} else {
cout<< "Reset output type done";
continue;
}
} else if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) {
// If we have read everything then we should've sent a drain message
// to the MFT. If the drain message is sent but it doesn't give out
// anymore output then we know the decoder has processed everything.
if (drain_message_sent_) {
cout<< "Drain message was already sent + no output => done";
return kNoMoreOutput;
} else {
if (!ReadAndProcessInput()) {
cout<< "Failed to read/process input. Sending drain message";
if (!SendDrainMessage()) {
cout<< "Failed to send drain message";
return kNoMoreOutput;
}
}
continue;
}
} else {
return kUnspecifiedError;
}

}

The above function is my implementation of H264 Decoder. The input samples are read from the H264 dump file as an elementary stream. Initially i am trying to passing only the first frame which s of size 1043 and passing it to decoder.

bool MftH264Decoder::ReadAndProcessInput() {
  FILE *pFile;
int bytes_read =0;
int bytes_remaining = 1043;
int read =0;
pFile = fopen ("Bourne.264","rb");
if (pFile == NULL)
{
cout<<"File Error";

}
char *in_buffer = NULL;
in_buffer = (char*) malloc (sizeof(char)*2000);
if(in_buffer == NULL)
{
cout<<"Memory error";
}
bytes_read=fread (in_buffer,1,1043,pFile);
fclose(pFile);
    return SendInput((unsigned char*)in_buffer,1043,0,0);
}

bool MftH264Decoder::SendInput(unsigned char* data, int size, long long timestamp,
                               long long duration) {
  /*if(initialized_)
  {
 return false;
  }*/
 // CHECK(data != NULL);
 // CHECK_GT(size, 0);
  if (drain_message_sent_) {
    cout<< "Drain message was already sent, but trying to send more "
                  "input to decoder";
    return false;
  }
  CComPtr<IMFSample> sample;
  sample.Attach(CreateInputSample(data, size, timestamp, duration,
                                  in_buffer_size_));
  if (sample == NULL) {
    cout<< "Failed to convert input stream to sample";
    return false;
  }
  HRESULT hr = decoder_->ProcessInput(0, sample, 0);
  if (FAILED(hr)) {
    cout<< "Failed to ProcessInput, hr = " << std::hex << hr;
    return false;
  }
  frames_read_++;
  return true;
}

The processOutput function always returns MF_E_TRANSFORM_NEED_MORE_INPUT  as a result it keeps on reading the first frame from the buffer.

Is this the correct way of calling Process Input and Process output functions?


Viewing all articles
Browse latest Browse all 1079

Trending Articles